From cf4605e90de5bde4a1848801ab32c849d13f731b Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Wed, 18 Dec 2024 13:56:21 +0200 Subject: [PATCH 1/5] mainnet-v1.39.4 external-crates --- Cargo.lock | 14 + external-crates/move/Cargo.lock | 1032 ++++-- external-crates/move/Cargo.toml | 9 +- .../check_bounds/1_param_and_255_locals.exp | 2 +- .../check_bounds/1_param_and_255_locals.mvir | 2 +- .../tests/check_bounds/256_locals.mvir | 2 +- .../check_bounds/too_many_type_actuals.exp | 2 +- .../check_bounds/too_many_type_actuals.mvir | 2 +- .../dependencies/call_integers_valid.move | 2 +- .../tests/instantiation_loops/complex_1.exp | 12 +- .../tests/instantiation_loops/complex_1.mvir | 6 +- .../instantiation_loops/complex_1_enum.exp | 12 +- .../instantiation_loops/complex_1_enum.mvir | 6 +- ...utually_recursive_just_type_params_ok.mvir | 2 +- ...utually_recursive_non_generic_type_ok.mvir | 2 +- ...ly_recursive_non_generic_type_ok_enum.mvir | 2 +- ...ree_args_just_type_params_shitfing_ok.mvir | 2 +- ...ee_args_type_con_non_generic_types_ok.mvir | 2 +- ...recursive_three_args_type_con_shifting.exp | 4 +- ...ecursive_three_args_type_con_shifting.mvir | 2 +- ...sive_three_args_type_con_shifting_enum.exp | 4 +- ...ive_three_args_type_con_shifting_enum.mvir | 2 +- ...two_args_swapping_just_type_params_ok.mvir | 2 +- ...y_recursive_two_args_swapping_type_con.exp | 4 +- ..._recursive_two_args_swapping_type_con.mvir | 2 +- ...ursive_two_args_swapping_type_con_enum.exp | 4 +- ...rsive_two_args_swapping_type_con_enum.mvir | 2 +- .../mutually_recursive_type_con.exp | 4 +- .../mutually_recursive_type_con.mvir | 2 +- .../mutually_recursive_type_con_enum.exp | 4 +- .../mutually_recursive_type_con_enum.mvir | 2 +- .../nested_types_1_enum.exp | 4 +- .../nested_types_1_enum.mvir | 2 +- .../instantiation_loops/nested_types_2.exp | 4 +- .../instantiation_loops/nested_types_2.mvir | 2 +- .../nested_types_2_enum_struct.exp | 4 +- .../nested_types_2_enum_struct.mvir | 2 +- .../recursive_infinite_type_terminates.exp | 4 +- .../recursive_infinite_type_terminates.mvir | 2 +- ...recursive_one_arg_just_type_params_ok.mvir | 2 +- ...recursive_one_arg_non_generic_type_ok.mvir | 2 +- .../recursive_one_arg_type_con.exp | 4 +- .../recursive_one_arg_type_con.mvir | 2 +- .../recursive_one_arg_type_con_enum.exp | 4 +- .../recursive_one_arg_type_con_enum.mvir | 2 +- ...ursive_two_args_swapping_type_con_enum.exp | 4 +- ...rsive_two_args_swapping_type_con_enum.mvir | 2 +- .../tests/instantiation_loops/two_loops.exp | 4 +- .../tests/instantiation_loops/two_loops.mvir | 2 +- .../instantiation_loops/two_loops_enum.exp | 4 +- .../instantiation_loops/two_loops_enum.mvir | 2 +- .../abort_positive_stack_size.mvir | 4 +- .../cast_negative_stack.exp | 20 +- .../cast_negative_stack.mvir | 10 +- .../cast_positive_stack.exp | 20 +- .../cast_positive_stack.mvir | 10 +- .../stack_usage_verifier/consume_stack.mvir | 2 +- .../function_call_negative_stack_err_1.mvir | 4 +- .../function_call_negative_stack_err_2.mvir | 4 +- ...ion_composition_pos_and_neg_stack_err.mvir | 4 +- ...tion_composition_positive_stack_err_1.mvir | 4 +- ...tion_composition_positive_stack_err_2.mvir | 4 +- .../integer_stack_balanced.mvir | 12 +- .../integer_stack_negative.exp | 24 +- .../integer_stack_negative.mvir | 12 +- .../integer_stack_positive.exp | 24 +- .../integer_stack_positive.mvir | 12 +- .../load_positive_stack.exp | 20 +- .../load_positive_stack.mvir | 10 +- .../multiple_return_values.mvir | 4 +- .../multiple_return_values_extra_binding.mvir | 4 +- .../multiple_return_values_extra_value.exp | 4 +- .../multiple_return_values_extra_value.mvir | 2 +- ...ultiple_return_values_missing_binding.mvir | 4 +- .../multiple_return_values_missing_value.exp | 4 +- .../multiple_return_values_missing_value.mvir | 2 +- .../pack_invalid_number_arguments_enum.exp | 16 +- .../pack_invalid_number_arguments_enum.mvir | 8 +- .../tests/stack_usage_verifier/pop_exact.mvir | 2 +- .../stack_usage_verifier/pop_negative.exp | 4 +- .../stack_usage_verifier/pop_negative.mvir | 2 +- .../stack_usage_verifier/pop_positive.exp | 4 +- .../stack_usage_verifier/pop_positive.mvir | 2 +- .../unpack_extra_binding.exp | 4 +- .../unpack_extra_binding.mvir | 2 +- .../unpack_extra_binding_enum.exp | 16 +- .../unpack_extra_binding_enum.mvir | 8 +- .../unpack_missing_binding.exp | 4 +- .../unpack_missing_binding.mvir | 2 +- .../unpack_missing_binding_enum.exp | 16 +- .../unpack_missing_binding_enum.mvir | 8 +- .../vector_ops_pack_unpack.exp | 12 +- .../vector_ops_pack_unpack.mvir | 6 +- .../crates/language-benchmarks/Cargo.toml | 5 +- .../language-benchmarks/benches/criterion.rs | 59 + .../language-benchmarks/benches/vm_benches.rs | 32 - .../language-benchmarks/src/measurement.rs | 9 +- .../crates/language-benchmarks/src/move_vm.rs | 89 +- .../language-benchmarks/tests/arith.move | 22 + .../language-benchmarks/tests/arith_2.move | 12 + .../tests/basic_alloc.move | 22 + .../{src => tests}/bench.move | 2 +- .../language-benchmarks/tests/call.move | 47 + .../language-benchmarks/tests/call_2.move | 16 + .../language-benchmarks/tests/natives.move | 48 + .../language-benchmarks/tests/transfers.move | 46 + .../language-benchmarks/tests/vector.move | 17 + .../crates/module-generation/src/generator.rs | 31 +- .../move/crates/move-analyzer/Cargo.toml | 1 + .../move-analyzer/editors/code/README.md | 27 +- .../editors/code/language-configuration.json | 4 +- .../editors/code/package-lock.json | 27 +- .../move-analyzer/editors/code/package.json | 17 +- .../editors/code/scripts/create.sh | 18 +- .../editors/code/src/configuration.ts | 2 +- .../move-analyzer/editors/code/src/main.ts | 38 +- .../editors/code/tests/runTests.ts | 4 + .../src/analysis/parsing_analysis.rs | 69 +- .../src/analysis/typing_analysis.rs | 214 +- .../move/crates/move-analyzer/src/analyzer.rs | 14 +- .../crates/move-analyzer/src/completion.rs | 1731 ---------- .../move-analyzer/src/completions/dot.rs | 116 + .../move-analyzer/src/completions/mod.rs | 430 +++ .../src/completions/name_chain.rs | 997 ++++++ .../move-analyzer/src/completions/snippets.rs | 216 ++ .../move-analyzer/src/completions/utils.rs | 131 + .../crates/move-analyzer/src/diagnostics.rs | 14 +- .../move/crates/move-analyzer/src/lib.rs | 2 +- .../move/crates/move-analyzer/src/symbols.rs | 1332 +++++--- .../tests/colon_colon_completion.exp | 534 ++- .../tests/colon_colon_completion.ide | 12 + .../tests/completion/sources/colon_colon.move | 24 + .../crates/move-analyzer/tests/consts.exp | 24 + .../crates/move-analyzer/tests/consts.ide | 12 + .../cursor_tests/cursor_dot_call_tests.exp | 4 +- .../crates/move-analyzer/tests/docstring.exp | 171 +- .../crates/move-analyzer/tests/docstring.ide | 20 + .../crates/move-analyzer/tests/dot_calls.exp | 45 +- .../move-analyzer/tests/dot_completion.exp | 68 +- .../move/crates/move-analyzer/tests/enums.exp | 57 +- .../move/crates/move-analyzer/tests/enums.ide | 4 + .../move-analyzer/tests/ide_testsuite.rs | 121 +- .../move-analyzer/tests/implicit_uses.exp | 12 +- .../crates/move-analyzer/tests/imports.exp | 21 +- .../crates/move-analyzer/tests/macros.exp | 30 +- .../crates/move-analyzer/tests/mod_access.exp | 18 +- .../tests/move-2024/sources/structs.move | 37 + .../same-pkg-name-error/dep-pkg/Move.toml | 9 + .../dep-pkg/sources/M1.move | 4 + .../tests/same-pkg-name-error/pkg/Move.toml | 10 + .../same-pkg-name-error/pkg/sources/M1.move | 15 + .../tests/same_pkg_name_error.exp | 1 + .../tests/same_pkg_name_error.ide | 8 + .../crates/move-analyzer/tests/structs.exp | 122 + .../crates/move-analyzer/tests/structs.ide | 56 + .../crates/move-analyzer/tests/symbols.exp | 221 +- .../crates/move-analyzer/tests/symbols.ide | 28 + .../move-analyzer/tests/symbols/Move.toml | 2 +- .../tests/symbols/sources/M1.move | 8 +- .../tests/symbols/sources/M2.move | 2 +- .../tests/symbols/sources/M3.move | 4 +- .../tests/symbols/sources/M4.move | 31 +- .../tests/symbols/sources/M6.move | 45 +- .../tests/symbols/sources/M7.move | 2 +- .../tests/symbols/sources/M8.move | 8 + .../tests/symbols/sources/M9.move | 2 +- .../trace-adapter/.eslintrc.json | 33 + .../move-analyzer/trace-adapter/.mocharc.yaml | 3 + .../move-analyzer/trace-adapter/.vscodeignore | 11 + .../move-analyzer/trace-adapter/LICENSE | 230 ++ .../move-analyzer/trace-adapter/README.md | 11 + .../trace-adapter/package-lock.json | 2225 +++++++++++++ .../move-analyzer/trace-adapter/package.json | 25 + .../trace-adapter/src/adapter.ts | 536 +++ .../trace-adapter/src/runtime.ts | 1003 ++++++ .../move-analyzer/trace-adapter/src/server.ts | 5 + .../trace-adapter/src/source_map_utils.ts | 370 +++ .../trace-adapter/src/trace_utils.ts | 942 ++++++ .../move-analyzer/trace-adapter/src/utils.ts | 18 + .../trace-adapter/tests/.gitignore | 6 + .../tests/abort_assert/Move.toml | 10 + .../build/abort_assert/bytecode_modules/m.mv | Bin 0 -> 268 bytes .../build/abort_assert/source_maps/m.json | 1 + .../build/abort_assert/sources/m.move | 13 + .../tests/abort_assert/sources/m.move | 13 + .../trace-adapter/tests/abort_assert/test.exp | 1 + .../tests/abort_assert/trace.spec.js | 11 + .../traces/abort_assert__m__test.json | 1 + .../trace-adapter/tests/abort_math/Move.toml | 10 + .../build/abort_math/bytecode_modules/m.mv | Bin 0 -> 245 bytes .../build/abort_math/source_maps/m.json | 1 + .../build/abort_math/sources/m.move | 13 + .../tests/abort_math/sources/m.move | 13 + .../trace-adapter/tests/abort_math/test.exp | 1 + .../tests/abort_math/trace.spec.js | 9 + .../traces/abort_math__m__test.json | 1 + .../tests/abort_native/Move.toml | 10 + .../build/abort_native/bytecode_modules/m.mv | Bin 0 -> 368 bytes .../dependencies/Iota/address.json | 1 + .../dependencies/MoveStdlib/vector.json | 1 + .../build/abort_native/source_maps/m.json | 1 + .../sources/dependencies/Iota/address.move | 87 + .../dependencies/MoveStdlib/vector.move | 375 +++ .../build/abort_native/sources/m.move | 15 + .../tests/abort_native/sources/m.move | 15 + .../trace-adapter/tests/abort_native/test.exp | 1 + .../tests/abort_native/trace.spec.js | 17 + .../traces/abort_native__m__test.json | 1 + .../tests/abort_native_bytecode/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 251 bytes .../dependencies/MoveStdlib/vector.json | 1 + .../abort_native_bytecode/source_maps/m.json | 1 + .../dependencies/MoveStdlib/vector.move | 365 ++ .../abort_native_bytecode/sources/m.move | 14 + .../abort_native_bytecode/sources/m.move | 14 + .../tests/abort_native_bytecode/test.exp | 1 + .../tests/abort_native_bytecode/trace.spec.js | 9 + .../abort_native_bytecode__m__test.json | 1 + .../tests/breakpoints_line/Move.toml | 10 + .../breakpoints_line/bytecode_modules/m.mv | Bin 0 -> 369 bytes .../build/breakpoints_line/source_maps/m.json | 1 + .../build/breakpoints_line/sources/m.move | 30 + .../tests/breakpoints_line/sources/m.move | 30 + .../tests/breakpoints_line/test.exp | 63 + .../tests/breakpoints_line/trace.spec.js | 27 + .../traces/breakpoints_line__m__test.json | 1 + .../trace-adapter/tests/compound/Move.toml | 10 + .../dependencies/MoveStdlib/vector.mv | Bin 0 -> 1123 bytes .../build/compound/bytecode_modules/m.mv | Bin 0 -> 721 bytes .../dependencies/MoveStdlib/vector.json | 1 + .../build/compound/source_maps/m.json | 1 + .../dependencies/MoveStdlib/vector.move | 365 ++ .../compound/build/compound/sources/m.move | 54 + .../tests/compound/sources/m.move | 54 + .../trace-adapter/tests/compound/test.exp | 55 + .../tests/compound/trace.spec.js | 23 + .../compound/traces/compound__m__test.json | 1 + .../trace-adapter/tests/global_loc/Move.toml | 10 + .../build/global_loc/bytecode_modules/m.mv | Bin 0 -> 520 bytes .../source_maps/dependencies/Iota/object.json | 1 + .../dependencies/Iota/tx_context.json | 1 + .../dependencies/MoveStdlib/bcs.json | 1 + .../build/global_loc/source_maps/m.json | 1 + .../sources/dependencies/Iota/object.move | 234 ++ .../sources/dependencies/Iota/tx_context.move | 142 + .../sources/dependencies/MoveStdlib/bcs.move | 12 + .../build/global_loc/sources/m.move | 22 + .../tests/global_loc/sources/m.move | 22 + .../trace-adapter/tests/global_loc/test.exp | 45 + .../tests/global_loc/trace.spec.js | 10 + .../traces/global_loc__m__test.json | 1 + .../trace-adapter/tests/macro_abort/Move.toml | 10 + .../build/macro_abort/bytecode_modules/m.mv | Bin 0 -> 294 bytes .../macro_abort/bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../build/macro_abort/source_maps/m.json | 1 + .../build/macro_abort/source_maps/m_dep.json | 1 + .../build/macro_abort/sources/m.move | 17 + .../build/macro_abort/sources/m_dep.move | 7 + .../tests/macro_abort/sources/m.move | 17 + .../tests/macro_abort/sources/m_dep.move | 7 + .../trace-adapter/tests/macro_abort/test.exp | 1 + .../tests/macro_abort/trace.spec.js | 9 + .../traces/macro_abort__m__test.json | 1 + .../tests/macro_breakpoint/Move.toml | 10 + .../macro_breakpoint/bytecode_modules/m.mv | Bin 0 -> 294 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../build/macro_breakpoint/source_maps/m.json | 1 + .../macro_breakpoint/source_maps/m_dep.json | 1 + .../build/macro_breakpoint/sources/m.move | 17 + .../build/macro_breakpoint/sources/m_dep.move | 7 + .../tests/macro_breakpoint/sources/m.move | 17 + .../tests/macro_breakpoint/sources/m_dep.move | 7 + .../tests/macro_breakpoint/test.exp | 10 + .../tests/macro_breakpoint/trace.spec.js | 12 + .../traces/macro_breakpoint__m__test.json | 1 + .../macro_different_different_files/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 300 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../bytecode_modules/m_dep_dep.mv | Bin 0 -> 196 bytes .../source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../source_maps/m_dep_dep.json | 1 + .../sources/m.move | 19 + .../sources/m_dep.move | 9 + .../sources/m_dep_dep.move | 6 + .../sources/m.move | 20 + .../sources/m_dep.move | 9 + .../sources/m_dep_dep.move | 6 + .../macro_different_different_files/test.exp | 27 + .../trace.spec.js | 18 + ...ro_different_different_files__m__test.json | 1 + .../Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 320 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../bytecode_modules/m_dep_dep.mv | Bin 0 -> 196 bytes .../source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../source_maps/m_dep_dep.json | 1 + .../sources/m.move | 20 + .../sources/m_dep.move | 10 + .../sources/m_dep_dep.move | 6 + .../sources/m.move | 20 + .../sources/m_dep.move | 10 + .../sources/m_dep_dep.move | 6 + .../macro_different_different_files2/test.exp | 35 + .../trace.spec.js | 28 + ...o_different_different_files2__m__test.json | 1 + .../tests/macro_different_files/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 294 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../macro_different_files/source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../macro_different_files/sources/m.move | 17 + .../macro_different_files/sources/m_dep.move | 7 + .../macro_different_files/sources/m.move | 17 + .../macro_different_files/sources/m_dep.move | 7 + .../tests/macro_different_files/test.exp | 22 + .../tests/macro_different_files/trace.spec.js | 16 + .../macro_different_files__m__test.json | 1 + .../macro_different_same_files/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 294 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../macro_different_same_files/sources/m.move | 18 + .../sources/m_dep.move | 13 + .../macro_different_same_files/sources/m.move | 21 + .../sources/m_dep.move | 13 + .../tests/macro_different_same_files/test.exp | 27 + .../macro_different_same_files/trace.spec.js | 18 + .../macro_different_same_files__m__test.json | 1 + .../macro_different_same_files2/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 320 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../sources/m.move | 21 + .../sources/m_dep.move | 14 + .../sources/m.move | 21 + .../sources/m_dep.move | 14 + .../macro_different_same_files2/test.exp | 35 + .../macro_different_same_files2/trace.spec.js | 28 + .../macro_different_same_files2__m__test.json | 1 + .../tests/macro_inner_call/Move.toml | 10 + .../macro_inner_call/bytecode_modules/m.mv | Bin 0 -> 319 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../bytecode_modules/m_dep_dep.mv | Bin 0 -> 217 bytes .../build/macro_inner_call/source_maps/m.json | 1 + .../macro_inner_call/source_maps/m_dep.json | 1 + .../source_maps/m_dep_dep.json | 1 + .../build/macro_inner_call/sources/m.move | 18 + .../build/macro_inner_call/sources/m_dep.move | 9 + .../macro_inner_call/sources/m_dep_dep.move | 5 + .../tests/macro_inner_call/hw_trace.json | 1472 +++++++++ .../tests/macro_inner_call/sources/m.move | 18 + .../tests/macro_inner_call/sources/m_dep.move | 9 + .../macro_inner_call/sources/m_dep_dep.move | 5 + .../tests/macro_inner_call/test.exp | 40 + .../tests/macro_inner_call/trace.spec.js | 19 + .../traces/macro_inner_call__m__test.json | 1 + .../macro_same_different_files/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 294 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../macro_same_different_files/sources/m.move | 27 + .../sources/m_dep.move | 6 + .../macro_same_different_files/sources/m.move | 27 + .../sources/m_dep.move | 6 + .../tests/macro_same_different_files/test.exp | 32 + .../macro_same_different_files/trace.spec.js | 24 + .../macro_same_different_files__m__test.json | 1 + .../macro_same_different_files2/Move.toml | 10 + .../bytecode_modules/m.mv | Bin 0 -> 320 bytes .../bytecode_modules/m_dep.mv | Bin 0 -> 192 bytes .../source_maps/m.json | 1 + .../source_maps/m_dep.json | 1 + .../sources/m.move | 28 + .../sources/m_dep.move | 6 + .../sources/m.move | 28 + .../sources/m_dep.move | 6 + .../macro_same_different_files2/test.exp | 37 + .../macro_same_different_files2/trace.spec.js | 29 + .../macro_same_different_files2__m__test.json | 1 + .../tests/macro_same_file/Move.toml | 10 + .../macro_same_file/bytecode_modules/m.mv | Bin 0 -> 294 bytes .../build/macro_same_file/source_maps/m.json | 1 + .../build/macro_same_file/sources/m.move | 21 + .../tests/macro_same_file/sources/m.move | 21 + .../tests/macro_same_file/test.exp | 30 + .../tests/macro_same_file/trace.spec.js | 25 + .../traces/macro_same_file__m__test.json | 1 + .../trace-adapter/tests/native_fun/Move.toml | 10 + .../build/native_fun/bytecode_modules/m.mv | Bin 0 -> 369 bytes .../dependencies/MoveStdlib/ascii.json | 1 + .../dependencies/MoveStdlib/macros.json | 1 + .../dependencies/MoveStdlib/string.json | 1 + .../dependencies/MoveStdlib/u64.json | 1 + .../dependencies/MoveStdlib/vector.json | 1 + .../build/native_fun/source_maps/m.json | 1 + .../dependencies/MoveStdlib/ascii.move | 167 + .../dependencies/MoveStdlib/macros.move | 103 + .../dependencies/MoveStdlib/string.move | 138 + .../sources/dependencies/MoveStdlib/u64.move | 80 + .../dependencies/MoveStdlib/vector.move | 365 ++ .../build/native_fun/sources/m.move | 14 + .../tests/native_fun/sources/m.move | 14 + .../trace-adapter/tests/native_fun/test.exp | 6 + .../tests/native_fun/trace.spec.js | 8 + .../traces/native_fun__m__test.json | 1 + .../trace-adapter/tests/references/Move.toml | 10 + .../dependencies/MoveStdlib/vector.mv | Bin 0 -> 1123 bytes .../build/references/bytecode_modules/m.mv | Bin 0 -> 612 bytes .../dependencies/MoveStdlib/vector.json | 1 + .../build/references/source_maps/m.json | 1 + .../dependencies/MoveStdlib/vector.move | 365 ++ .../build/references/sources/m.move | 45 + .../tests/references/sources/m.move | 45 + .../trace-adapter/tests/references/test.exp | 90 + .../tests/references/trace.spec.js | 21 + .../traces/references__m__test.json | 1 + .../tests/references_deep/Move.toml | 10 + .../dependencies/MoveStdlib/vector.mv | Bin 0 -> 1123 bytes .../references_deep/bytecode_modules/m.mv | Bin 0 -> 504 bytes .../dependencies/MoveStdlib/vector.json | 1 + .../build/references_deep/source_maps/m.json | 1 + .../dependencies/MoveStdlib/vector.move | 365 ++ .../build/references_deep/sources/m.move | 34 + .../tests/references_deep/sources/m.move | 34 + .../tests/references_deep/test.exp | 74 + .../tests/references_deep/trace.spec.js | 17 + .../traces/references_deep__m__test.json | 1 + .../trace-adapter/tests/run_spec.js | 52 + .../trace-adapter/tests/shadowing/Move.toml | 10 + .../build/shadowing/bytecode_modules/m.mv | Bin 0 -> 352 bytes .../build/shadowing/source_maps/m.json | 1 + .../shadowing/build/shadowing/sources/m.move | 26 + .../tests/shadowing/sources/m.move | 26 + .../trace-adapter/tests/shadowing/test.exp | 63 + .../tests/shadowing/trace.spec.js | 25 + .../shadowing/traces/shadowing__m__test.json | 1 + .../trace-adapter/tests/stepping/Move.toml | 10 + .../build/stepping/bytecode_modules/m.mv | Bin 0 -> 256 bytes .../build/stepping/source_maps/m.json | 1 + .../stepping/build/stepping/sources/m.move | 16 + .../tests/stepping/sources/m.move | 16 + .../trace-adapter/tests/stepping/test.exp | 20 + .../tests/stepping/trace.spec.js | 14 + .../stepping/traces/stepping__m__test.json | 1 + .../tests/stepping_call/Move.toml | 10 + .../build/stepping_call/bytecode_modules/m.mv | Bin 0 -> 321 bytes .../build/stepping_call/source_maps/m.json | 1 + .../build/stepping_call/sources/m.move | 26 + .../tests/stepping_call/sources/m.move | 26 + .../tests/stepping_call/test.exp | 58 + .../tests/stepping_call/trace.spec.js | 27 + .../traces/stepping_call__m__test.json | 1 + .../move-analyzer/trace-adapter/tsconfig.json | 18 + .../move-analyzer/trace-debug/.eslintrc.json | 33 + .../trace-debug/.vscode/launch.json | 37 + .../move-analyzer/trace-debug/.vscodeignore | 12 + .../crates/move-analyzer/trace-debug/LICENSE | 230 ++ .../move-analyzer/trace-debug/README.md | 49 + .../move-analyzer/trace-debug/images/move.png | Bin 0 -> 256463 bytes .../trace-debug/package-lock.json | 1685 ++++++++++ .../move-analyzer/trace-debug/package.json | 100 + .../trace-debug/src/extension.ts | 325 ++ .../move-analyzer/trace-debug/tsconfig.json | 13 + .../move-binary-format/src/compatibility.rs | 248 +- .../src/compatibility_mode.rs | 259 ++ .../move-binary-format/src/file_format.rs | 42 +- .../src/file_format_common.rs | 18 +- .../move/crates/move-binary-format/src/lib.rs | 1 + .../src/proptest_types/types.rs | 2 +- .../src/unit_tests/compatibility_tests.rs | 93 +- .../move-bytecode-source-map/Cargo.toml | 1 + .../src/source_map.rs | 36 +- .../move-bytecode-source-map/src/utils.rs | 39 +- .../crates/move-bytecode-utils/Cargo.toml | 1 + .../src/dependency_graph.rs | 65 - .../crates/move-bytecode-utils/src/layout.rs | 31 +- .../crates/move-bytecode-utils/src/lib.rs | 38 +- .../src/script_signature.rs | 2 +- .../move/crates/move-cli/Cargo.toml | 5 + .../move/crates/move-cli/src/base/new.rs | 69 +- .../move/crates/move-cli/src/base/test.rs | 58 +- .../move/crates/move-cli/src/sandbox/cli.rs | 17 +- .../move-cli/src/sandbox/commands/run.rs | 2 +- .../crates/move-cli/src/sandbox/utils/mod.rs | 8 - .../build_with_dep_warnings/args.exp | 6 +- .../build_tests/build_with_warnings/args.exp | 6 +- .../build_tests/canonicalize_module/args.exp | 9 +- .../bar/sources/Bar.move | 4 +- .../circular_dependencies/sources/Foo.move | 4 +- .../build_tests/disassemble_module/args.exp | 12 +- .../empty_module_no_deps/sources/A.move | 2 +- .../sources/UseSigner.move | 2 +- .../build_tests/migration/Move.toml.expected | 2 +- .../tests/build_tests/migration/args.exp | 2 +- .../Move.toml.expected | 2 +- .../migration_address_block/args.exp | 2 +- .../migration_edition_not_allowed/args.exp | 2 +- .../migration_multiline/Move.toml.expected | 2 +- .../build_tests/migration_multiline/args.exp | 2 +- .../migration_names/Move.toml.expected | 2 +- .../build_tests/migration_names/args.exp | 2 +- .../Move.toml.expected | 2 +- .../migration_names_mut_allowed/args.exp | 2 +- .../migration_paths/Move.toml.expected | 2 +- .../build_tests/migration_paths/args.exp | 2 +- .../migration_with_blocking_errors/args.exp | 2 +- .../new_clobber/gitignore_exists/args.exp | 8 + .../new_clobber/gitignore_exists/args.txt | 4 + .../gitignore_exists/package/.gitignore | 1 + .../{simple_new => new_simple}/args.exp | 4 + .../{simple_new => new_simple}/args.txt | 2 + .../sources/Foo.move | 2 +- .../sources/Foo.move | 2 +- .../sources/Foo.move | 2 +- .../sources/Foo.move | 2 +- .../rebuild_no_modification/sources/Foo.move | 2 +- .../simple_build_with_docs/sources/Foo.move | 2 +- .../unbound_dependency/sources/A.move | 2 +- .../move_unit_tests/bytecode_deps/B/Move.toml | 8 + .../bytecode_deps/B/sources/Bar.move | 8 + .../move_unit_tests/bytecode_deps/C/Move.toml | 5 + .../bytecode_deps/C/sources/Foo.move | 5 + .../move_unit_tests/bytecode_deps/Move.toml | 15 + .../move_unit_tests/bytecode_deps/args.exp | 17 + .../move_unit_tests/bytecode_deps/args.txt | 7 + .../bytecode_deps/sources/A.move | 13 + .../generate_struct_layout/args.exp | 118 +- .../generate_struct_layout/args.txt | 40 +- .../generate_struct_layout/sources/M1.move | 4 +- .../generate_struct_layout/sources/M2.move | 2 +- .../sources/phantoms.move | 2 +- .../sandbox_tests/module_disassemble/args.exp | 22 +- .../module_publish_view/args.exp | 6 +- .../multi_module_publish/args.exp | 32 +- .../multi_module_publish/args.txt | 4 +- .../sources/GoodFriends.move | 6 +- .../sandbox_tests/package_basics/args.exp | 33 +- .../sandbox_tests/print_stack_trace/args.exp | 16 +- .../print_stack_trace/sources/M.move | 2 +- .../print_stack_trace/sources/N.move | 4 +- .../sources/print_stack_trace.move | 2 +- .../sources/m.move | 2 +- .../tracing-unit-tests/Move.toml | 9 + .../tracing-unit-tests/NO_TEMPDIR | 0 .../tracing_tests/tracing-unit-tests/args.exp | 29 + .../tracing_tests/tracing-unit-tests/args.txt | 2 + .../0x1__calls__test_call_order.json | 1 + .../0x1__calls__test_call_return_order.json | 1 + ...0x1__calls__test_complex_nested_calls.json | 1 + .../0x1__calls__test_return_order.json | 1 + .../new_traces/0x1__errors__aborter.json | 1 + .../new_traces/0x1__errors__bad_cast.json | 1 + .../new_traces/0x1__errors__div_0.json | 1 + .../0x1__errors__fail_during_abort.json | 1 + .../0x1__errors__fail_in_native.json | 1 + .../new_traces/0x1__errors__overshift_l.json | 1 + .../new_traces/0x1__errors__overshift_r.json | 1 + .../new_traces/0x1__errors__underflow.json | 1 + ...0x1__natives__get_orig_type_name_test.json | 1 + .../0x1__natives__get_type_name_test.json | 1 + .../0x1__packs__test_gen_pack_order.json | 1 + .../0x1__packs__test_gen_unpack_order.json | 1 + .../0x1__packs__test_pack_order.json | 1 + .../0x1__packs__test_unpack_order.json | 1 + ...ces__nested_struct_reference_mutation.json | 1 + ...ferences__pass_mut_assign_in_other_fn.json | 1 + .../0x1__references__test_struct_borrow.json | 1 + ...1__references__test_vector_mut_borrow.json | 1 + ...eferences__test_vector_mut_borrow_pop.json | 1 + .../0x1__calls__test_call_order.json | 1 + .../0x1__calls__test_call_return_order.json | 1 + ...0x1__calls__test_complex_nested_calls.json | 1 + .../0x1__calls__test_return_order.json | 1 + .../saved_traces/0x1__errors__aborter.json | 1 + .../saved_traces/0x1__errors__bad_cast.json | 1 + .../saved_traces/0x1__errors__div_0.json | 1 + .../0x1__errors__fail_during_abort.json | 1 + .../0x1__errors__fail_in_native.json | 1 + .../0x1__errors__overshift_l.json | 1 + .../0x1__errors__overshift_r.json | 1 + .../saved_traces/0x1__errors__underflow.json | 1 + ...0x1__natives__get_orig_type_name_test.json | 1 + .../0x1__natives__get_type_name_test.json | 1 + .../0x1__packs__test_gen_pack_order.json | 1 + .../0x1__packs__test_gen_unpack_order.json | 1 + .../0x1__packs__test_pack_order.json | 1 + .../0x1__packs__test_unpack_order.json | 1 + ...ces__nested_struct_reference_mutation.json | 1 + ...ferences__pass_mut_assign_in_other_fn.json | 1 + .../0x1__references__test_struct_borrow.json | 1 + ...1__references__test_vector_mut_borrow.json | 1 + ...eferences__test_vector_mut_borrow_pop.json | 1 + .../tracing-unit-tests/sources/calls.move | 75 + .../tracing-unit-tests/sources/errors.move | 50 + .../tracing-unit-tests/sources/natives.move | 17 + .../sources/references.move | 74 + .../tracing-unit-tests/sources/structs.move | 44 + .../move-cli/tests/tracing_testsuite.rs | 27 + .../no_git_remote_package/sources/Dummy.move | 2 +- .../valid_package1/sources/Dummy.move | 2 +- .../valid_package2/sources/Dummy.move | 2 +- .../valid_package3/sources/Dummy.move | 2 +- .../move-command-line-common/Cargo.toml | 6 - .../move-command-line-common/src/files.rs | 2 +- .../move-command-line-common/src/lib.rs | 4 - .../derived_line_number_raw_abort.exp | 11 + .../derived_line_number_raw_abort.move | 11 + .../macro_call_line_number_abort.exp | 21 + .../macro_call_line_number_abort.move | 27 + .../tests/control_flow/assert_in_while.move | 2 +- .../control_flow/basic_named_blocks.move | 2 +- .../tests/control_flow/if_assignment.move | 2 +- .../tests/control_flow/nested_blocks.move | 2 +- .../tests/control_flow/nested_loops.move | 2 +- .../return_in_if_branch_taken_no_else.move | 2 +- .../control_flow/unused_named_blocks.move | 2 +- .../tests/dependencies/dependency_order.move | 6 +- .../tests/dependencies/transitive_deps.move | 6 +- .../tests/evaluation_order/binop_aborts.exp | 12 +- .../tests/evaluation_order/binop_aborts.move | 14 +- .../evaluation_order/binop_call_struct.move | 14 +- .../tests/evaluation_order/binop_calls.move | 78 +- .../tests/evaluation_order/macro_calls.move | 2 +- .../evaluation_order/short_circuiting.move | 2 +- .../short_circuiting_invalid.exp | 2 +- .../short_circuiting_invalid.move | 10 +- .../evaluation_order/struct_arguments.move | 10 +- .../tests/functions/large_enum.exp | 10 +- .../tests/functions/large_enum.move | 11 + .../method_is_by_value_even_when_ignored.exp | 4 +- .../method_is_by_value_even_when_ignored.move | 7 +- .../tests/matching/abc_match.move | 2 +- .../tests/matching/abc_match_binder.move | 2 +- .../tests/matching/abc_match_mut_ref.move | 2 +- .../tests/matching/abc_match_no_drop.move | 2 +- .../tests/matching/abc_match_ref.move | 2 +- .../tests/matching/abc_match_twice.move | 2 +- .../matching/abc_match_value_wildcard.move | 2 +- .../tests/matching/at_pattern_lit.move | 2 +- .../tests/matching/awful_naming_0.exp | 1 + .../tests/matching/awful_naming_0.move | 27 + .../tests/matching/awful_naming_1.exp | 1 + .../tests/matching/awful_naming_1.move | 26 + .../tests/matching/bad_guard_1.move | 2 +- .../tests/matching/bad_guard_2.move | 2 +- .../tests/matching/bind_subject.move | 2 +- .../tests/matching/const_at.move | 2 +- .../tests/matching/const_in_guard.move | 2 +- .../tests/matching/const_matching.move | 2 +- .../tests/matching/const_mut_guard.move | 2 +- .../tests/matching/const_pair.move | 2 +- .../tests/matching/const_result.move | 2 +- .../tests/matching/const_self.move | 2 +- .../tests/matching/drop_ref.move | 2 +- .../tests/matching/enum_no_tyargs_match.move | 2 +- .../tests/matching/enum_poly_match.move | 2 +- .../tests/matching/exhaustive_struct.move | 2 +- .../tests/matching/fib.move | 2 +- .../tests/matching/go_repro.exp | 0 .../tests/matching/guard.move | 2 +- .../tests/matching/guard_backtrack.move | 2 +- .../tests/matching/guard_backtrack_2.move | 2 +- .../tests/matching/guard_backtrack_3.move | 2 +- .../tests/matching/guard_backtrack_4.move | 2 +- .../tests/matching/guard_backtrack_5.move | 2 +- .../tests/matching/index_syntax_0.exp | 1 + .../tests/matching/index_syntax_0.move | 35 + .../tests/matching/index_syntax_1.exp | 1 + .../tests/matching/index_syntax_1.move | 34 + .../tests/matching/index_syntax_2.exp | 1 + .../tests/matching/index_syntax_2.move | 39 + .../tests/matching/lit_abort.exp | 1 + .../tests/matching/lit_abort.move | 19 + .../tests/matching/lit_match.move | 2 +- .../tests/matching/lit_mut_borrow_match.move | 2 +- .../tests/matching/macro_match.move | 2 +- .../tests/matching/match_lit_mut_bind.exp | 1 + .../tests/matching/match_lit_mut_bind.move | 26 + .../tests/matching/match_mut_lit.move | 2 +- .../tests/matching/match_type.move | 2 +- .../tests/matching/multi_or.move | 2 +- .../tests/matching/mut_field_alias.exp | 1 + .../tests/matching/mut_field_alias.move | 22 + .../tests/matching/nested_at.move | 2 +- .../matching/rhs_shadow_loop_label_0.exp | 1 + .../matching/rhs_shadow_loop_label_0.move | 56 + .../matching/rhs_shadow_loop_label_1.exp | 1 + .../matching/rhs_shadow_loop_label_1.move | 50 + .../matching/rhs_shadow_loop_label_2.exp | 1 + .../matching/rhs_shadow_loop_label_2.move | 58 + .../matching/rhs_shadow_loop_label_3.exp | 1 + .../matching/rhs_shadow_loop_label_3.move | 58 + .../tests/matching/stack_interp.exp | 1 + .../tests/matching/stack_interp.move | 117 + .../tests/matching/stack_interp_macro.exp | 1 + .../tests/matching/stack_interp_macro.move | 118 + .../tests/matching/struct_abort.exp | 1 + .../tests/matching/struct_abort.move | 19 + .../tests/matching/struct_match.move | 2 +- .../tests/matching/struct_match_mut.move | 2 +- .../tests/matching/true_false_abort.exp | 1 + .../tests/matching/true_false_abort.move | 17 + .../matching/true_false_nested_abort.exp | 1 + .../matching/true_false_nested_abort.move | 17 + .../operators/arithmetic_operators_u32.exp | 20 +- .../operators/arithmetic_operators_u32.move | 32 +- .../tests/operators/bitwise_operators.move | 4 +- .../tests/operators/eq_refs.move | 2 +- .../tests/operators/shift_operators.exp | 20 +- .../tests/operators/shift_operators.move | 30 +- .../tests/syntax/index_syntax.move | 2 +- .../move/crates/move-compiler/Cargo.toml | 2 + .../move/crates/move-compiler/README.md | 2 +- .../crates/move-compiler/src/cfgir/ast.rs | 56 +- .../move-compiler/src/cfgir/borrows/mod.rs | 19 +- .../crates/move-compiler/src/cfgir/cfg.rs | 18 +- .../move-compiler/src/cfgir/liveness/mod.rs | 32 +- .../move-compiler/src/cfgir/locals/mod.rs | 72 +- .../crates/move-compiler/src/cfgir/mod.rs | 25 +- .../src/cfgir/optimize/constant_fold.rs | 43 +- .../src/cfgir/optimize/eliminate_locals.rs | 6 +- .../src/cfgir/optimize/forwarding_jumps.rs | 2 + .../src/cfgir/optimize/inline_blocks.rs | 2 + .../move-compiler/src/cfgir/optimize/mod.rs | 7 +- .../src/cfgir/optimize/simplify_jumps.rs | 2 + .../move-compiler/src/cfgir/translate.rs | 219 +- .../crates/move-compiler/src/cfgir/visitor.rs | 404 ++- .../src/command_line/compiler.rs | 58 +- .../move-compiler/src/diagnostics/codes.rs | 69 +- .../move-compiler/src/diagnostics/mod.rs | 377 +-- .../src/diagnostics/warning_filters.rs | 561 ++++ .../crates/move-compiler/src/editions/mod.rs | 64 +- .../src/expansion/alias_map_builder.rs | 6 +- .../crates/move-compiler/src/expansion/ast.rs | 196 +- .../crates/move-compiler/src/expansion/mod.rs | 1 + .../src/expansion/name_validation.rs | 426 +++ .../src/expansion/path_expander.rs | 145 +- .../src/expansion/primitive_definers.rs | 28 +- .../move-compiler/src/expansion/translate.rs | 930 ++---- .../move/crates/move-compiler/src/hlir/ast.rs | 198 +- .../src/hlir/detect_dead_code.rs | 1097 +++--- .../src/hlir/match_compilation.rs | 687 ++-- .../move-compiler/src/hlir/translate.rs | 805 +++-- .../move-compiler/src/iota_mode/id_leak.rs | 91 +- .../move-compiler/src/iota_mode/info.rs | 314 ++ .../src/iota_mode/linters/coin_field.rs | 70 +- .../iota_mode/linters/collection_equality.rs | 130 +- .../iota_mode/linters/custom_state_change.rs | 90 +- .../src/iota_mode/linters/freeze_wrapped.rs | 106 +- .../iota_mode/linters/freezing_capability.rs | 79 +- .../src/iota_mode/linters/missing_key.rs | 61 +- .../src/iota_mode/linters/mod.rs | 16 +- .../linters/public_mut_tx_context.rs | 69 +- .../src/iota_mode/linters/public_random.rs | 62 +- .../src/iota_mode/linters/self_transfer.rs | 30 +- .../src/iota_mode/linters/share_owned.rs | 205 +- .../crates/move-compiler/src/iota_mode/mod.rs | 9 + .../move-compiler/src/iota_mode/typing.rs | 139 +- .../src/linters/abort_constant.rs | 102 + .../src/linters/combinable_comparisons.rs | 238 ++ .../src/linters/constant_naming.rs | 53 +- .../src/linters/equal_operands.rs | 57 + .../src/linters/loop_without_exit.rs | 49 + .../src/linters/meaningless_math_operation.rs | 118 + .../crates/move-compiler/src/linters/mod.rs | 198 +- .../src/linters/redundant_ref_deref.rs | 132 + .../src/linters/self_assignment.rs | 175 + .../src/linters/unnecessary_conditional.rs | 97 + .../src/linters/unnecessary_unit.rs | 83 + .../src/linters/unnecessary_while_loop.rs | 50 +- .../src/linters/unneeded_return.rs | 196 ++ .../crates/move-compiler/src/naming/ast.rs | 188 +- .../move-compiler/src/naming/fake_natives.rs | 9 +- .../src/naming/resolve_use_funs.rs | 69 +- .../src/naming/syntax_methods.rs | 58 +- .../move-compiler/src/naming/translate.rs | 440 +-- .../crates/move-compiler/src/parser/ast.rs | 94 +- .../crates/move-compiler/src/parser/lexer.rs | 279 +- .../crates/move-compiler/src/parser/mod.rs | 129 +- .../crates/move-compiler/src/parser/syntax.rs | 283 +- .../move-compiler/src/parser/token_set.rs | 8 + .../parser/verification_attribute_filter.rs | 16 +- .../crates/move-compiler/src/shared/ide.rs | 2 +- .../move-compiler/src/shared/matching.rs | 20 +- .../crates/move-compiler/src/shared/mod.rs | 410 +-- .../move-compiler/src/shared/program_info.rs | 37 +- .../move-compiler/src/shared/string_utils.rs | 7 + .../move-compiler/src/shared/unique_map.rs | 144 + .../src/to_bytecode/canonicalize_handles.rs | 2 +- .../move-compiler/src/to_bytecode/context.rs | 4 +- .../src/to_bytecode/translate.rs | 52 +- .../crates/move-compiler/src/typing/ast.rs | 175 +- .../crates/move-compiler/src/typing/core.rs | 203 +- .../src/typing/dependency_ordering.rs | 24 +- .../src/typing/deprecation_warnings.rs | 34 +- .../crates/move-compiler/src/typing/expand.rs | 31 +- .../src/typing/infinite_instantiations.rs | 13 +- .../move-compiler/src/typing/macro_expand.rs | 35 +- .../src/typing/match_analysis.rs | 44 +- .../src/typing/match_compilation.rs | 2917 ---------------- .../src/typing/recursive_datatypes.rs | 7 +- .../src/typing/syntax_methods.rs | 32 +- .../move-compiler/src/typing/translate.rs | 491 ++- .../move-compiler/src/typing/visitor.rs | 918 +++++- .../src/unit_test/filter_test_members.rs | 15 +- .../crates/move-compiler/src/unit_test/mod.rs | 4 + .../src/unit_test/plan_builder.rs | 99 +- .../tests/iota_mode/linter/coin_field.exp | 14 +- .../iota_mode/linter/custom_state_change.exp | 22 +- .../iota_mode/linter/custom_state_change.move | 10 +- .../linter/false_positive_share_owned.exp | 34 + .../linter/false_positive_share_owned.move | 77 + .../iota_mode/linter/freeze_wrapped.move | 3 +- .../freezing_capability_false_negatives.move | 3 +- .../freezing_capability_false_positives.move | 3 +- .../freezing_capability_suppression.move | 3 +- .../freezing_capability_true_negatives.move | 3 +- .../freezing_capability_true_positives.move | 3 +- .../tests/iota_mode/linter/self_transfer.move | 8 +- .../tests/iota_mode/linter/share_owned.exp | 27 - .../tests/iota_mode/linter/share_owned.move | 60 - .../linter/true_negative_share_owned.move | 108 + .../linter/true_positive_share_owned.exp | 34 + .../linter/true_positive_share_owned.move | 77 + ...ruct_id_field_incorrect_struct_address.exp | 8 +- ...uct_id_field_incorrect_struct_address.move | 3 +- .../linter/correct_redundant_ref_deref.move | 10 + ...false_negative_combinable_comparisons.move | 7 + .../linter/false_negative_equal_operands.move | 8 + .../false_negative_loop_without_exit.move | 15 + ...e_negative_meaningless_math_operation.move | 13 + .../linter/false_negative_self_assigment.move | 26 + ...alse_negative_unnecessary_conditional.move | 14 + .../linter/incorrect_redundant_ref_deref.exp | 172 + .../linter/incorrect_redundant_ref_deref.move | 140 + .../move_2024/allowed_unneeded_return.move | 56 + .../false_negative_equal_operands.move | 8 + .../linter/move_2024/ref_deref_complex.exp | 72 + .../linter/move_2024/ref_deref_complex.move | 53 + .../move_2024/ref_deref_conditional.exp | 113 + .../move_2024/ref_deref_conditional.move | 89 + .../ref_deref_conditional_valid.move | 85 + .../linter/move_2024/ref_deref_fields.exp | 80 + .../linter/move_2024/ref_deref_fields.move | 71 + .../move_2024/ref_deref_fields_valid.move | 49 + .../linter/move_2024/unneeded_return.exp | 137 + .../linter/move_2024/unneeded_return.move | 46 + .../move_2024/unneeded_return_branch.exp | 113 + .../move_2024/unneeded_return_branch.move | 69 + .../linter/move_2024/unneeded_return_okay.exp | 54 + .../move_2024/unneeded_return_okay.move | 31 + .../tests/linter/redundant_ref_deref.exp | 24 + .../tests/linter/redundant_ref_deref.move | 20 + .../tests/linter/ref_deref_negative.move | 21 + .../tests/linter/ref_deref_path.exp | 16 + .../tests/linter/ref_deref_path.move | 7 + .../tests/linter/ref_deref_triple.exp | 16 + .../tests/linter/ref_deref_triple.move | 7 + .../tests/linter/suppress_abort_constant.move | 19 + .../suppress_combinable_comparisons.move | 17 + .../tests/linter/suppress_equal_operands.move | 9 + .../linter/suppress_loop_without_exit.move | 7 + .../suppress_meaningless_math_operation.move | 8 + .../linter/suppress_self_assignment.move | 15 + .../suppress_unnecessary_conditional.move | 17 + .../linter/suppress_unnecessary_unit.move | 12 + .../suppress_unnecessary_while_loop.move | 4 +- .../suppressed_case_redundant_ref_deref.move | 17 + .../linter/true_negative_abort_constant.move | 17 + .../true_negative_loop_without_exit.move | 19 + ...e_negative_meaningless_math_operation.move | 17 + .../linter/true_negative_self_assignment.move | 63 + ...true_negative_unnecessary_conditional.move | 17 + .../true_negative_unnecessary_unit.move | 12 + .../linter/true_positive_abort_constant.exp | 126 + .../linter/true_positive_abort_constant.move | 72 + .../true_positive_combinable_comparisons.exp | 1136 +++++++ .../true_positive_combinable_comparisons.move | 161 + .../linter/true_positive_equal_operands.exp | 144 + .../linter/true_positive_equal_operands.move | 24 + .../true_positive_loop_without_exit.exp | 27 + .../true_positive_loop_without_exit.move | 19 + ...ue_positive_meaningless_math_operation.exp | 340 ++ ...e_positive_meaningless_math_operation.move | 60 + .../linter/true_positive_self_assignment.exp | 318 ++ .../linter/true_positive_self_assignment.move | 55 + .../true_positive_unnecessary_conitional.exp | 52 + .../true_positive_unnecessary_conitional.move | 15 + .../linter/true_positive_unnecessary_unit.exp | 151 + .../true_positive_unnecessary_unit.move | 52 + .../true_positive_unnecessary_while_loop.exp | 4 +- .../move_2024/cfgir/cfg_conditional.move | 9 + .../tests/move_2024/cfgir/cfg_panic_0.move | 9 + .../tests/move_2024/cfgir/cfg_panic_1.move | 7 + .../tests/move_2024/cfgir/expand_test.move | 19 + .../move_2024/cfgir/named_loop_no_value.move | 7 + .../expansion/type_hole_as_type_param.exp | 12 +- .../move_2024/folding/equal_operand.move | 24 + .../folding/equal_operand_false_negative.move | 26 + .../tests/move_2024/hlir/abort_pair.exp | 8 + .../tests/move_2024/hlir/abort_pair.move | 5 + .../tests/move_2024/hlir/break_outer_loop.exp | 10 + .../move_2024/hlir/break_outer_loop.move | 19 + .../tests/move_2024/hlir/dead_code_guard.exp | 6 +- .../move_2024/hlir/dead_code_nested_block.exp | 29 + .../hlir/dead_code_nested_block.move | 17 + .../tests/move_2024/hlir/determine_error.move | 5 + .../move_2024/hlir/if_abort_statement.exp | 8 + .../move_2024/hlir/if_abort_statement.move | 6 + ...rol_exp_associativity_unreachable_code.exp | 8 + ...ol_exp_associativity_unreachable_code.move | 30 + .../tests/move_2024/hlir/nested_if_abort.move | 9 + .../hlir/nested_if_abort_statement.exp | 16 + .../hlir/nested_if_abort_statement.move | 10 + .../hlir/nested_named_block_inner_break.move | 9 + .../move_2024/hlir/no_dead_code_block.move | 25 + .../tests/move_2024/hlir/return_value.exp | 10 + .../tests/move_2024/hlir/return_value.move | 15 + .../hlir/true_false_nested_abort.move | 17 + .../ide_mode/chain_lower_case_incomplete.exp | 6 + .../ide_mode/chain_lower_case_incomplete.ide | 0 .../chain_lower_case_incomplete.ide.exp | 34 + .../ide_mode/chain_lower_case_incomplete.move | 7 + .../ide_mode/chain_upper_case_incomplete.exp | 6 + .../ide_mode/chain_upper_case_incomplete.ide | 0 .../chain_upper_case_incomplete.ide.exp | 34 + .../ide_mode/chain_upper_case_incomplete.move | 7 + .../move_2024/ide_mode/dot_incomplete.exp | 18 + .../move_2024/ide_mode/dot_incomplete.ide.exp | 42 + .../method_and_field_autocomplete.ide.exp | 54 + .../ide_mode/method_autocomplete.ide.exp | 42 + .../named_struct_autocomplete.ide.exp | 6 + .../named_struct_middle_autocomplete.ide.exp | 6 + .../ide_mode/on_dot_autocomplete.exp | 15 + .../ide_mode/on_dot_autocomplete.ide | 0 .../ide_mode/on_dot_autocomplete.ide.exp | 105 + .../ide_mode/on_dot_autocomplete.move | 25 + .../positional_struct_autocomplete.ide.exp | 6 + .../ide_mode/seq_item_after_incomplete.exp | 75 + .../ide_mode/seq_item_after_incomplete.move | 56 + ...struct_method_invalid_autocomplete.ide.exp | 12 + .../ide_mode/type_param_autocomplete.ide.exp | 17 + .../type_param_no_autocomplete.ide.exp | 17 + .../ide_mode/use_fun_autocomplete.ide.exp | 12 + .../abc_match_no_drop_exhaustive_invalid.exp | 12 + .../abc_match_no_drop_exhaustive_invalid.move | 18 + .../tests/move_2024/matching/generated_0.move | 418 +++ .../tests/move_2024/matching/go_match.move | 15 + .../tests/move_2024/matching/go_repro.move | 16 + .../move_2024/matching/guard_invalid_copy.exp | 24 +- .../matching/guard_invalid_copy.move | 46 +- .../tests/move_2024/matching/guard_wild.move | 13 + .../matching/guard_wild_inexhaustive.exp | 8 + .../matching/guard_wild_inexhaustive.move | 13 + .../matching/guard_wild_initial.move | 14 + .../move_2024/matching/if_compilation.move | 9 + .../matching/inferred_int_complex.move | 14 + .../matching/inferred_int_mut_ref_type.move | 5 + .../matching/inferred_int_ref_type.move | 5 + .../matching/inferred_int_subject.move | 5 + .../move_2024/matching/invalid_match_lhs.exp | 17 + .../move_2024/matching/invalid_match_lhs.move | 12 + .../matching/invalid_match_tuple.exp | 23 +- .../tests/move_2024/matching/invalid_mut.exp | 12 +- .../matching/invalid_named_match_2.exp | 8 +- .../matching/invalid_or_binding_2.exp | 16 +- .../matching/invalid_or_binding_3.exp | 12 + .../matching/invalid_or_binding_3.move | 12 + .../matching/invalid_or_binding_4.exp | 28 + .../matching/invalid_or_binding_4.move | 13 + .../move_2024/matching/invalid_or_pattern.exp | 17 + .../matching/invalid_or_pattern.move | 12 + .../move_2024/matching/invalid_or_types.exp | 11 + .../move_2024/matching/invalid_or_types.move | 12 + .../move_2024/matching/invalid_or_types_2.exp | 11 + .../matching/invalid_or_types_2.move | 12 + .../move_2024/matching/invalid_or_types_3.exp | 11 + .../matching/invalid_or_types_3.move | 12 + .../move_2024/matching/invalid_or_types_4.exp | 11 + .../matching/invalid_or_types_4.move | 13 + .../matching/invalid_positional_ctor.exp | 8 +- .../matching/invalid_positional_match_2.exp | 8 +- .../matching/invalid_raw_variant_name.exp | 33 + .../matching/invalid_raw_variant_name.move | 13 + .../matching/invalid_struct_form.exp | 16 +- .../tests/move_2024/matching/lit_abort.move | 19 + .../matching/matching_everywhere.move | 51 + .../move_2024/matching/mut_field_alias.move | 17 + .../move_2024/matching/mut_field_alias_2.move | 17 + .../matching/rhs_shadow_loop_label.move | 49 + .../matching/rhs_shadow_loop_with_or.move | 44 + .../move_2024/matching/stack_interp.move | 117 + .../matching/stack_interp_macro.move | 118 + .../move_2024/matching/struct_abort.move | 19 + .../move_2024/matching/true_false_abort.move | 17 + .../matching/true_false_nested_abort.move | 17 + .../tests/move_2024/migration/match_okay.exp | 4 +- .../naming/lambda_shadows_function.exp | 16 +- .../naming/pattern_ellipsis_invalid.exp | 12 - ...sitional_pack_of_non_positional_struct.exp | 8 +- .../naming/positional_struct_lhs_unpack.exp | 44 +- .../positional_struct_non_positional_pack.exp | 8 +- ...ositional_struct_non_positional_unpack.exp | 16 +- ...tional_unpack_of_non_positional_struct.exp | 16 +- .../tests/move_2024/parser/dot_incomplete.exp | 8 - ...positional_struct_unpack_deeply_nested.exp | 20 +- .../labeled_control_exp_associativity.move | 4 +- ..._exp_associativity_else_after_if_block.exp | 24 +- ...ntrol_exp_associativity_typing_invalid.exp | 6 +- ...rol_exp_associativity_unreachable_code.exp | 8 - .../parser/mut_field_pun_invalid_assign.exp | 2 +- .../parser/mut_field_pun_invalid_pack.exp | 2 +- .../parser/pattern_ellipsis_invalid.exp | 2 +- ...positional_struct_fields_keyword_field.exp | 2 +- .../parsing/clever_errors_raw_abort.move | 40 + .../parsing/expr_abort_missing_value.move | 5 + .../typing/eq_refs_struct_invalid_no_drop.exp | 258 +- .../typing/invalid_deprecation_attributes.exp | 2 +- .../move_2024/typing/let_mut_macro_return.exp | 13 +- ...pes_checked_invalid_constraints_simple.exp | 21 +- ...es_checked_invalid_constraints_simple.move | 2 +- .../typing/named_block_invalid_if.exp | 12 + .../typing/named_block_invalid_if.move | 7 + .../control_flow/while_after_while.move | 6 + .../move_check/expansion/duplicate_alias.exp | 16 +- .../expansion/invalid_local_name.exp | 12 +- .../invalid_unpack_assign_lhs_other_value.exp | 2 +- .../invalid_unpack_assign_mdot_no_struct.exp | 2 +- .../expansion/mdot_with_non_address_exp.exp | 2 +- .../expansion/pack_no_fields_block_expr.exp | 2 +- .../pack_no_fields_single_block_expr.exp | 4 +- ...pack_no_fields_single_block_other_expr.exp | 18 +- .../type_arguments_on_field_access.exp | 2 +- .../expansion/unpack_assign_block_expr.exp | 14 +- .../unpack_assign_block_single_expr.exp | 2 +- .../expansion/unpack_assign_other_expr.exp | 38 +- .../use_function_same_name_as_function.exp | 16 +- .../use_function_same_name_as_struct.exp | 16 +- .../expansion/use_inner_scope_duplicates.exp | 22 +- .../use_struct_same_name_as_function.exp | 20 +- .../use_struct_same_name_as_struct.exp | 20 +- .../move_check/feature_gate/dot_call.exp | 14 +- .../move_check/feature_gate/macro_call.exp | 2 +- .../feature_gate/macro_definition.exp | 4 +- .../macro_definition_with_usage.exp | 6 +- .../move_check/feature_gate/macro_lambda.exp | 4 +- .../feature_gate/public_package.exp | 2 +- .../move_check/ide_mode/dot_incomplete.move | 2 +- .../named_struct_autocomplete.ide.exp | 28 + .../move_check/liveness/loop_weirdness.exp | 12 - .../move_check/liveness/loop_weirdness.move | 1 + .../tests/move_check/liveness/nested_dead.exp | 8 - .../liveness/nested_dead_single.exp | 8 + .../liveness/nested_dead_single.move | 5 + .../liveness/trailing_semi_single.exp | 12 + .../liveness/trailing_semi_single.move | 5 + .../move_check/naming/assert_one_arg.exp | 6 +- .../duplicate_type_parameter_struct.exp | 32 +- .../naming/named_blocks_invalid.exp | 36 +- .../naming/other_builtins_invalid.exp | 4 +- .../naming/syntax_annotations_unsupported.exp | 10 +- .../naming/type_hole_gated_invalid_usage.exp | 22 +- .../naming/type_hole_gated_valid_usage.exp | 2 +- .../naming/unknown_assertion_annotation.exp | 2 +- .../move_check/naming/var_as_fun_invalid.exp | 2 +- .../ability_modifier_infix_and_postfix.exp | 16 +- ...ifier_invalid_infix_with_valid_postfix.exp | 2 +- ...bility_modifier_postfix_missing_commas.exp | 2 +- ..._postfix_missing_semi_multiple_structs.exp | 2 +- ..._modifier_postfix_no_abilities_no_semi.exp | 2 +- ...odifier_postfix_no_abilities_with_semi.exp | 2 +- .../ability_modifier_postfix_no_semi.exp | 2 +- .../ability_modifier_postfix_with_semi.exp | 2 +- ...ty_modifies_infix_no_abilities_postfix.exp | 16 +- ...ty_modifies_no_abilities_infix_postfix.exp | 2 +- .../parser/block_comments_inline.exp | 18 + .../parser/block_comments_inline.move | 15 + .../parser/comments_nested_unbalanced.exp | 2 +- ..._exp_associativity_else_after_if_block.exp | 24 +- ...ntrol_exp_associativity_typing_invalid.exp | 6 +- ...rol_exp_associativity_unreachable_code.exp | 8 - .../move_check/parser/copy_move_path.exp | 4 +- .../move_check/parser/empty_doc_comment.move | 16 + .../parser/expr_abort_missing_value.exp | 13 +- .../parser/expr_abort_missing_value.move | 4 +- .../function_conflicting_visibility.exp | 48 +- .../parser/function_type_extra_comma.exp | 2 +- .../invalid_unpack_assign_rhs_not_fields.exp | 4 +- .../parser/named_blocks_invalid_2.exp | 2 +- .../parser/named_blocks_invalid_3.exp | 20 +- .../parser/positional_struct_declaration.exp | 2 +- ...positional_struct_fields_keyword_field.exp | 16 +- .../parser/positional_struct_pack.exp | 20 +- .../parser/positional_struct_unpack.exp | 20 +- .../move_check/parser/return_in_binop.exp | 8 - .../parser/spec_parsing_index_fail.exp | 2 +- .../parser/spec_parsing_lambda_fail.exp | 2 +- .../tests/move_check/parser/struct_public.exp | 12 +- .../parser/struct_type_extra_comma.exp | 2 +- .../move_check/parser/top_level_module.exp | 2 +- .../top_level_module_address_invalid.exp | 12 +- .../use_module_member_invalid_comma.exp | 2 +- .../parser/use_with_modifiers_exp.exp | 2 +- .../parser/vector_literal_unclosed_args.exp | 2 +- .../commands/abort_negative_stack_size.exp | 9 - .../commands/abort_negative_stack_size.move | 7 - .../move/commands/break_unreachable.exp | 6 +- .../move/commands/dead_return.exp | 6 +- .../move/commands/dead_return_local.exp | 6 +- .../move/commands/invalid_fallthrough2.exp | 6 +- .../move/commands/invalid_fallthrough3.exp | 6 +- .../typing/assign_duplicate_assigning.exp | 30 +- .../move_check/typing/assign_wrong_arity.exp | 16 +- .../typing/bind_duplicate_binding.exp | 16 +- .../tests/move_check/typing/cast_invalid.exp | 22 +- .../move_check/typing/clever_assertions.exp | 6 +- .../typing/constant_non_base_type.exp | 18 +- ...satisfied_type_arguments_internal_pack.exp | 8 - .../typing/declare_duplicate_binding.exp | 16 +- .../duplicate_function_parameter_names.exp | 16 +- .../move_check/typing/exp_list_nested.exp | 18 +- .../tests/move_check/typing/if_no_else.exp | 34 + .../tests/move_check/typing/if_no_else.move | 14 + .../typing/instantiate_signatures.exp | 12 +- .../tests/move_check/typing/module_call.exp | 162 +- .../typing/module_call_complicated_rhs.exp | 80 +- .../module_call_constraints_not_satisfied.exp | 54 +- .../typing/native_structs_pack_unpack.exp | 24 +- ...om_params_constraint_abilities_invalid.exp | 126 +- .../move_check/typing/recursive_local.exp | 16 +- .../vector_mismatched_args_non_base_type.exp | 18 +- .../tests/move_check_testsuite.rs | 15 +- .../move/crates/move-core-types/Cargo.toml | 1 + .../move-core-types/src/account_address.rs | 8 + .../src/annotated_extractor.rs | 335 ++ .../move-core-types/src/annotated_value.rs | 103 +- .../move-core-types/src/annotated_visitor.rs | 528 ++- .../crates/move-core-types/src/identifier.rs | 37 +- .../move-core-types/src/language_storage.rs | 72 +- .../move/crates/move-core-types/src/lib.rs | 3 +- .../move/crates/move-core-types/src/parser.rs | 635 ---- .../src/parsing}/address.rs | 25 +- .../crates/move-core-types/src/parsing/mod.rs | 11 + .../src/parsing}/parser.rs | 344 +- .../src/parsing}/types.rs | 14 +- .../src/parsing}/values.rs | 16 +- .../move-core-types/src/runtime_value.rs | 20 +- .../move/crates/move-core-types/src/u256.rs | 12 + .../src/unit_tests/extractor_test.rs | 853 +++++ .../src/unit_tests/identifier_test.rs | 28 + .../move-core-types/src/unit_tests/mod.rs | 2 + .../src/unit_tests/parsing_test.rs | 678 ++++ .../src/unit_tests/value_test.rs | 52 +- .../src/unit_tests/visitor_test.rs | 819 +++-- .../move/crates/move-coverage/Cargo.toml | 1 + .../move-coverage/src/source_coverage.rs | 19 +- .../move/crates/move-disassembler/Cargo.toml | 2 +- .../move-disassembler/src/disassembler.rs | 2304 +++++++------ .../move/crates/move-docgen/src/docgen.rs | 21 +- .../tests/sources/const_string_test.move | 15 + .../sources/const_string_test.spec_inline.md | 56 + .../const_string_test.spec_inline_no_fold.md | 56 + .../const_string_test.spec_separate.md | 56 + .../declarations/function.exp | 16 +- .../bytecode-generation/declarations/let.exp | 8 +- .../bytecode-generation/declarations/let.mvir | 4 +- .../expressions/binary_add.exp | 6 +- .../expressions/borrow.exp | 38 +- .../expressions/borrow.mvir | 8 +- .../expressions/borrow_mut.exp | 20 +- .../expressions/borrow_mut.mvir | 2 +- .../expressions/builtins/vector.exp | 8 +- .../expressions/builtins/vector.mvir | 2 +- .../expressions/combined.exp | 8 +- .../expressions/combined.mvir | 2 +- .../bytecode-generation/expressions/pack.exp | 6 +- .../expressions/unpack.exp | 8 +- .../expressions/unpack.mvir | 2 +- .../bytecode-generation/statements/assert.exp | 8 +- .../statements/assert.mvir | 2 +- .../statements/assign.mvir | 2 +- .../bytecode-generation/statements/enums.exp | 9 +- .../bytecode-generation/statements/jump.exp | 16 +- .../bytecode-generation/statements/jump.mvir | 6 +- .../statements/jump_if.exp | 32 +- .../statements/jump_if.mvir | 8 +- .../statements/jump_if_false.exp | 32 +- .../statements/jump_if_false.mvir | 8 +- .../tests/parsing/comments.exp | 40 +- .../tests/parsing/comments.mvir | 12 +- .../tests/parsing/crlf.exp | 40 +- .../tests/parsing/crlf.mvir | 12 +- .../tests/parsing/keywords.mvir | 2 +- .../tests/parsing/named_addresses.exp | 11 +- .../tests/parsing/types.mvir | 4 +- .../move-ir-to-bytecode-syntax/src/lexer.rs | 2 +- .../move-ir-to-bytecode-syntax/src/syntax.rs | 51 +- .../move-ir-to-bytecode/src/compiler.rs | 120 +- .../move/crates/move-ir-types/src/ast.rs | 64 +- .../move-model/src/builder/model_builder.rs | 1 + .../move-model/src/builder/module_builder.rs | 30 +- .../move/crates/move-model/src/lib.rs | 30 +- .../move/crates/move-model/src/model.rs | 58 +- .../move/crates/move-model/src/ty.rs | 6 + .../move/crates/move-model/tests/testsuite.rs | 4 +- .../src/compilation/compiled_package.rs | 23 +- .../move-package/src/lock_file/schema.rs | 34 +- .../crates/move-package/src/migration/mod.rs | 4 +- .../crates/move-package/src/package_hooks.rs | 28 +- .../src/resolution/dependency_cache.rs | 50 +- .../src/resolution/dependency_graph.rs | 295 +- .../crates/move-package/src/resolution/mod.rs | 29 +- .../src/resolution/resolution_graph.rs | 19 +- .../src/resolution/resolving_table.rs | 6 + .../src/source_package/manifest_parser.rs | 90 +- .../src/source_package/parsed_manifest.rs | 21 +- .../tests/test_dependency_graph.rs | 34 +- .../move-package/tests/test_lock_file.rs | 12 +- .../crates/move-package/tests/test_runner.rs | 19 +- .../test_sources/basic_no_deps/Move.locked | 2 +- .../test_sources/basic_no_deps/sources/A.move | 2 +- .../Move.locked | 2 +- .../basic_no_deps_test_mode/sources/A.move | 2 +- .../sources/ATest.move | 2 +- .../case_insensitive_check/sources/Set.move | 2 +- .../case_insensitive_check/sources/a.move | 2 +- .../case_insensitive_check/sources/foo.move | 2 +- .../sources/otherModule.move | 2 +- .../dep_dev_dep_diamond/Move.locked | 22 +- .../test_sources/dep_good_digest/Move.locked | 6 +- .../deps_only/B/sources/AA.move | 2 +- .../Move.locked | 18 +- .../Move.toml | 8 +- .../deps_only/C/Move.toml | 8 +- .../Move.toml | 8 +- .../Move.locked | 18 +- .../Move.resolved | 2 +- .../Move.toml | 8 +- .../Move.locked | 20 +- .../Move.resolved | 2 +- .../Move.toml | 8 +- .../Move.locked | 22 +- .../deps_only/C/Move.toml | 8 +- .../deps_only/C/Move.toml | 8 +- .../Move.locked | 28 +- .../diamond_problem_dep_override/Move.locked | 18 +- .../Move.locked | 26 +- .../Move.locked | 30 +- .../diamond_problem_no_conflict/Move.locked | 16 +- .../deps_only/B/sources/AA.move | 2 +- .../direct_and_indirect_dep/Move.locked | 16 +- .../tests/test_sources/external/Move.locked | 12 +- .../tests/test_sources/external/Move.resolved | 2 +- .../tests/test_sources/external/Move.toml | 8 +- .../test_sources/external_bad_dep/Move.locked | 12 +- .../test_sources/external_bad_dep/Move.toml | 4 +- .../test_sources/external_broken/Move.toml | 4 +- .../test_sources/external_dev_dep/Move.locked | 20 +- .../external_dev_dep/Move.resolved | 2 +- .../test_sources/external_dev_dep/Move.toml | 8 +- .../test_sources/external_failing/Move.toml | 4 +- .../external_no_resolver/Move.toml | 4 +- .../test_sources/external_overlap/Move.locked | 14 +- .../external_overlap/Move.resolved | 2 +- .../test_sources/external_overlap/Move.toml | 8 +- .../external_overlap_fail/Move.toml | 8 +- .../external_overlap_fail_symmetric/Move.toml | 8 +- .../Move.locked | 19 + .../Move.progress | 6 + .../Move.resolved | 180 + .../external_package_batch_response/Move.toml | 8 + .../deps_only/bar/Move.toml | 5 + .../deps_only/bar/sources/bar.move | 1 + .../deps_only/foo/Move.toml | 5 + .../deps_only/foo/sources/foo.move | 1 + .../sources/root.move | 1 + .../external_resolver_config/Move.locked | 6 + .../external_resolver_config/Move.resolved | 64 + .../external_resolver_config/Move.toml | 6 + .../sources/Root.move | 11 + .../Move.resolved | 3 + .../Move.toml | 5 + .../sources/Root.move | 11 + .../Move.resolved | 3 + .../Move.toml | 5 + .../sources/Root.move | 11 + .../test_sources/external_silent/Move.locked | 12 +- .../test_sources/external_silent/Move.toml | 4 +- .../multiple_deps_no_rename/Move.locked | 10 +- .../nested_deps_git_local/Move.locked | 10 +- .../nested_deps_local_local/Move.locked | 10 +- .../nested_deps_override/Move.locked | 10 +- .../nested_deps_shared_override/Move.locked | 20 +- .../tests/test_sources/one_dep/Move.locked | 6 +- .../one_dep_bad_digest/Move.locked | 6 +- .../test_sources/one_dep_override/Move.locked | 6 +- .../test_sources/package_hooks/Move.resolved | 2 +- .../test_sources/package_hooks/Move.toml | 2 +- .../package_hooks_subdir/Move.resolved | 1 - .../package_hooks_subdir/Move.toml | 5 - .../parsing_edition_2024/Move.resolved | 74 +- .../Move.resolved | 2 +- .../parsing_edition_unknown/Move.resolved | 2 +- .../Move.resolved | 2 +- .../Move.resolved | 2 +- .../test_sources/resolve_pkg_name/Move.locked | 16 +- .../deps_only/B-rename/sources/AA.move | 2 +- .../Move.resolved | 10 +- .../deps_only/A-rename/Move.lock | 6 +- .../deps_only/B/Move.lock | 6 +- .../deps_only/C-rename-v1/Move.lock | 2 +- .../deps_only/C-rename-v2/Move.lock | 2 +- .../Move.resolved | 2 +- .../deps_only/C/Move.toml | 8 +- .../test_sources/resolve_version/Move.locked | 10 +- .../resolve_version_diamond/Move.locked | 16 +- .../resolve_version_diamond_deep/Move.locked | 20 +- .../Move.locked | 20 +- .../Move.locked | 18 +- .../Move.resolved | 2 +- .../Move.toml | 2 +- .../Move.locked | 18 +- .../tests/test_sources/resolvers/silent.sh | 10 +- .../test_sources/resolvers/successful.sh | 10 +- .../test_sources/resolvers/successful_dep.sh | 14 +- .../successful_package_batch_response.sh | 50 + .../resolvers/successful_subst.sh | 10 +- .../successful_subst_name_resolution.sh | 10 +- .../resolvers/successful_version.sh | 10 +- .../Package1/sources/Dummy.move | 2 +- .../Package2/sources/Dummy.move | 2 +- .../move/crates/move-prover/src/lib.rs | 2 +- .../src/inconsistency_check.rs | 3 + .../tests/borrow/function_call.exp | 246 +- .../tests/borrow/function_call.move | 2 +- .../tests/borrow/hyper_edge.exp | 246 +- .../tests/borrow/hyper_edge.move | 6 +- .../escape_analysis/return_internal_refs.move | 2 +- .../escape_analysis/return_refs_into_vec.exp | 428 ++- .../escape_analysis/return_refs_into_vec.move | 2 +- .../escape_analysis/return_refs_safe.move | 2 +- .../tests/escape_analysis/struct_eq.move | 2 +- .../tests/testsuite.rs | 4 +- .../move/crates/move-stdlib/src/lib.rs | 6 +- .../move/crates/move-trace-format/Cargo.toml | 38 + .../crates/move-trace-format/src/format.rs | 389 +++ .../crates/move-trace-format/src/interface.rs | 40 + .../move/crates/move-trace-format/src/lib.rs | 7 + .../move-trace-format/src/memory_tracer.rs | 197 ++ .../src/framework.rs | 24 +- .../src/tasks.rs | 18 +- .../src/vm_test_harness.rs | 7 +- .../tests/vm_test_harness/example.move | 6 +- .../named_addresses_in_commands.exp | 4 +- .../named_addresses_in_commands.move | 8 +- .../tests/vm_test_harness/print_bytecode.exp | 14 +- .../tests/vm_test_harness/print_bytecode.move | 2 +- .../move/crates/move-unit-test/Cargo.toml | 3 +- .../move/crates/move-unit-test/src/lib.rs | 51 +- .../move-unit-test/src/test_reporter.rs | 32 +- .../crates/move-unit-test/src/test_runner.rs | 84 +- .../move-unit-test/tests/sources/A.move | 2 +- .../move-unit-test/tests/sources/B.move | 8 +- .../crates/move-unit-test/tests/test_deps.rs | 2 +- .../tests/test_sources/address_args.exp | 6 +- .../tests/test_sources/address_args.move | 2 +- .../tests/test_sources/arithmetic_errors.exp | 8 +- .../tests/test_sources/arithmetic_errors.move | 2 +- .../tests/test_sources/const_abort.exp | 4 +- .../tests/test_sources/const_abort.move | 2 +- .../tests/test_sources/construct_data.exp | 4 +- .../tests/test_sources/construct_data.move | 6 +- .../test_sources/cross_module_aborts.exp | 10 +- .../test_sources/cross_module_aborts.move | 6 +- .../tests/test_sources/do_nothing.exp | 2 +- .../tests/test_sources/do_nothing.move | 2 +- .../test_sources/expected_abort_no_abort.exp | 6 +- .../test_sources/expected_abort_no_abort.move | 4 +- .../tests/test_sources/native_abort.exp | 16 +- .../tests/test_sources/native_abort.move | 6 +- .../test_sources/non_exsistent_native.exp | 6 +- .../test_sources/non_exsistent_native.move | 2 +- .../tests/test_sources/proposal_test.exp | 6 +- .../tests/test_sources/proposal_test.move | 8 +- .../tests/test_sources/random_test.exp | 20 +- .../tests/test_sources/random_test.move | 2 +- .../tests/test_sources/signer_args.exp | 18 +- .../tests/test_sources/signer_args.move | 2 +- .../tests/test_sources/timeout.exp | 16 +- .../tests/test_sources/timeout.move | 2 +- .../tests/test_sources/unexpected_abort.exp | 26 +- .../tests/test_sources/unexpected_abort.move | 6 +- .../test_sources/use_unit_test_module.exp | 4 +- .../test_sources/use_unit_test_module.move | 2 +- .../move/crates/move-vm-config/Cargo.toml | 2 +- .../move/crates/move-vm-config/src/runtime.rs | 16 +- .../move-vm-integration-tests/Cargo.toml | 20 +- .../move-vm-integration-tests/src/compiler.rs | 9 +- .../move-vm-integration-tests/src/lib.rs | 4 +- .../src/tests/bad_entry_point_tests.rs | 6 +- .../src/tests/bad_storage_tests.rs | 22 +- .../src/tests/compatibility_tests.rs | 10 +- .../src/tests/depth_tests_modules.move | 34 +- .../src/tests/exec_func_effects_tests.rs | 6 +- .../src/tests/function_arg_tests.rs | 39 +- .../src/tests/instantiation_tests.rs | 6 +- .../src/tests/invariant_violation_tests.rs | 4 +- .../src/tests/leak_tests.rs | 4 +- .../src/tests/loader_tests.rs | 48 +- .../src/tests/loader_tests_modules.move | 80 +- .../src/tests/nested_loop_tests.rs | 10 +- .../src/tests/relinking_tests_a_v0.move | 4 +- .../src/tests/relinking_tests_b_v0.move | 4 +- .../src/tests/relinking_tests_b_v1.move | 4 +- .../src/tests/relinking_tests_c_v0.move | 2 +- .../src/tests/relinking_tests_c_v1.move | 2 +- .../src/tests/relinking_tests_c_v2.move | 2 +- .../src/tests/return_value_tests.rs | 16 +- .../move/crates/move-vm-profiler/Cargo.toml | 2 +- .../move/crates/move-vm-profiler/src/lib.rs | 64 +- .../move/crates/move-vm-runtime/Cargo.toml | 10 +- .../crates/move-vm-runtime/src/interpreter.rs | 164 +- .../move/crates/move-vm-runtime/src/lib.rs | 3 +- .../move/crates/move-vm-runtime/src/loader.rs | 52 +- .../move-vm-runtime/src/native_functions.rs | 9 +- .../crates/move-vm-runtime/src/runtime.rs | 13 +- .../crates/move-vm-runtime/src/session.rs | 44 +- .../crates/move-vm-runtime/src/tracing.rs | 24 +- .../move-vm-runtime/src/tracing2/mod.rs | 108 + .../move-vm-runtime/src/tracing2/tracer.rs | 1758 ++++++++++ .../move/crates/move-vm-test-utils/Cargo.toml | 2 +- .../src/tiered_gas_schedule.rs | 18 +- .../tests/builtins/signer_runtime_dummy.mvir | 6 +- .../tests/builtins/vec_borrow_and_modify.mvir | 8 +- .../tests/builtins/vec_pop.mvir | 8 +- .../tests/builtins/vec_push.mvir | 8 +- .../tests/builtins/vec_swap.mvir | 8 +- .../vector_ops_borrow_and_modify_ok.mvir | 8 +- .../tests/builtins/vector_ops_bound_ok.mvir | 12 +- .../tests/builtins/vector_ops_len_ok.mvir | 6 +- .../builtins/vector_ops_out_of_bound.exp | 6 +- .../builtins/vector_ops_out_of_bound.mvir | 6 +- .../builtins/vector_ops_pack_unpack_ok.mvir | 4 +- .../tests/builtins/vector_ops_pop_empty.exp | 4 +- .../tests/builtins/vector_ops_pop_empty.mvir | 4 +- .../tests/builtins/vector_ops_pop_ok.mvir | 5 +- .../tests/builtins/vector_ops_unpack_less.exp | 6 +- .../builtins/vector_ops_unpack_less.mvir | 6 +- .../tests/builtins/vector_ops_unpack_more.exp | 6 +- .../builtins/vector_ops_unpack_more.mvir | 6 +- .../tests/builtins/vector_ops_unpack_ok.mvir | 8 +- .../tests/commands/abort_in_module.exp | 2 +- .../tests/commands/abort_in_module.mvir | 4 +- .../control_flow/fields_packed_in_order.exp | 2 +- .../control_flow/fields_packed_in_order.mvir | 4 +- .../return_in_if_branch_taken.mvir | 4 +- .../return_in_if_branch_taken_no_else.mvir | 4 +- .../address_arg_is_not_signer.mvir | 4 +- .../expected_2_signer_args_got_1.move | 2 +- .../mixed_signer_inputs_scripts.mvir | 6 +- .../modify_mutable_ref_inputs.mvir | 2 +- .../tests/entry_points/ref_inputs.mvir | 8 +- .../script_too_few_type_args_inner.exp | 2 +- .../script_too_few_type_args_inner.mvir | 4 +- .../script_too_many_type_args_inner.exp | 2 +- .../script_too_many_type_args_inner.mvir | 4 +- .../script_type_arg_kind_mismatch_1.exp | 2 +- .../script_type_arg_kind_mismatch_1.mvir | 4 +- .../tests/entry_points/struct_arguments.mvir | 4 +- .../enums/basic_poly_enum_type_mismatch.exp | 9 +- .../enums/basic_poly_enum_type_mismatch.mvir | 4 +- .../enums/enum_variant_jump_same_label.exp | 19 +- .../enums/enum_variant_jump_same_label.mvir | 12 +- .../tests/enums/enum_variant_mismatch.exp | 7 +- .../tests/enums/enum_variant_mismatch.mvir | 8 +- .../enums/enum_variant_tag_unpack_invalid.exp | 48 +- .../enum_variant_tag_unpack_invalid.mvir | 28 +- .../enums/mono/enum_decl_monomorphic.exp | 7 +- .../enums/mono/enum_decl_monomorphic.mvir | 8 +- .../enum_decl_monomorphic_fail_unpack.exp | 6 +- .../enum_decl_monomorphic_fail_unpack.mvir | 6 +- ...m_decl_monomorphic_mismatched_variants.exp | 2 +- ..._decl_monomorphic_mismatched_variants.mvir | 6 +- .../tests/enums/mono/mut_ref_update.exp | 8 +- .../tests/enums/mono/mut_ref_update.mvir | 8 +- .../enums/mono/mut_ref_update_variant.exp | 9 +- .../enums/mono/mut_ref_update_variant.mvir | 8 +- .../tests/enums/poly/basic_poly_enum.exp | 5 +- .../tests/enums/poly/basic_poly_enum.mvir | 8 +- .../enum_decl_poly_mismatched_variants.exp | 2 +- .../enum_decl_poly_mismatched_variants.mvir | 6 +- .../tests/enums/poly/poly_mut_ref_update.exp | 8 +- .../tests/enums/poly/poly_mut_ref_update.mvir | 8 +- .../poly/poly_mut_ref_update_variant.exp | 9 +- .../poly/poly_mut_ref_update_variant.mvir | 8 +- .../tests/enums/unpack_mut_ref_alias.mvir | 6 +- .../tests/enums/variant_switch_loop.exp | 9 +- .../tests/enums/variant_switch_loop.mvir | 8 +- .../arithmetic_operators_u128.exp | 24 +- .../arithmetic_operators_u128.mvir | 34 +- .../instructions/arithmetic_operators_u16.exp | 22 +- .../arithmetic_operators_u16.mvir | 32 +- .../arithmetic_operators_u256.exp | 22 +- .../arithmetic_operators_u256.mvir | 32 +- .../instructions/arithmetic_operators_u32.exp | 22 +- .../arithmetic_operators_u32.mvir | 32 +- .../instructions/arithmetic_operators_u64.exp | 22 +- .../arithmetic_operators_u64.mvir | 32 +- .../instructions/arithmetic_operators_u8.exp | 22 +- .../instructions/arithmetic_operators_u8.mvir | 32 +- .../instructions/assign_struct_field.exp | 4 +- .../instructions/assign_struct_field.mvir | 2 +- .../tests/instructions/bitwise_operators.mvir | 4 +- .../tests/instructions/casting_operators.exp | 64 +- .../tests/instructions/casting_operators.mvir | 76 +- .../instructions/comparison_operators.mvir | 12 +- .../tests/instructions/deref_value.mvir | 4 +- .../instructions/deref_value_nested.mvir | 10 +- .../instructions/equality_reference_value.exp | 6 +- .../equality_reference_value.mvir | 6 +- .../tests/instructions/field_reads.mvir | 6 +- .../tests/instructions/field_writes.mvir | 6 +- .../inaccessible_borrowed_local.mvir | 4 +- .../tests/instructions/pack_unpack.mvir | 2 +- .../tests/instructions/shift_operators.exp | 20 +- .../tests/instructions/shift_operators.mvir | 32 +- .../tests/instructions/vec_copy_nested.mvir | 2 +- .../publish_module_and_use.mvir | 12 +- .../publish_module_and_use_2.mvir | 2 +- .../publish_module_and_use_3.mvir | 2 +- ...e_and_use_with_multiple_return_values.mvir | 2 +- .../publish_two_modules.mvir | 12 +- .../use_modules_published.mvir | 6 +- .../tests/native_functions/vector_module.mvir | 10 +- .../tests/recursion/direct_recursion.mvir | 2 +- .../tests/recursion/mutual_recursion.mvir | 2 +- .../recursion/runtime_type_deeply_nested.mvir | 4 +- .../tests/references/borrow_in_loop.exp | 4 +- .../tests/references/borrow_in_loop.mvir | 2 +- .../references/deref_move_module_ok.mvir | 4 +- .../tests/references/mixed_lvalue.mvir | 4 +- .../tests/references/mutate_move_ok.mvir | 4 +- .../add_function_calls.mvir | 6 +- .../assign_function_call.mvir | 6 +- .../binop_function_calls_as_args.mvir | 4 +- .../function_composition.mvir | 6 +- .../many_function_calls_as_args.mvir | 6 +- .../multiple_composite_functions.mvir | 6 +- .../pass_args_on_stack_as_expressions.mvir | 6 +- .../stack_and_function_calls/pop_weird.mvir | 6 +- .../push_args_before_function_call.mvir | 6 +- ...push_args_before_function_composition.mvir | 6 +- .../return_expression_lists.mvir | 6 +- .../return_function_in_if_binop_in_else.mvir | 6 +- .../move/crates/move-vm-types/Cargo.toml | 3 - .../move-vm-types/src/values/values_impl.rs | 270 +- .../move/documentation/book/src/packages.md | 9 +- .../move/documentation/coding_guidelines.md | 14 +- .../tooling/prettier-extension/.gitignore | 3 + .../tooling/prettier-extension/.vscodeignore | 10 + .../tooling/prettier-extension/CHANGELOG.md | 7 + .../prettier-extension/CONTRIBUTING.md | 18 + .../move/tooling/prettier-extension/LICENSE | 201 ++ .../move/tooling/prettier-extension/README.md | 58 + .../tooling/prettier-extension/img/move.png | Bin 0 -> 256463 bytes .../tooling/prettier-extension/jsconfig.json | 13 + .../prettier-extension/package-lock.json | 2937 +++++++++++++++++ .../tooling/prettier-extension/package.json | 86 + .../prettier-extension/src/extension.js | 132 + .../src/formatter-worker.js | 30 + .../move/tooling/prettier-move/.gitignore | 2 + .../move/tooling/prettier-move/.npmignore | 3 + .../move/tooling/prettier-move/CHANGELOG.md | 29 + .../tooling/prettier-move/CONTRIBUTING.md | 31 + .../move/tooling/prettier-move/README.md | 96 + .../prettier-move/bin/prettier-move.js | 29 + .../tooling/prettier-move/package-lock.json | 1770 ++++++++++ .../move/tooling/prettier-move/package.json | 34 + .../move/tooling/prettier-move/pnpm-lock.yaml | 1413 ++++++++ .../tooling/prettier-move/prettier.config.js | 13 + .../scripts/treesitter-wasm-gen.sh | 50 + .../prettier-move/src/cst/annotation.ts | 72 + .../tooling/prettier-move/src/cst/common.ts | 388 +++ .../tooling/prettier-move/src/cst/constant.ts | 109 + .../prettier-move/src/cst/enum_definition.ts | 76 + .../src/cst/expression/abort_expression.ts | 34 + .../cst/expression/annotation_expression.ts | 39 + .../src/cst/expression/assign_expression.ts | 33 + .../src/cst/expression/binary_expression.ts | 76 + .../prettier-move/src/cst/expression/block.ts | 70 + .../src/cst/expression/block_item.ts | 30 + .../src/cst/expression/borrow_expression.ts | 30 + .../src/cst/expression/break_expression.ts | 34 + .../src/cst/expression/call_expression.ts | 29 + .../src/cst/expression/cast_expression.ts | 36 + .../src/cst/expression/continue_expression.ts | 30 + .../cst/expression/dereference_expression.ts | 34 + .../src/cst/expression/dot_expression.ts | 87 + .../src/cst/expression/expression_list.ts | 33 + .../cst/expression/identified_expression.ts | 31 + .../src/cst/expression/if_expression.ts | 99 + .../prettier-move/src/cst/expression/index.ts | 86 + .../src/cst/expression/index_expression.ts | 38 + .../src/cst/expression/lambda_expression.ts | 95 + .../src/cst/expression/let_statement.ts | 63 + .../src/cst/expression/loop_expression.ts | 30 + .../cst/expression/macro_call_expression.ts | 77 + .../src/cst/expression/match_expression.ts | 114 + .../cst/expression/move_or_copy_expression.ts | 30 + .../src/cst/expression/name_expression.ts | 29 + .../src/cst/expression/pack_expression.ts | 30 + .../src/cst/expression/return_expression.ts | 51 + .../src/cst/expression/unary_expression.ts | 29 + .../src/cst/expression/unit_expression.ts | 19 + .../src/cst/expression/vector_expression.ts | 86 + .../src/cst/expression/while_expression.ts | 46 + .../prettier-move/src/cst/formatting.ts | 101 + .../src/cst/function_definition.ts | 291 ++ .../tooling/prettier-move/src/cst/literal.ts | 70 + .../tooling/prettier-move/src/cst/module.ts | 165 + .../prettier-move/src/cst/source_file.ts | 39 + .../src/cst/struct_definition.ts | 268 ++ .../prettier-move/src/cst/use_declaration.ts | 231 ++ .../prettier-move/src/imports-grouping.ts | 295 ++ .../move/tooling/prettier-move/src/index.ts | 120 + .../move/tooling/prettier-move/src/printer.ts | 94 + .../move/tooling/prettier-move/src/tree.ts | 439 +++ .../tooling/prettier-move/src/utilities.ts | 388 +++ .../tooling/prettier-move/tests/README.md | 35 + .../control-flow/abort_expression.exp.move | 22 + .../tests/control-flow/abort_expression.move | 22 + .../tests/control-flow/if_expression.exp.move | 100 + .../tests/control-flow/if_expression.move | 100 + .../control-flow/loop_expression.exp.move | 13 + .../tests/control-flow/loop_expression.move | 13 + .../control-flow/return_expression.exp.move | 53 + .../tests/control-flow/return_expression.move | 54 + .../control-flow/while_expression.exp.move | 24 + .../tests/control-flow/while_expression.move | 27 + .../errors/tree-sitter-match_test.exp.move | 224 ++ .../tests/errors/tree-sitter-match_test.move | 223 ++ .../tests/errors/tree-sitter.exp.move | 55 + .../tests/errors/tree-sitter.move | 34 + .../tests/expression/call_expression.exp.move | 25 + .../tests/expression/call_expression.move | 17 + .../tests/expression/dot_expression.exp.move | 159 + .../tests/expression/dot_expression.move | 135 + .../expression/index_expression.exp.move | 10 + .../tests/expression/index_expression.move | 10 + .../expression/macro_call_and_lambda.exp.move | 272 ++ .../expression/macro_call_and_lambda.move | 224 ++ .../expression/match_expression.exp.move | 132 + .../tests/expression/match_expression.move | 130 + .../expression/vector_expression.exp.move | 149 + .../tests/expression/vector_expression.move | 142 + .../functions/binary_expression.exp.move | 51 + .../tests/functions/binary_expression.move | 52 + .../tests/functions/bind_unpack.exp.move | 26 + .../tests/functions/bind_unpack.move | 23 + .../tests/functions/block_item.exp.move | 5 + .../tests/functions/block_item.move | 5 + .../tests/functions/expression.exp.move | 387 +++ .../tests/functions/expression.move | 236 ++ .../tests/functions/let_statement.exp.move | 148 + .../tests/functions/let_statement.move | 134 + .../tests/functions/simple.exp.move | 33 + .../prettier-move/tests/functions/simple.move | 28 + .../tests/functions/test.exp.move | 96 + .../prettier-move/tests/functions/test.move | 118 + .../tests/misc/enum.macro.exp.move | 172 + .../prettier-move/tests/misc/enum.macro.move | 171 + .../tests/misc/formatting.exp.move | 84 + .../prettier-move/tests/misc/formatting.move | 73 + .../prettier-move/tests/misc/misc.exp.move | 230 ++ .../prettier-move/tests/misc/misc.move | 213 ++ .../prettier-move/tests/misc/other.exp.move | 82 + .../prettier-move/tests/misc/other.move | 79 + .../tests/module-members/annotation.exp.move | 59 + .../tests/module-members/annotation.move | 59 + .../tests/module-members/constant.exp.move | 118 + .../tests/module-members/constant.move | 119 + .../tests/module-members/enum.exp.move | 71 + .../tests/module-members/enum.move | 70 + .../tests/module-members/friend.exp.move | 8 + .../tests/module-members/friend.move | 8 + .../tests/module-members/function.exp.move | 116 + .../tests/module-members/function.move | 113 + .../group_annotation_ignore.exp.move | 26 + .../group_annotation_ignore.move | 26 + .../module-members/group_imports.exp.move | 27 + .../tests/module-members/group_imports.move | 29 + .../group_imports_module.exp.move | 31 + .../module-members/group_imports_module.move | 28 + .../tests/module-members/members.exp.move | 22 + .../tests/module-members/members.move | 17 + .../tests/module-members/struct.exp.move | 127 + .../tests/module-members/struct.move | 116 + .../module-members/use_declaration.exp.move | 31 + .../tests/module-members/use_declaration.move | 27 + .../tooling/prettier-move/tests/run.test.ts | 123 + .../special-features/module_label.exp.move | 14 + .../tests/special-features/module_label.move | 11 + .../module_label_two_modules.exp.move | 21 + .../module_label_two_modules.move | 17 + .../special-features/prettier_ignore.exp.move | 17 + .../special-features/prettier_ignore.move | 17 + .../tests/special-features/tab_width.exp.move | 7 + .../tests/special-features/tab_width.move | 7 + .../special-features/wrap_comments.exp.move | 44 + .../tests/special-features/wrap_comments.move | 12 + .../prettier-move/tree-sitter-move.wasm | Bin 0 -> 344314 bytes .../move/tooling/prettier-move/tsconfig.json | 26 + 1717 files changed, 69861 insertions(+), 18585 deletions(-) create mode 100644 external-crates/move/crates/language-benchmarks/benches/criterion.rs delete mode 100644 external-crates/move/crates/language-benchmarks/benches/vm_benches.rs create mode 100644 external-crates/move/crates/language-benchmarks/tests/arith.move create mode 100644 external-crates/move/crates/language-benchmarks/tests/arith_2.move create mode 100644 external-crates/move/crates/language-benchmarks/tests/basic_alloc.move rename external-crates/move/crates/language-benchmarks/{src => tests}/bench.move (99%) create mode 100644 external-crates/move/crates/language-benchmarks/tests/call.move create mode 100644 external-crates/move/crates/language-benchmarks/tests/call_2.move create mode 100644 external-crates/move/crates/language-benchmarks/tests/natives.move create mode 100644 external-crates/move/crates/language-benchmarks/tests/transfers.move create mode 100644 external-crates/move/crates/language-benchmarks/tests/vector.move delete mode 100644 external-crates/move/crates/move-analyzer/src/completion.rs create mode 100644 external-crates/move/crates/move-analyzer/src/completions/dot.rs create mode 100644 external-crates/move/crates/move-analyzer/src/completions/mod.rs create mode 100644 external-crates/move/crates/move-analyzer/src/completions/name_chain.rs create mode 100644 external-crates/move/crates/move-analyzer/src/completions/snippets.rs create mode 100644 external-crates/move/crates/move-analyzer/src/completions/utils.rs create mode 100644 external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/sources/M1.move create mode 100644 external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/sources/M1.move create mode 100644 external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.exp create mode 100644 external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.ide create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/.eslintrc.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/.mocharc.yaml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/.vscodeignore create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/LICENSE create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/README.md create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/package-lock.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/package.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/src/adapter.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/src/runtime.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/src/server.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/src/source_map_utils.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/src/trace_utils.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/src/utils.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/.gitignore create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/traces/abort_assert__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/traces/abort_math__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/Iota/address.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/MoveStdlib/vector.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/Iota/address.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/MoveStdlib/vector.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/traces/abort_native__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/dependencies/MoveStdlib/vector.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/dependencies/MoveStdlib/vector.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/traces/abort_native_bytecode__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/build/breakpoints_line/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/build/breakpoints_line/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/build/breakpoints_line/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/traces/breakpoints_line__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/bytecode_modules/dependencies/MoveStdlib/vector.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/dependencies/MoveStdlib/vector.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/dependencies/MoveStdlib/vector.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/traces/compound__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/object.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/tx_context.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/MoveStdlib/bcs.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/object.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/tx_context.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/MoveStdlib/bcs.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/traces/global_loc__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/traces/macro_abort__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/traces/macro_breakpoint__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m_dep_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/traces/macro_different_different_files__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m_dep_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/traces/macro_different_different_files2__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/traces/macro_different_files__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/traces/macro_different_same_files__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/traces/macro_different_same_files2__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m_dep_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/source_maps/m_dep_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/sources/m_dep_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/hw_trace.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/traces/macro_inner_call__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/traces/macro_same_different_files__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/bytecode_modules/m_dep.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m_dep.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m_dep.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/traces/macro_same_different_files2__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/traces/macro_same_file__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/source_maps/dependencies/MoveStdlib/ascii.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/source_maps/dependencies/MoveStdlib/macros.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/source_maps/dependencies/MoveStdlib/string.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/source_maps/dependencies/MoveStdlib/u64.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/source_maps/dependencies/MoveStdlib/vector.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/ascii.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/macros.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/string.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/u64.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/vector.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/traces/native_fun__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/bytecode_modules/dependencies/MoveStdlib/vector.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/dependencies/MoveStdlib/vector.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/dependencies/MoveStdlib/vector.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references/traces/references__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/bytecode_modules/dependencies/MoveStdlib/vector.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/dependencies/MoveStdlib/vector.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/dependencies/MoveStdlib/vector.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/traces/references_deep__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/run_spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/build/shadowing/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/build/shadowing/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/build/shadowing/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/traces/shadowing__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/traces/stepping__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/Move.toml create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/bytecode_modules/m.mv create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/source_maps/m.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/sources/m.move create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/test.exp create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/trace.spec.js create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/traces/stepping_call__m__test.json create mode 100644 external-crates/move/crates/move-analyzer/trace-adapter/tsconfig.json create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/.eslintrc.json create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/.vscode/launch.json create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/.vscodeignore create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/LICENSE create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/README.md create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/images/move.png create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/package-lock.json create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/package.json create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/src/extension.ts create mode 100644 external-crates/move/crates/move-analyzer/trace-debug/tsconfig.json create mode 100644 external-crates/move/crates/move-binary-format/src/compatibility_mode.rs delete mode 100644 external-crates/move/crates/move-bytecode-utils/src/dependency_graph.rs create mode 100644 external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.exp create mode 100644 external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.txt create mode 100644 external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/package/.gitignore rename external-crates/move/crates/move-cli/tests/build_tests/{simple_new => new_simple}/args.exp (96%) rename external-crates/move/crates/move-cli/tests/build_tests/{simple_new => new_simple}/args.txt (60%) create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/Move.toml create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/sources/Bar.move create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/Move.toml create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/sources/Foo.move create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/Move.toml create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.exp create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.txt create mode 100644 external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/sources/A.move create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/Move.toml create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/NO_TEMPDIR create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.exp create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.txt create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_return_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_complex_nested_calls.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_return_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__aborter.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__bad_cast.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__div_0.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_during_abort.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_in_native.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_l.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_r.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__underflow.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_orig_type_name_test.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_type_name_test.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_pack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_unpack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_pack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_unpack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__nested_struct_reference_mutation.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__pass_mut_assign_in_other_fn.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_struct_borrow.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow_pop.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_return_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_complex_nested_calls.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_return_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__aborter.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__bad_cast.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__div_0.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_during_abort.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_in_native.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_l.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_r.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__underflow.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_orig_type_name_test.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_type_name_test.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_pack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_unpack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_pack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_unpack_order.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__nested_struct_reference_mutation.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__pass_mut_assign_in_other_fn.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_struct_borrow.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow_pop.json create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/calls.move create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/errors.move create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/natives.move create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/references.move create mode 100644 external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/structs.move create mode 100644 external-crates/move/crates/move-cli/tests/tracing_testsuite.rs create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/go_repro.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.move create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.exp create mode 100644 external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.move create mode 100644 external-crates/move/crates/move-compiler/src/diagnostics/warning_filters.rs create mode 100644 external-crates/move/crates/move-compiler/src/expansion/name_validation.rs create mode 100644 external-crates/move/crates/move-compiler/src/iota_mode/info.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/abort_constant.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/combinable_comparisons.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/equal_operands.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/loop_without_exit.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/meaningless_math_operation.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/redundant_ref_deref.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/self_assignment.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/unnecessary_conditional.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/unnecessary_unit.rs create mode 100644 external-crates/move/crates/move-compiler/src/linters/unneeded_return.rs delete mode 100644 external-crates/move/crates/move-compiler/src/typing/match_compilation.rs create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.exp create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.move delete mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.exp delete mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_negative_share_owned.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.exp create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/correct_redundant_ref_deref.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_combinable_comparisons.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operands.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_loop_without_exit.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_self_assigment.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_conditional.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/allowed_unneeded_return.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/false_negative_equal_operands.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional_valid.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields_valid.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/ref_deref_negative.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_abort_constant.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_combinable_comparisons.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operands.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_loop_without_exit.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_meaningless_math_operation.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_self_assignment.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_conditional.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_unit.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppressed_case_redundant_ref_deref.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_abort_constant.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_loop_without_exit.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_meaningless_math_operation.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_self_assignment.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_conditional.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_unit.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_conditional.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_0.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_1.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/cfgir/expand_test.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/cfgir/named_loop_no_value.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand_false_negative.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/determine_error.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_named_block_inner_break.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/no_dead_code_block.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/hlir/true_false_nested_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/generated_0.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/go_match.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/go_repro.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_initial.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/if_compilation.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_complex.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_mut_ref_type.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_ref_type.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_subject.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/lit_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/matching_everywhere.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias_2.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_label.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_with_or.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp_macro.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/struct_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_nested_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/parsing/clever_errors_raw_abort.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/parsing/expr_abort_missing_value.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/control_flow/while_after_while.move delete mode 100644 external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/parser/empty_doc_comment.move delete mode 100644 external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.exp delete mode 100644 external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.move create mode 100644 external-crates/move/crates/move-core-types/src/annotated_extractor.rs delete mode 100644 external-crates/move/crates/move-core-types/src/parser.rs rename external-crates/move/crates/{move-command-line-common/src => move-core-types/src/parsing}/address.rs (91%) create mode 100644 external-crates/move/crates/move-core-types/src/parsing/mod.rs rename external-crates/move/crates/{move-command-line-common/src => move-core-types/src/parsing}/parser.rs (59%) rename external-crates/move/crates/{move-command-line-common/src => move-core-types/src/parsing}/types.rs (94%) rename external-crates/move/crates/{move-command-line-common/src => move-core-types/src/parsing}/values.rs (98%) create mode 100644 external-crates/move/crates/move-core-types/src/unit_tests/extractor_test.rs create mode 100644 external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs create mode 100644 external-crates/move/crates/move-docgen/tests/sources/const_string_test.move create mode 100644 external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline.md create mode 100644 external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline_no_fold.md create mode 100644 external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_separate.md create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.locked create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.progress create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.resolved create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.toml create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/Move.toml create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/sources/bar.move create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/Move.toml create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/sources/foo.move create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/sources/root.move create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.locked create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.resolved create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.toml create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/sources/Root.move create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.resolved create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.toml create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/sources/Root.move create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.resolved create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.toml create mode 100644 external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/sources/Root.move delete mode 100644 external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.resolved delete mode 100644 external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.toml create mode 100755 external-crates/move/crates/move-package/tests/test_sources/resolvers/successful_package_batch_response.sh create mode 100644 external-crates/move/crates/move-trace-format/Cargo.toml create mode 100644 external-crates/move/crates/move-trace-format/src/format.rs create mode 100644 external-crates/move/crates/move-trace-format/src/interface.rs create mode 100644 external-crates/move/crates/move-trace-format/src/lib.rs create mode 100644 external-crates/move/crates/move-trace-format/src/memory_tracer.rs create mode 100644 external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs create mode 100644 external-crates/move/crates/move-vm-runtime/src/tracing2/tracer.rs create mode 100644 external-crates/move/tooling/prettier-extension/.gitignore create mode 100644 external-crates/move/tooling/prettier-extension/.vscodeignore create mode 100644 external-crates/move/tooling/prettier-extension/CHANGELOG.md create mode 100644 external-crates/move/tooling/prettier-extension/CONTRIBUTING.md create mode 100644 external-crates/move/tooling/prettier-extension/LICENSE create mode 100644 external-crates/move/tooling/prettier-extension/README.md create mode 100644 external-crates/move/tooling/prettier-extension/img/move.png create mode 100644 external-crates/move/tooling/prettier-extension/jsconfig.json create mode 100644 external-crates/move/tooling/prettier-extension/package-lock.json create mode 100644 external-crates/move/tooling/prettier-extension/package.json create mode 100644 external-crates/move/tooling/prettier-extension/src/extension.js create mode 100644 external-crates/move/tooling/prettier-extension/src/formatter-worker.js create mode 100644 external-crates/move/tooling/prettier-move/.gitignore create mode 100644 external-crates/move/tooling/prettier-move/.npmignore create mode 100644 external-crates/move/tooling/prettier-move/CHANGELOG.md create mode 100644 external-crates/move/tooling/prettier-move/CONTRIBUTING.md create mode 100644 external-crates/move/tooling/prettier-move/README.md create mode 100755 external-crates/move/tooling/prettier-move/bin/prettier-move.js create mode 100644 external-crates/move/tooling/prettier-move/package-lock.json create mode 100644 external-crates/move/tooling/prettier-move/package.json create mode 100644 external-crates/move/tooling/prettier-move/pnpm-lock.yaml create mode 100644 external-crates/move/tooling/prettier-move/prettier.config.js create mode 100755 external-crates/move/tooling/prettier-move/scripts/treesitter-wasm-gen.sh create mode 100644 external-crates/move/tooling/prettier-move/src/cst/annotation.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/common.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/constant.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/enum_definition.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/abort_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/annotation_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/assign_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/binary_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/block.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/block_item.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/borrow_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/break_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/call_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/cast_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/continue_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/dereference_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/dot_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/expression_list.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/identified_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/if_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/index.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/index_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/lambda_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/let_statement.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/loop_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/macro_call_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/match_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/move_or_copy_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/name_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/pack_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/return_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/unary_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/unit_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/vector_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/expression/while_expression.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/formatting.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/function_definition.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/literal.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/module.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/source_file.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/struct_definition.ts create mode 100644 external-crates/move/tooling/prettier-move/src/cst/use_declaration.ts create mode 100644 external-crates/move/tooling/prettier-move/src/imports-grouping.ts create mode 100644 external-crates/move/tooling/prettier-move/src/index.ts create mode 100644 external-crates/move/tooling/prettier-move/src/printer.ts create mode 100644 external-crates/move/tooling/prettier-move/src/tree.ts create mode 100644 external-crates/move/tooling/prettier-move/src/utilities.ts create mode 100644 external-crates/move/tooling/prettier-move/tests/README.md create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.move create mode 100644 external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/call_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/call_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/dot_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/dot_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/index_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/index_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/match_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/match_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/vector_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/expression/vector_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/binary_expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/binary_expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/block_item.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/block_item.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/expression.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/expression.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/let_statement.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/let_statement.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/simple.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/simple.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/test.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/functions/test.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/enum.macro.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/enum.macro.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/formatting.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/formatting.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/misc.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/misc.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/other.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/misc/other.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/annotation.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/annotation.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/constant.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/constant.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/enum.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/enum.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/friend.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/friend.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/function.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/function.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/group_imports.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/group_imports.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/members.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/members.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/struct.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/struct.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.move create mode 100644 external-crates/move/tooling/prettier-move/tests/run.test.ts create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/module_label.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/module_label.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/tab_width.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/tab_width.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.exp.move create mode 100644 external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.move create mode 100755 external-crates/move/tooling/prettier-move/tree-sitter-move.wasm create mode 100644 external-crates/move/tooling/prettier-move/tsconfig.json diff --git a/Cargo.lock b/Cargo.lock index 550aa462be0..9aeac640356 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9973,6 +9973,20 @@ dependencies = [ "serde", ] +[[package]] +name = "move-trace-format" +version = "0.0.1" +dependencies = [ + "anyhow", + "move-binary-format", + "move-core-types", + "move-proc-macros", + "ref-cast", + "serde", + "serde_json", + "variant_count", +] + [[package]] name = "move-transactional-test-runner" version = "0.1.0" diff --git a/external-crates/move/Cargo.lock b/external-crates/move/Cargo.lock index 812fbf776bc..9ca0d8899fb 100644 --- a/external-crates/move/Cargo.lock +++ b/external-crates/move/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -79,58 +79,58 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -146,13 +146,13 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -168,23 +168,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -193,6 +193,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bcs" version = "0.1.6" @@ -218,25 +224,25 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3deeecb812ca5300b7d3f66f730cc2ebd3511c3d36c691dd79c165d5b19a26e3" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "syn 1.0.109", ] [[package]] name = "bit-set" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" @@ -377,9 +383,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cassowary" @@ -395,9 +401,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.13" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" dependencies = [ "jobserver", "libc", @@ -412,14 +418,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-targets 0.52.6", ] @@ -458,23 +465,23 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", - "clap_derive 4.5.13", + "clap_derive 4.5.18", ] [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.2", + "clap_lex 0.7.4", "strsim 0.11.1", ] @@ -486,21 +493,21 @@ checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "syn 1.0.109", ] [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -514,9 +521,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "codespan" @@ -541,18 +548,18 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -579,9 +586,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -647,18 +654,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -675,18 +682,18 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -721,9 +728,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "csv" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -753,6 +760,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.92", + "quote 1.0.37", + "strsim 0.11.1", + "syn 2.0.90", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote 1.0.37", + "syn 2.0.90", +] + [[package]] name = "datatest-stable" version = "0.1.3" @@ -764,26 +806,36 @@ dependencies = [ "walkdir", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "derivative" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "syn 1.0.109", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -829,10 +881,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.5", + "redox_users 0.4.6", "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", +] + [[package]] name = "dissimilar" version = "1.0.9" @@ -897,12 +960,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -934,9 +997,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fixed-hash" @@ -1013,9 +1076,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "half" @@ -1031,9 +1094,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1079,9 +1142,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1100,14 +1163,149 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] @@ -1144,13 +1342,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 1.0.109", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -1161,18 +1359,26 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] name = "indexmap" -version = "2.4.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", + "serde", ] +[[package]] +name = "inline_colorization" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1804bdb6a9784758b200007273a8b84e2b0b0b97a8f1e18e763eceb3e9f98a" + [[package]] name = "instant" version = "0.1.13" @@ -1208,9 +1414,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -1223,10 +1429,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1276,27 +1483,20 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" dependencies = [ "arbitrary", "cc", - "once_cell", ] -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - [[package]] name = "libredox" version = "0.1.3" @@ -1330,6 +1530,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -1351,9 +1557,9 @@ dependencies = [ [[package]] name = "lsp-server" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248f65b78f6db5d8e1b1604b4098a28b43d21a8eb1deeca22b1c421b276c7095" +checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9" dependencies = [ "crossbeam-channel", "log", @@ -1401,11 +1607,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1422,11 +1628,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", @@ -1463,7 +1668,7 @@ name = "move-analyzer" version = "1.0.0" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.23", "codespan-reporting", "crossbeam", "datatest-stable", @@ -1476,6 +1681,7 @@ dependencies = [ "lsp-types", "move-command-line-common", "move-compiler", + "move-core-types", "move-ir-types", "move-package", "move-symbol-pool", @@ -1521,6 +1727,7 @@ dependencies = [ "move-ir-types", "move-symbol-pool", "serde", + "serde_json", ] [[package]] @@ -1528,6 +1735,7 @@ name = "move-bytecode-utils" version = "0.1.0" dependencies = [ "anyhow", + "indexmap 2.7.0", "move-binary-format", "move-core-types", "petgraph", @@ -1563,7 +1771,7 @@ name = "move-bytecode-viewer" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.23", "crossterm", "move-binary-format", "move-bytecode-source-map", @@ -1578,7 +1786,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs", - "clap 4.5.16", + "clap 4.5.23", "codespan-reporting", "colored", "datatest-stable", @@ -1633,7 +1841,7 @@ version = "0.0.1" dependencies = [ "anyhow", "bcs", - "clap 4.5.16", + "clap 4.5.23", "codespan-reporting", "datatest-stable", "dunce", @@ -1652,11 +1860,13 @@ dependencies = [ "move-symbol-pool", "once_cell", "petgraph", + "rayon", "regex", "serde", "serde_json", "similar", "stacker", + "tempfile", "vfs", ] @@ -1691,6 +1901,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", + "serde_with", "thiserror", "uint", ] @@ -1701,9 +1912,10 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs", - "clap 4.5.16", + "clap 4.5.23", "codespan", "colored", + "indexmap 2.7.0", "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", @@ -1720,9 +1932,9 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs", - "clap 4.5.16", - "colored", + "clap 4.5.23", "hex", + "inline_colorization", "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", @@ -1760,7 +1972,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs", - "clap 4.5.16", + "clap 4.5.23", "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", @@ -1850,7 +2062,7 @@ name = "move-package" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.23", "colored", "datatest-stable", "expect-test", @@ -1884,8 +2096,8 @@ dependencies = [ name = "move-proc-macros" version = "0.1.0" dependencies = [ - "quote 1.0.36", - "syn 2.0.75", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -1893,7 +2105,7 @@ name = "move-prover" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.23", "codespan-reporting", "itertools", "log", @@ -1984,13 +2196,31 @@ dependencies = [ "serde_json", ] +[[package]] +name = "move-trace-format" +version = "0.0.1" +dependencies = [ + "anyhow", + "arbitrary", + "getrandom 0.2.15", + "move-binary-format", + "move-core-types", + "move-proc-macros", + "proptest", + "proptest-derive", + "ref-cast", + "serde", + "serde_json", + "variant_count", +] + [[package]] name = "move-transactional-test-runner" version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "clap 4.5.16", + "clap 4.5.23", "datatest-stable", "move-binary-format", "move-bytecode-source-map", @@ -2022,7 +2252,7 @@ dependencies = [ "anyhow", "bcs", "better_any", - "clap 4.5.16", + "clap 4.5.23", "codespan-reporting", "colored", "datatest-stable", @@ -2035,6 +2265,7 @@ dependencies = [ "move-stdlib", "move-stdlib-natives", "move-symbol-pool", + "move-trace-format", "move-vm-profiler", "move-vm-runtime", "move-vm-test-utils", @@ -2097,6 +2328,7 @@ dependencies = [ "move-binary-format", "move-bytecode-verifier", "move-core-types", + "move-trace-format", "move-vm-config", "move-vm-profiler", "move-vm-types", @@ -2198,6 +2430,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -2236,7 +2474,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2251,18 +2488,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -2301,9 +2538,9 @@ checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -2333,8 +2570,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "syn 1.0.109", ] @@ -2381,7 +2618,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.8", "smallvec", "windows-targets 0.52.6", ] @@ -2430,9 +2667,9 @@ checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", "phf_shared", - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -2446,15 +2683,15 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -2465,19 +2702,25 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -2541,8 +2784,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "syn 1.0.109", "version_check", ] @@ -2553,8 +2796,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "version_check", ] @@ -2569,18 +2812,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", @@ -2590,7 +2833,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", @@ -2609,9 +2852,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.21" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" dependencies = [ "cc", ] @@ -2633,11 +2876,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.92", ] [[package]] @@ -2772,18 +3015,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.3" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -2801,9 +3035,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", @@ -2825,21 +3059,21 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -2853,13 +3087,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -2870,9 +3104,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rust-argon2" @@ -2880,7 +3114,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" dependencies = [ - "base64", + "base64 0.13.1", "blake2b_simd", "constant_time_eq", "crossbeam-utils", @@ -2900,15 +3134,15 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2946,9 +3180,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -2985,20 +3219,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -3012,9 +3246,39 @@ version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", +] + +[[package]] +name = "serde_with" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.7.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +dependencies = [ + "darling", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -3155,25 +3419,31 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -3245,22 +3515,33 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.75" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2 1.0.92", + "quote 1.0.37", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", +] + [[package]] name = "tap" version = "1.0.1" @@ -3269,9 +3550,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -3304,7 +3585,7 @@ dependencies = [ name = "test-generation" version = "0.1.0" dependencies = [ - "clap 4.5.16", + "clap 4.5.23", "crossbeam-channel", "getrandom 0.2.15", "hex", @@ -3343,22 +3624,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -3381,40 +3662,66 @@ dependencies = [ ] [[package]] -name = "tinytemplate" -version = "1.2.1" +name = "time" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", "serde", - "serde_json", + "time-core", + "time-macros", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ - "tinyvec_macros", + "num-conv", + "time-core", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] [[package]] name = "tokio" -version = "1.39.3" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio 1.0.3", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", @@ -3429,9 +3736,9 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] @@ -3467,16 +3774,16 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.7.0", "toml_datetime", "winnow", ] [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3485,20 +3792,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -3517,9 +3824,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -3576,38 +3883,23 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" @@ -3617,9 +3909,9 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -3627,6 +3919,18 @@ dependencies = [ "serde", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -3645,7 +3949,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" dependencies = [ - "quote 1.0.36", + "quote 1.0.37", "syn 1.0.109", ] @@ -3706,9 +4010,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -3717,53 +4021,52 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ - "quote 1.0.36", + "quote 1.0.37", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -3771,11 +4074,11 @@ dependencies = [ [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall 0.5.8", "wasite", "web-sys", ] @@ -3983,6 +4286,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.2.0" @@ -3998,6 +4313,30 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -4014,9 +4353,30 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", + "synstructure", ] [[package]] @@ -4034,7 +4394,29 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 2.0.75", + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2 1.0.92", + "quote 1.0.37", + "syn 2.0.90", ] diff --git a/external-crates/move/Cargo.toml b/external-crates/move/Cargo.toml index 553f221bceb..661284039f8 100644 --- a/external-crates/move/Cargo.toml +++ b/external-crates/move/Cargo.toml @@ -26,7 +26,7 @@ clap = { version = "4", features = ["derive"] } codespan = "0.11.1" codespan-reporting = "0.11.1" colored = "2.0.0" -criterion = "0.3.4" +criterion = { version = "0.3.4", features = ["html_reports"] } criterion-cpu-time = "0.1.0" crossbeam = "0.8" crossbeam-channel = "0.5.0" @@ -50,6 +50,8 @@ hex = "0.4.3" hex-literal = "0.3.4" hkdf = "0.10.0" im = "15.1.0" +indexmap = "2.1.0" +inline_colorization = "0.1.6" internment = { version = "0.5.0", features = ["arc"] } itertools = "0.10.0" json_comments = "0.2.2" @@ -62,7 +64,6 @@ memory-stats = "1.0.0" mirai-annotations = "1.10.1" named-lock = "0.2.0" num = "0.4.0" -num-bigint = "0.4.0" num_cpus = "1.13.0" once_cell = "1.7.2" ouroboros = "0.17.2" @@ -79,7 +80,7 @@ proptest = "1.0.0" proptest-derive = "0.3.0" quote = "1.0.9" rand = "0.8.0" -rayon = "1.5.0" +rayon = "1.10.0" ref-cast = "1.0.6" regex = "1.5.5" ripemd160 = "0.9.1" @@ -88,6 +89,7 @@ serde-name = "0.1.1" serde-reflection = "0.4" serde_bytes = "0.11.5" serde_json = "1.0.64" +serde_with = "3.9.0" serde_yaml = "0.8.26" sha2 = "0.9.3" sha3 = "0.9.1" @@ -151,6 +153,7 @@ move-stackless-bytecode = { path = "crates/move-stackless-bytecode" } move-stdlib = { path = "crates/move-stdlib" } move-stdlib-natives = { path = "crates/move-stdlib-natives" } move-symbol-pool = { path = "crates/move-symbol-pool" } +move-trace-format = { path = "crates/move-trace-format" } move-transactional-test-runner = { path = "crates/move-transactional-test-runner" } move-unit-test = { path = "crates/move-unit-test" } move-vm-config = { path = "crates/move-vm-config" } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp index 974c19a2d02..03714e44588 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp @@ -2,7 +2,7 @@ processed 1 task task 0, lines 1-264: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: TOO_MANY_LOCALS, sub_status: None, location: undefined, diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir index 654674e5bba..6121141f668 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { foo(p1: u8) { let x1 : u8; let x2 : u8; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir index 19a5030b3f1..dfd8fd954dd 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { foo() { let x1 : u8; let x2 : u8; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp index a4ad787848d..3e0ab849edb 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp @@ -2,7 +2,7 @@ processed 1 task task 0, lines 1-11: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, location: undefined, diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir index 1ffbb5deda9..bbf22a84bb4 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } foo() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move index 96a8df31082..95d581de785 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move @@ -10,7 +10,7 @@ public fun plus256(a: u256): u256 { a + 1 } //# publish -module 0x42::m_test { +module 0x43::m_test { use 0x42::m; public fun test8() { m::plus8(1u8); } public fun test16() { m::plus16(1u16); } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp index 8a8f0e085cc..396de5edaa3 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp @@ -2,30 +2,30 @@ processed 3 tasks task 0, lines 1-51: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } task 1, lines 53-70: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::M2'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M2, + location: 0x7::M2, indices: [], offsets: [], } task 2, lines 72-122: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::M3'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M3, + location: 0x8::M3, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir index 338a67ae293..003a8055e8e 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } a() { @@ -51,7 +51,7 @@ module 0x1.M { // loop: c#T1 --> c#T2 --> d#T --> b#T2 --S--> c#T1 //# publish -module 0x1.M2 { +module 0x7.M2 { struct S { b: bool } f() { @@ -71,7 +71,7 @@ module 0x1.M2 { //# publish -module 0x1.M3 { +module 0x8.M3 { struct S { b: bool } a() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.exp index 8a8f0e085cc..396de5edaa3 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.exp @@ -2,30 +2,30 @@ processed 3 tasks task 0, lines 1-51: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } task 1, lines 53-70: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::M2'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M2, + location: 0x7::M2, indices: [], offsets: [], } task 2, lines 72-122: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::M3'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M3, + location: 0x8::M3, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.mvir index 48c02eeb5a3..0c40ecf23d3 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { enum S { V{ b: bool } } a() { @@ -51,7 +51,7 @@ module 0x1.M { // loop: c#T1 --> c#T2 --> d#T --> b#T2 --S--> c#T1 //# publish -module 0x1.M2 { +module 0x7.M2 { enum S { V { b: bool } } f() { @@ -71,7 +71,7 @@ module 0x1.M2 { //# publish -module 0x1.M3 { +module 0x8.M3 { enum S { V{ b: bool } } a() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir index e629305a028..6da321cf28d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { f() { label b0: Self.g(); diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir index 36b0e3d5d47..43fb7213dff 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.mvir index 7047b775fde..0ae491e6b69 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { enum S { V{ b: bool } } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir index 35f8a8925e8..e7150bbfc9d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { f() { label b0: Self.g(); diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir index d351f5297cd..ed5944413dc 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp index adbec9b3fe0..2a408054d93 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir index 8633f2a894e..234ba01a2d0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.exp index adbec9b3fe0..2a408054d93 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.mvir index 94016c7ddef..2d2bde3bce5 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { enum S { V{ b: bool } } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir index fdd12bf4219..49f338117a0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { f() { label b0: Self.g(); diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp index 78369208ad9..ad01a23a64f 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-17: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir index 39bfec96ce8..89d20e57345 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.exp index 78369208ad9..ad01a23a64f 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-17: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.mvir index 37bbd0a6a9a..373a6652e1c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { enum S { V { b: bool } } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp index 6d41922052c..be62ad1f511 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-20: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir index 17d06014e4f..ae7cf51e4cc 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir @@ -3,7 +3,7 @@ // Not good: infinitely many types/instances. // f, g>, f>, g>>, ... -module 0x1.M { +module 0x6.M { struct S { b: bool } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.exp index 6d41922052c..be62ad1f511 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-20: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.mvir index 5630abc40ab..b5a60d8aed6 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.mvir @@ -3,7 +3,7 @@ // Not good: infinitely many types/instances. // f, g>, f>, g>>, ... -module 0x1.M { +module 0x6.M { enum S { V { b: bool } } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.exp index 78c493676f0..214ea269d78 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-11: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.mvir index 5c2ae8ba244..a1da9c97669 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { enum S { V { b: bool }, R { } } foo() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp index b3a74762fbf..ce40b165ce0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-13: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir index 8d0b0a07042..c6fe46d04d6 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir @@ -1,6 +1,6 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } struct R { b: bool } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.exp index b3a74762fbf..ce40b165ce0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-13: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.mvir index 3de19698788..13719dc6d0c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.mvir @@ -1,6 +1,6 @@ //# publish -module 0x1.M { +module 0x6.M { struct S { b: bool } enum R { V{ b: bool } } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp index c332bce7d73..1a6d508c2e1 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-45: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir index a2847b03923..a37775e335d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir @@ -1,6 +1,6 @@ //# publish -module 0x1.M { +module 0x6.M { struct Box { x: T } unbox(b: Self.Box): T { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir index 2e4b63f4416..ba67668677d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir @@ -2,7 +2,7 @@ // This is good as there is only one instance foo for any T. -module 0x1.M { +module 0x6.M { f(x: T) { label b0: Self.f(move(x)); diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir index 52d442efd9f..bd5d7d200d7 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir @@ -2,7 +2,7 @@ // Good: two instances foo & foo (if T != u64) for any T. -module 0x1.M { +module 0x6.M { f() { label b0: Self.f(); diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp index b3a74762fbf..ce40b165ce0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-13: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir index 0bf3a7ecea4..fac9b6bec0d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir @@ -2,7 +2,7 @@ // Bad! Can have infinitely many instances: f, f>, f>>, ... -module 0x1.M { +module 0x6.M { struct S { b: bool } f(x: T) { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.exp index b3a74762fbf..ce40b165ce0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-13: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.mvir index 1c8c5e8a77e..79bb4ba7998 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.mvir @@ -2,7 +2,7 @@ // Bad! Can have infinitely many instances: f, f>, f>>, ... -module 0x1.M { +module 0x6.M { enum S { V{ b: bool } } f(x: T) { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.exp index dd4ffa564ac..711fe8831e5 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-14: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.mvir index 562d14461a0..397c7f59228 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.mvir @@ -3,7 +3,7 @@ // Similar to the case with one argument, but swaps the two type parameters. // f => f, T1> => f, S> => f>, S> => ... -module 0x1.M { +module 0x6.M { enum S { V{ x: T } } f(a: T1, b: T2) { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp index 6d41922052c..be62ad1f511 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-20: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir index 1c553a73fb0..6b9f433d13c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir @@ -3,7 +3,7 @@ // Two loops in the resulting graph. // One error for the loop. -module 0x1.M { +module 0x6.M { struct S { b: bool } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.exp index 6d41922052c..be62ad1f511 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-20: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.mvir index dd3e44bdb88..5dda00b6fbc 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.mvir @@ -3,7 +3,7 @@ // Two loops in the resulting graph. // One error for the loop. -module 0x1.M { +module 0x6.M { enum S { V { b: bool } } f() { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir index 55b29920c75..47124425714 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { public foo(): u64 { label b0: @@ -10,7 +10,7 @@ module 0x1.M { //# run module 0x42.m { -import 0x1.M; +import 0x6.M; entry foo() { label b0: diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp index c225167ca88..8813cc78507 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp @@ -12,50 +12,50 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 1, lines 11-20: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x43::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 2, lines 21-30: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x44::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 3, lines 31-40: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000045::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x45::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 4, lines 41-50: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000046::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x46::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 5, lines 51-60: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000047::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x47::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir index a6c68adf7c9..f2d596581a0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir @@ -9,7 +9,7 @@ label b0: } //# run -module 0x42.m { +module 0x43.m { entry foo() { label b0: @@ -19,7 +19,7 @@ label b0: } //# run -module 0x42.m { +module 0x44.m { entry foo() { label b0: @@ -29,7 +29,7 @@ label b0: } //# run -module 0x42.m { +module 0x45.m { entry foo() { label b0: @@ -39,7 +39,7 @@ label b0: } //# run -module 0x42.m { +module 0x46.m { entry foo() { label b0: @@ -49,7 +49,7 @@ label b0: } //# run -module 0x42.m { +module 0x47.m { entry foo() { label b0: diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp index 99048989707..045003b01f8 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp @@ -12,50 +12,50 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 1, lines 12-22: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x43::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 2, lines 23-33: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x44::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 3, lines 34-44: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000045::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x45::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 4, lines 45-55: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000046::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x46::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 5, lines 56-66: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000047::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x47::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir index b1d50383d51..9e1a2ab4d5e 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir @@ -10,7 +10,7 @@ label b0: } //# run -module 0x42.m { +module 0x43.m { entry foo() { label b0: @@ -21,7 +21,7 @@ label b0: } //# run -module 0x42.m { +module 0x44.m { entry foo() { label b0: @@ -32,7 +32,7 @@ label b0: } //# run -module 0x42.m { +module 0x45.m { entry foo() { label b0: @@ -43,7 +43,7 @@ label b0: } //# run -module 0x42.m { +module 0x46.m { entry foo() { label b0: @@ -54,7 +54,7 @@ label b0: } //# run -module 0x42.m { +module 0x47.m { entry foo() { label b0: diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir index 6da510c3bb2..2c104aa6cf8 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct R has key { data: vector } is_ok_(addr: &address, data: &vector): bool { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir index 2c3ee0f4617..f3cb1e037cd 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { public baz(k: u64, l: u64, m: u64) : u64 { let z: u64; label b0: @@ -10,7 +10,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { label b0: diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir index af8863f0c62..0d155a47e10 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { public push_u64(): u64 { label b0: return 42; @@ -23,7 +23,7 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; +import 0x6.A; entry foo() { let ans: u64; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir index 1e41dfc79bb..cbd64175c84 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { public parity(u: u64): u64 * bool { label b0: return copy(u), (move(u) % 2 == 0); @@ -22,7 +22,7 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; +import 0x6.A; entry foo() { let k: u64; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir index 8ee20a4f7cc..dd121aceb9c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { public foo(v: u64): u64 * u64 { let one_less: u64; let one_more: u64; @@ -17,7 +17,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { let y: u64; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir index d093bfe94f0..e305f1b4818 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { public parity(u: u64): u64 * bool { label b0: return copy(u), (move(u) % 2 == 0); @@ -17,7 +17,7 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; +import 0x6.A; entry foo() { let k: u64; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir index 0f3bcf7462d..5ae7f117976 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { two(): u8 * u8{ label b0: return 0u8, 255u8; @@ -15,7 +15,7 @@ module 0x1.A { //# publish -module 0x1.B { +module 0x7.B { two(): u16 * u16{ label b0: return 0u16, 65535u16; @@ -30,7 +30,7 @@ module 0x1.B { } //# publish -module 0x1.C { +module 0x8.C { two(): u32 * u32{ label b0: return 0u32, 4294967295u32; @@ -45,7 +45,7 @@ module 0x1.C { } //# publish -module 0x1.D { +module 0x9.D { two(): u64 * u64{ label b0: return 0u64, 18446744073709551615u64; @@ -60,7 +60,7 @@ module 0x1.D { } //# publish -module 0x1.E { +module 0xa.E { two(): u128 * u128{ label b0: return 0u128, 340282366920938463463374607431768211455u128; @@ -75,7 +75,7 @@ module 0x1.E { } //# publish -module 0x1.F { +module 0xb.F { two(): u256 * u256{ label b0: return 0u256, 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp index 699a4ac9c61..c624c4cdf29 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp @@ -2,60 +2,60 @@ processed 6 tasks task 0, lines 1-14: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0x6::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 1, lines 17-30: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0x7::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 2, lines 32-45: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0x8::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 3, lines 47-60: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000009::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0x9::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 4, lines 62-75: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000000a::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0xa::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 5, lines 77-90: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000000b::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0xb::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir index 3c79aa53843..afb71b732ee 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { three(): u8 * u8{ label b0: return 0u8, 255u8; @@ -15,7 +15,7 @@ module 0x1.A { //# publish -module 0x1.A { +module 0x7.A { three(): u16 * u16{ label b0: return 0u16, 65535u16; @@ -30,7 +30,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0x8.A { three(): u32 * u32{ label b0: return 0u32, 4294967295u32; @@ -45,7 +45,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0x9.A { three(): u64 * u64{ label b0: return 0u64, 18446744073709551615u64; @@ -60,7 +60,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0xa.A { three(): u128 * u128{ label b0: return 0u128, 340282366920938463463374607431768211455u128; @@ -75,7 +75,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0xb.A { three(): u256 * u256{ label b0: return 0u256, 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp index 0159c527ec6..5b0d3bd5e12 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp @@ -2,60 +2,60 @@ processed 6 tasks task 0, lines 1-14: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0x6::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 1, lines 17-30: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0x7::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 2, lines 32-45: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0x8::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 3, lines 47-60: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000009::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0x9::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 4, lines 62-75: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000000a::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0xa::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 5, lines 77-90: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000000b::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0xb::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir index d852de8a760..684c4b08da7 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { two(): u8 * u8{ label b0: return 0u8, 255u8; @@ -15,7 +15,7 @@ module 0x1.A { //# publish -module 0x1.A { +module 0x7.A { two(): u16 * u16{ label b0: return 0u16, 65535u16; @@ -30,7 +30,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0x8.A { two(): u32 * u32{ label b0: return 0u32, 4294967295u32; @@ -45,7 +45,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0x9.A { two(): u64 * u64{ label b0: return 0u64, 18446744073709551615u64; @@ -60,7 +60,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0xa.A { two(): u128 * u128{ label b0: return 0u128, 340282366920938463463374607431768211455u128; @@ -75,7 +75,7 @@ module 0x1.A { } //# publish -module 0x1.A { +module 0xb.A { two(): u256 * u256{ label b0: return 0u256, 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp index e889ba7cca1..e3584b774d5 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp @@ -12,50 +12,50 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 1, lines 11-20: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x43::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 2, lines 21-30: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x44::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 3, lines 31-40: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000045::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x45::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 4, lines 41-50: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000046::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x46::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 5, lines 51-60: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000047::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x47::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir index 51a47e9e901..1836524fc13 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir @@ -9,7 +9,7 @@ label b0: } //# run -module 0x42.m { +module 0x43.m { entry foo() { label b0: @@ -19,7 +19,7 @@ label b0: } //# run -module 0x42.m { +module 0x44.m { entry foo() { label b0: @@ -29,7 +29,7 @@ label b0: } //# run -module 0x42.m { +module 0x45.m { entry foo() { label b0: @@ -39,7 +39,7 @@ label b0: } //# run -module 0x42.m { +module 0x46.m { entry foo() { label b0: @@ -49,7 +49,7 @@ label b0: } //# run -module 0x42.m { +module 0x47.m { entry foo() { label b0: diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir index 4f712c14377..6f6c734ae21 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct T { b: bool } public new(): Self.T { @@ -22,7 +22,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { let i: u64; let t: Test.T; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir index 7848d2d9782..a3a59dec7f2 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct T { b: bool } public new(): Self.T { @@ -22,7 +22,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { let i: u64; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp index c01500ef556..c6b98bc7c79 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-22: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::Test, + location: 0x6::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir index c87a256ddd6..0c2da08ec77 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct T { b: bool } public new(): Self.T { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir index 13b4b9222ac..5bb415363fd 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct T { b: bool } public new(): Self.T { @@ -22,7 +22,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { let i: u64; let t: Test.T; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp index 375de9b58ec..42d23089c9f 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-22: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::Test, + location: 0x6::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir index 9a361944c42..4984ab43d2e 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct T { b: bool } public new(): Self.T { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.exp index d4f83da77d8..94e1abe52f0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.exp @@ -2,40 +2,40 @@ processed 4 tasks task 0, lines 1-11: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonoTooMany'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::MonoTooMany'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::MonoTooMany, + location: 0x6::MonoTooMany, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 1, lines 13-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonoTooFew'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::MonoTooFew'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::MonoTooFew, + location: 0x7::MonoTooFew, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 2, lines 25-35: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::PolyTooMany'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::PolyTooMany'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::PolyTooMany, + location: 0x8::PolyTooMany, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 3, lines 37-47: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::PolyTooFew'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000009::PolyTooFew'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::PolyTooFew, + location: 0x9::PolyTooFew, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.mvir index 3e2d8e28706..a97f8e35406 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.MonoTooMany { +module 0x6.MonoTooMany { enum Foo{ V { x: u64 } } bar(x: u64, y: u64): Self.Foo { @@ -11,7 +11,7 @@ module 0x1.MonoTooMany { } //# publish -module 0x1.MonoTooFew { +module 0x7.MonoTooFew { enum Foo{ V { x: u64 } } bar(x: u64, y: u64): Self.Foo { @@ -23,7 +23,7 @@ module 0x1.MonoTooFew { } //# publish -module 0x1.PolyTooMany { +module 0x8.PolyTooMany { enum Foo{ V { x: T } } bar(x: u64, y: u64): Self.Foo { @@ -35,7 +35,7 @@ module 0x1.PolyTooMany { } //# publish -module 0x1.PolyTooFew { +module 0x9.PolyTooFew { enum Foo{ V { x: T } } bar(x: u64, y: u64): Self.Foo { diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir index ba04f90880e..3c2bd7d6c42 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { three(): u64 * u64 * u64 { label b0: return 0, 1, 2; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp index 141eed8a420..93e436150ca 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-14: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::A, + location: 0x6::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir index 8dcf844a296..e87f737091d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { three(): u64 * u64 * u64 { label b0: return 0, 1, 2; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp index 6b6a4314f88..dd30db4ec5d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-14: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::A, + location: 0x6::A, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir index 916930ed556..2c742476a87 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { three(): u64 * u64 * u64 { label b0: return 0, 1, 2; diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp index fe4dbe30c9a..1915f300731 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::Test, + location: 0x6::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir index 99e17859360..7643e2b02d2 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct X { b: bool } struct T { i: u64, x: Self.X } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.exp index f9c16469dbf..624f6f2a0ae 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.exp @@ -2,40 +2,40 @@ processed 4 tasks task 0, lines 1-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::Test, + location: 0x6::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 1, lines 25-46: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::Test'. Got VMError: { major_status: GENERIC_MEMBER_OPCODE_MISMATCH, sub_status: None, - location: 0x1::Test, + location: 0x7::Test, indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } task 2, lines 48-69: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::Test, + location: 0x8::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 3, lines 71-92: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000009::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x1::Test, + location: 0x9::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.mvir index 32ac8099c26..809046ebc72 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct X { b: bool } enum T { V{ i: u64, x: Self.X } } @@ -23,7 +23,7 @@ module 0x1.Test { } //# publish -module 0x1.Test { +module 0x7.Test { struct X { b: bool } enum T { V{ i: H, x: Self.X } } @@ -46,7 +46,7 @@ module 0x1.Test { } //# publish -module 0x1.Test { +module 0x8.Test { struct X { b: bool } enum T { V{ i: H, x: Self.X } } @@ -69,7 +69,7 @@ module 0x1.Test { } //# publish -module 0x1.Test { +module 0x9.Test { struct X { b: bool } enum T { V{ i: H, x: Self.X } } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp index 76928c5efe6..c4d018ddb72 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp @@ -2,10 +2,10 @@ processed 1 task task 0, lines 1-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::Test, + location: 0x6::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir index 424c00fddca..c850fb96f1f 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct X { b: bool } struct T { i: u64, x: Self.X, b: bool, y: u64 } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.exp index c5fe244682f..775ca364e2d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.exp @@ -2,40 +2,40 @@ processed 4 tasks task 0, lines 1-22: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::Test, + location: 0x6::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 1, lines 24-45: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000007::Test'. Got VMError: { major_status: GENERIC_MEMBER_OPCODE_MISMATCH, sub_status: None, - location: 0x1::Test, + location: 0x7::Test, indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } task 2, lines 47-68: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000008::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::Test, + location: 0x8::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } task 3, lines 70-91: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000009::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x1::Test, + location: 0x9::Test, indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.mvir index fd83f799ce1..fea181991d0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { struct X { b: bool } enum T { V { i: u64, x: Self.X, b: bool, y: u64 } } @@ -22,7 +22,7 @@ module 0x1.Test { } //# publish -module 0x1.Test { +module 0x7.Test { struct X { b: bool } enum T { V{ i: H, x: Self.X, b: bool, y: u64 } } @@ -45,7 +45,7 @@ module 0x1.Test { } //# publish -module 0x1.Test { +module 0x8.Test { struct X { b: bool } enum T { V{ i: H, x: Self.X, b: bool, y: u64 } } @@ -68,7 +68,7 @@ module 0x1.Test { } //# publish -module 0x1.Test { +module 0x9.Test { struct X { b: bool } enum T { V{ i: H, x: Self.X, b: bool, y: u64 } } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp index db91a6561a0..9a21c209f65 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp @@ -12,30 +12,30 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 1, lines 12-22: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x43::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 2, lines 23-35: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::m'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, - location: 0x42::m, + location: 0x44::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } task 3, lines 36-48: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000045::m'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, - location: 0x42::m, + location: 0x45::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir index 99085f29914..fe8c5c2782d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir @@ -10,7 +10,7 @@ label b0: } //# run -module 0x42.m { +module 0x43.m { entry foo() { let v: vector; @@ -21,7 +21,7 @@ label b0: } //# run -module 0x42.m { +module 0x44.m { entry foo() { let v: vector; @@ -34,7 +34,7 @@ label b0: } //# run -module 0x42.m { +module 0x45.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/language-benchmarks/Cargo.toml b/external-crates/move/crates/language-benchmarks/Cargo.toml index 582979bdcd2..23eb260b91f 100644 --- a/external-crates/move/crates/language-benchmarks/Cargo.toml +++ b/external-crates/move/crates/language-benchmarks/Cargo.toml @@ -21,6 +21,9 @@ move-vm-runtime.workspace = true move-vm-test-utils.workspace = true move-vm-types.workspace = true +[lib] +bench = false + [[bench]] -name = "vm_benches" +name = "criterion" harness = false diff --git a/external-crates/move/crates/language-benchmarks/benches/criterion.rs b/external-crates/move/crates/language-benchmarks/benches/criterion.rs new file mode 100644 index 00000000000..9433d227962 --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/benches/criterion.rs @@ -0,0 +1,59 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use criterion::{criterion_group, criterion_main, measurement::Measurement, Criterion}; +use language_benchmarks::{measurement::cpu_time_measurement, move_vm::bench}; + +// +// MoveVM benchmarks +// + +fn arith(c: &mut Criterion) { + bench(c, "arith.move"); +} + +fn arith_2(c: &mut Criterion) { + bench(c, "arith_2.move"); +} + +fn basic_alloc(c: &mut Criterion) { + bench(c, "basic_alloc.move"); +} + +fn call(c: &mut Criterion) { + bench(c, "call.move"); +} + +fn call_2(c: &mut Criterion) { + bench(c, "call_2.move"); +} + +fn natives(c: &mut Criterion) { + bench(c, "natives.move"); +} + +fn transfers(c: &mut Criterion) { + bench(c, "transfers.move"); +} + +fn vector(c: &mut Criterion) { + bench(c, "vector.move"); +} + +criterion_group!( + name = vm_benches; + config = cpu_time_measurement(); + targets = + arith, + arith_2, + basic_alloc, + call, + call_2, + natives, + transfers, + vector, +); + +criterion_main!(vm_benches); diff --git a/external-crates/move/crates/language-benchmarks/benches/vm_benches.rs b/external-crates/move/crates/language-benchmarks/benches/vm_benches.rs deleted file mode 100644 index e3e836db085..00000000000 --- a/external-crates/move/crates/language-benchmarks/benches/vm_benches.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use criterion::{criterion_group, criterion_main, measurement::Measurement, Criterion}; -use language_benchmarks::{measurement::cpu_time_measurement, move_vm::bench}; - -// MoveVM benchmarks -// - -fn arith(c: &mut Criterion) { - bench(c, "arith"); -} - -fn call(c: &mut Criterion) { - bench(c, "call"); -} - -fn natives(c: &mut Criterion) { - bench(c, "natives"); -} - -criterion_group!( - name = vm_benches; - config = cpu_time_measurement(); - targets = arith, - call, - natives -); - -criterion_main!(vm_benches); diff --git a/external-crates/move/crates/language-benchmarks/src/measurement.rs b/external-crates/move/crates/language-benchmarks/src/measurement.rs index 1a3de082518..5fbf1eabdfa 100644 --- a/external-crates/move/crates/language-benchmarks/src/measurement.rs +++ b/external-crates/move/crates/language-benchmarks/src/measurement.rs @@ -5,9 +5,16 @@ use criterion::Criterion; use criterion_cpu_time::PosixTime; +use std::time::Duration; pub fn cpu_time_measurement() -> Criterion { - Criterion::default().with_measurement(PosixTime::UserAndSystemTime) + Criterion::default() + .with_measurement(PosixTime::UserAndSystemTime) + .without_plots() + .noise_threshold(0.20) + .confidence_level(0.9) + .warm_up_time(Duration::from_secs(10)) // Warm-up time before measurements start + .measurement_time(Duration::from_secs(30)) // Measurement time of 30 seconds } pub fn wall_time_measurement() -> Criterion { diff --git a/external-crates/move/crates/language-benchmarks/src/move_vm.rs b/external-crates/move/crates/language-benchmarks/src/move_vm.rs index 0d751c15137..d50c6331db1 100644 --- a/external-crates/move/crates/language-benchmarks/src/move_vm.rs +++ b/external-crates/move/crates/language-benchmarks/src/move_vm.rs @@ -3,50 +3,71 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::path::PathBuf; +use std::{path::PathBuf, sync::Arc}; -use criterion::{measurement::Measurement, Criterion}; +use criterion::{Criterion, measurement::Measurement}; use move_binary_format::CompiledModule; -use move_compiler::Compiler; +use move_compiler::{Compiler, FullyCompiledProgram, editions::Edition, shared::PackagePaths}; use move_core_types::{ account_address::AccountAddress, - identifier::{IdentStr, Identifier}, - language_storage::{ModuleId, CORE_CODE_ADDRESS}, + identifier::Identifier, + language_storage::{CORE_CODE_ADDRESS, ModuleId}, }; use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::BlankStorage; use move_vm_types::gas::UnmeteredGasMeter; use once_cell::sync::Lazy; -static MOVE_BENCH_SRC_PATH: Lazy = Lazy::new(|| { - vec![env!("CARGO_MANIFEST_DIR"), "src", "bench.move"] - .into_iter() - .collect() +static PRECOMPILED_MOVE_STDLIB: Lazy = Lazy::new(|| { + let program_res = move_compiler::construct_pre_compiled_lib( + vec![PackagePaths { + name: None, + paths: move_stdlib::move_stdlib_files(), + named_address_map: move_stdlib::move_stdlib_named_addresses(), + }], + None, + move_compiler::Flags::empty(), + None, + ) + .unwrap(); + match program_res { + Ok(stdlib) => stdlib, + Err((files, errors)) => { + eprintln!("!!!Standard library failed to compile!!!"); + move_compiler::diagnostics::report_diagnostics(&files, errors) + } + } }); /// Entry point for the bench, provide a function name to invoke in Module Bench /// in bench.move. -pub fn bench(c: &mut Criterion, fun: &str) { - let modules = compile_modules(); - let move_vm = MoveVM::new(move_stdlib_natives::all_natives( - AccountAddress::from_hex_literal("0x1").unwrap(), - move_stdlib_natives::GasParameters::zeros(), - /* silent debug */ true, - )) - .unwrap(); - execute(c, &move_vm, modules, fun); +pub fn bench(c: &mut Criterion, filename: &str) { + let modules = compile_modules(filename); + let move_vm = create_vm(); + execute(c, &move_vm, modules, filename); +} + +fn make_path(file: &str) -> PathBuf { + vec![env!("CARGO_MANIFEST_DIR"), "tests", file] + .into_iter() + .collect() } // Compile `bench.move` and its dependencies -fn compile_modules() -> Vec { - let mut src_files = move_stdlib::move_stdlib_files(); - src_files.push(MOVE_BENCH_SRC_PATH.to_str().unwrap().to_owned()); +pub fn compile_modules(filename: &str) -> Vec { + let src_files = vec![make_path(filename).to_str().unwrap().to_owned()]; + let pkg_config = move_compiler::shared::PackageConfig { + edition: Edition::E2024_BETA, + ..Default::default() + }; let (_files, compiled_units) = Compiler::from_files( None, src_files, vec![], move_stdlib::move_stdlib_named_addresses(), ) + .set_pre_compiled_lib(Arc::new(PRECOMPILED_MOVE_STDLIB.clone())) + .set_default_config(pkg_config) .build_and_report() .expect("Error compiling..."); compiled_units @@ -55,12 +76,22 @@ fn compile_modules() -> Vec { .collect() } +fn create_vm() -> MoveVM { + MoveVM::new(move_stdlib_natives::all_natives( + AccountAddress::from_hex_literal("0x1").unwrap(), + move_stdlib_natives::GasParameters::zeros(), + // silent debug + true, + )) + .unwrap() +} + // execute a given function in the Bench module fn execute( c: &mut Criterion, move_vm: &MoveVM, modules: Vec, - fun: &str, + file: &str, ) { // establish running context let storage = BlankStorage::new(); @@ -80,21 +111,23 @@ fn execute( } // module and function to call - let module_id = ModuleId::new(sender, Identifier::new("Bench").unwrap()); - let fun_name = IdentStr::new(fun).unwrap_or_else(|_| panic!("Invalid identifier name {}", fun)); + let module_id = ModuleId::new(sender, Identifier::new("bench").unwrap()); + let fun_name = Identifier::new("bench").unwrap(); // benchmark - c.bench_function(fun, |b| { - b.iter(|| { + c.bench_function(file, |b| { + b.iter_with_large_drop(|| { session .execute_function_bypass_visibility( &module_id, - fun_name, + &fun_name, vec![], Vec::>::new(), &mut UnmeteredGasMeter, ) - .unwrap_or_else(|err| panic!("{:?}::{} failed with {:?}", &module_id, fun, err)) + .unwrap_or_else(|err| { + panic!("{:?}::bench in {file} failed with {:?}", &module_id, err) + }) }) }); } diff --git a/external-crates/move/crates/language-benchmarks/tests/arith.move b/external-crates/move/crates/language-benchmarks/tests/arith.move new file mode 100644 index 00000000000..23e06cedfc3 --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/arith.move @@ -0,0 +1,22 @@ +module 0x1::bench { + fun check(check: bool, code: u64) { + if (check) () else abort code + } + + public fun bench() { + let mut i = 0; + // 10000 is the number of loops to make the benchmark run for a couple of minutes, + // which is an eternity. + // Adjust according to your needs, it's just a reference + while (i < 10000) { + 1; + 10 + 3; + 10; + 7 + 5; + let x = 1; + let y = x + 3; + check(x + y == 5, 10); + i = i + 1; + }; + } +} diff --git a/external-crates/move/crates/language-benchmarks/tests/arith_2.move b/external-crates/move/crates/language-benchmarks/tests/arith_2.move new file mode 100644 index 00000000000..bba7bbce51d --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/arith_2.move @@ -0,0 +1,12 @@ +module 0x1::bench { + const COUNT: u64 = 10_000u64; + + public fun bench() { + let mut sum = 0; + let mut i = 0; + while (i < COUNT) { + sum = sum + i; + i = i + 1; + } + } +} diff --git a/external-crates/move/crates/language-benchmarks/tests/basic_alloc.move b/external-crates/move/crates/language-benchmarks/tests/basic_alloc.move new file mode 100644 index 00000000000..8fad1143855 --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/basic_alloc.move @@ -0,0 +1,22 @@ +module 0x1::bench { + const COUNT: u64 = 10_000u64; + + public struct LargeStruct has drop { + a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: u64 + } + + fun bench_inner(): LargeStruct { + let mut i = 0; + let mut alloc = LargeStruct { a: 0, b: 0, c: 0, d: 0, e: 0, f: 0, g: 0, h: 0 }; + while (i < COUNT) { + alloc = LargeStruct { a: i, b: i, c: i, d: i, e: i, f: i, g: i, h: i }; + i = i + 1; + }; + alloc + } + + public fun bench() { + let LargeStruct { a: _, b: _, c: _, d: _, e: _, f: _, g: _, h: i } = bench_inner(); + let _i = i; + } +} diff --git a/external-crates/move/crates/language-benchmarks/src/bench.move b/external-crates/move/crates/language-benchmarks/tests/bench.move similarity index 99% rename from external-crates/move/crates/language-benchmarks/src/bench.move rename to external-crates/move/crates/language-benchmarks/tests/bench.move index fc9b4d205d4..6b69121cfb4 100644 --- a/external-crates/move/crates/language-benchmarks/src/bench.move +++ b/external-crates/move/crates/language-benchmarks/tests/bench.move @@ -2,7 +2,7 @@ // The Module must be called `Bench` and the set of public functions are callable from the bench (Rust code). // `benches/transaction.rs` contains the calling code. // The idea is that you build your scenario with a public entry point and a bunch of private functions as needed. -module 0x1::Bench { +module 0x6::Bench { use std::vector; // diff --git a/external-crates/move/crates/language-benchmarks/tests/call.move b/external-crates/move/crates/language-benchmarks/tests/call.move new file mode 100644 index 00000000000..dd2f54f302a --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/call.move @@ -0,0 +1,47 @@ +module 0x1::bench { + // + // Global helpers + // + fun check(check: bool, code: u64) { + if (check) () else abort code + } + + public fun bench() { + let mut i = 0; + // 3000 is the number of loops to make the benchmark run for a couple of minutes, + // which is an eternity. + // Adjust according to your needs, it's just a reference + while (i < 3000) { + let b = call_1(@0x0, 128); + call_2(b); + i = i + 1; + }; + } + + fun call_1(addr: address, val: u64): bool { + let b = call_1_1(&addr); + call_1_2(val, val); + b + } + + fun call_1_1(_addr: &address): bool { + true + } + + fun call_1_2(val1: u64, val2: u64): bool { + val1 == val2 + } + + fun call_2(b: bool) { + call_2_1(b); + check(call_2_2() == 400, 200); + } + + fun call_2_1(b: bool) { + check(b == b, 100) + } + + fun call_2_2(): u64 { + 100 + 300 + } +} diff --git a/external-crates/move/crates/language-benchmarks/tests/call_2.move b/external-crates/move/crates/language-benchmarks/tests/call_2.move new file mode 100644 index 00000000000..9503929d986 --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/call_2.move @@ -0,0 +1,16 @@ +module 0x1::bench { + + const COUNT: u64 = 10_000u64; + + public fun bench(): u64 { + let mut i = 0; + while (i < COUNT) { + i = i + call_empty_function(); + }; + i + } + + public fun call_empty_function(): u64 { + 1 + } +} diff --git a/external-crates/move/crates/language-benchmarks/tests/natives.move b/external-crates/move/crates/language-benchmarks/tests/natives.move new file mode 100644 index 00000000000..1c5ab67e40f --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/natives.move @@ -0,0 +1,48 @@ +module 0x1::bench { + + // + // Global helpers + // + fun check(check: bool, code: u64) { + if (check) () else abort code + } + + // + // `natives` benchmark + // + fun test_vector_ops(mut x1: T, mut x2: T): (T, T) { + let mut v: vector = vector::empty(); + check(v.length() == 0, 100); + v.push_back(x1); + check(v.length() == 1, 101); + v.push_back(x2); + check(v.length() == 2, 102); + v.swap(0, 1); + x1 = v.pop_back(); + check(v.length() == 1, 103); + x2 = v.pop_back(); + check(v.length() == 0, 104); + v.destroy_empty(); + (x1, x2) + } + + fun test_vector() { + test_vector_ops(1u8, 2u8); + test_vector_ops(1u64, 2u64); + test_vector_ops(1u128, 2u128); + test_vector_ops(true, false); + test_vector_ops
(@0x1, @0x2); + test_vector_ops>(vector::empty(), vector::empty()); + } + + public fun bench() { + let mut i = 0; + // 300 is the number of loops to make the benchmark run for a couple of minutes, + // which is an eternity. + // Adjust according to your needs, it's just a reference + while (i < 300) { + test_vector(); + i = i + 1; + } + } +} diff --git a/external-crates/move/crates/language-benchmarks/tests/transfers.move b/external-crates/move/crates/language-benchmarks/tests/transfers.move new file mode 100644 index 00000000000..cc214c07be6 --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/transfers.move @@ -0,0 +1,46 @@ +module 0x1::bench { + + const COUNT: u64 = 10_000u64; + + public struct Account { balance: u64 } + + fun destroy_account(account: Account) { + let Account { balance: _ } = account; + } + + public fun bench() { + let mut accounts = vector::empty(); + let num_accounts = COUNT; + let transfer_amount = 10; + + // Initialize accounts with a balance of 1000 each + let mut i = 0; + while (i < num_accounts) { + accounts.push_back(Account { balance: 1000 }); + i = i + 1; + }; + + // Perform transfers + let mut j = 0; + while (j < num_accounts / 2) { + let sender_index = j; + let receiver_index = num_accounts - j - 1; + + let sender = accounts.borrow_mut(sender_index); + if (sender.balance >= transfer_amount) { + sender.balance = sender.balance - transfer_amount; + let receiver = accounts.borrow_mut(receiver_index); + receiver.balance = receiver.balance + transfer_amount; + }; + + j = j + 1; + }; + + let mut i = 0; + while (i < num_accounts) { + destroy_account(accounts.pop_back()); + i = i + 1; + }; + accounts.destroy_empty(); + } +} diff --git a/external-crates/move/crates/language-benchmarks/tests/vector.move b/external-crates/move/crates/language-benchmarks/tests/vector.move new file mode 100644 index 00000000000..24c249a1168 --- /dev/null +++ b/external-crates/move/crates/language-benchmarks/tests/vector.move @@ -0,0 +1,17 @@ +module 0x1::bench { + const COUNT: u64 = 100_000u64; + + public fun bench() { + let mut v = vector::empty(); + let mut i = 0; + while (i < COUNT) { + v.push_back(i); + i = i + 1; + }; + i = 0; + while (i < COUNT) { + v.pop_back(); + i = i + 1; + }; + } +} diff --git a/external-crates/move/crates/module-generation/src/generator.rs b/external-crates/move/crates/module-generation/src/generator.rs index ea02c96c0b0..5c14353f242 100644 --- a/external-crates/move/crates/module-generation/src/generator.rs +++ b/external-crates/move/crates/module-generation/src/generator.rs @@ -119,13 +119,12 @@ impl<'a> ModuleGenerator<'a> { if !structs.is_empty() { end += 1; }; - - match self.index(end) { - 0 => Type::Address, - 1 => Type::U8, - 2 => Type::U64, - 3 => Type::U128, - 4 => Type::Bool, + let type_ = match self.index(end) { + 0 => Type_::Address, + 1 => Type_::U8, + 2 => Type_::U64, + 3 => Type_::U128, + 4 => Type_::Bool, 5 if !structs.is_empty() => { let index = self.index(structs.len()); let struct_def = structs[index].value.clone(); @@ -139,17 +138,18 @@ impl<'a> ModuleGenerator<'a> { let module_name = ModuleName::module_self(); QualifiedDatatypeIdent::new(module_name, struct_name) }; - Type::Datatype(struct_ident, ty_instants) + Type_::Datatype(struct_ident, ty_instants) } - 6 => Type::U16, - 7 => Type::U32, - 8 => Type::U256, + 6 => Type_::U16, + 7 => Type_::U32, + 8 => Type_::U256, _ => { let index = self.index(ty_param_context.len()); let ty_var = ty_param_context[index].value.clone(); - Type::TypeParameter(ty_var) + Type_::TypeParameter(ty_var) } - } + }; + Spanned::unsafe_no_loc(type_) } fn typ(&mut self, ty_param_context: &[(TypeVar, BTreeSet)]) -> Type { @@ -164,7 +164,7 @@ impl<'a> ModuleGenerator<'a> { // if typ.is_nominal_resource { .... } if self.options.references_allowed && self.gen.gen_bool(0.25) { let is_mutable = self.gen.gen_bool(0.25); - Type::Reference(is_mutable, Box::new(typ)) + Spanned::unsafe_no_loc(Type_::Reference(is_mutable, Box::new(typ))) } else { typ } @@ -216,7 +216,7 @@ impl<'a> ModuleGenerator<'a> { .iter() .map(|(ty_var_, _)| { let param_name = Spanned::unsafe_no_loc(Var_(self.identifier().into())); - let ty = Type::TypeParameter(ty_var_.value.clone()); + let ty = Spanned::unsafe_no_loc(Type_::TypeParameter(ty_var_.value.clone())); (param_name, ty) }) .collect(); @@ -251,6 +251,7 @@ impl<'a> ModuleGenerator<'a> { ) }); let fun = Function_ { + loc: Spanned::unsafe_no_loc(()).loc, visibility: FunctionVisibility::Public, is_entry: false, signature, diff --git a/external-crates/move/crates/move-analyzer/Cargo.toml b/external-crates/move/crates/move-analyzer/Cargo.toml index 2ff11f4caaf..29a35bba18f 100644 --- a/external-crates/move/crates/move-analyzer/Cargo.toml +++ b/external-crates/move/crates/move-analyzer/Cargo.toml @@ -20,6 +20,7 @@ lsp-server.workspace = true lsp-types.workspace = true move-command-line-common.workspace = true move-compiler.workspace = true +move-core-types.workspace = true move-ir-types.workspace = true move-package.workspace = true move-symbol-pool.workspace = true diff --git a/external-crates/move/crates/move-analyzer/editors/code/README.md b/external-crates/move/crates/move-analyzer/editors/code/README.md index d880304ae7c..57150aae42e 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/README.md +++ b/external-crates/move/crates/move-analyzer/editors/code/README.md @@ -1,7 +1,9 @@ # Move Provides language support for the Move programming language. For information about Move visit the -language [documentation](https://docs.iota.org/developer/iota-101/move-overview/). +language [documentation](https://docs.iota.org/developer/iota-101/move-overview/). It also provides early-stage +support for trace-debugging Move unit tests using a familiar VSCode debugging interface (e.g., stepping +through the code, tracking local variable names, setting line breakpoints). # How to Install @@ -21,13 +23,18 @@ definition, type on hover). Please see [Troubleshooting](#troubleshooting) for s the pre-built move-analyzer binary is not available for your platform or if you want to use move-analyzer binary stored in a different location. -If you want to build and test Move code using the extension, you must install the `iota` binary on +If you want to build, test, and trace Move code using the extension, you must install the `iota` binary on your machine - see [here](https://docs.iota.org/developer/getting-started/install-iota) for instructions. The extension assumes that the `iota` binary is in your system path, but you can set its custom location location using VSCode's settings (`⌘` + `,` on macOS, or use the menu item _Code > Preferences > Settings_). Search for the `move.iota.path` user setting, set it to the new location of the `iota` binary, and restart VSCode. +In order to trace-debug Move code execution, the `iota` binary must be built with the `tracing` feature flag. +If your version of the `iota` binary was not built with this feature flag, an attempt to trace test +execution will fail. In this case you may have to build the `iota` binary from source following these +[instructions](https://docs.iota.org/developer/getting-started/install-iota#install-iota-binaries-from-source). + # Troubleshooting ## What if the pre-built move-analyzer binary is not available for my platform? @@ -95,6 +102,18 @@ Move source file (a file with a `.move` file extension) and: - inlay hints: - types: local declarations, lambda parameters, variant and struct pattern matching - parameter names at function calls -- If the opened Move source file is located within a buildable project you can build and (locally) +- If the opened Move source file is located within a buildable project, and you have the `iota` + binary installed, you can build and (locally) test this project using `Move: Build a Move package` and `Move: Test a Move package` commands from - VSCode's command palette + VSCode's command palette. +- If the opened Move source file is located within a buildable project, and you have the `iota` + binary installed, you can trace-debug execution of Move unit tests within this project. + This functionality is provided by this (Move) extension automatically including the Move Trace Debugging + [extension](https://marketplace.visualstudio.com/items?itemName=iota.move-trace-debug). Go to + the Move Trace Debugging extension link to find more detailed information about trace-debugging and + the current level of support. Trace-debugging a Move unit test is a two-step process: + - first, you need to generate traces for Move unit tests by using `Move: Trace Move test execution` + command from VSCode's command palette (traces will be available in the `traces` directory in JSON format) + - second, you need to execute `Run->Start Debugging` menu command with Move file containing the test + you want to trace-debug opened (if the file contains multiple tests, you will be able to select a specific one + from a drop-down menu) diff --git a/external-crates/move/crates/move-analyzer/editors/code/language-configuration.json b/external-crates/move/crates/move-analyzer/editors/code/language-configuration.json index 5b20cd79bc1..60ae28d100f 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/language-configuration.json +++ b/external-crates/move/crates/move-analyzer/editors/code/language-configuration.json @@ -12,7 +12,7 @@ { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, { "open": "/*", "close": "*/", "notIn": ["string"] } ], - "brackets": + "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] @@ -27,5 +27,5 @@ ["(", ")"], ["<", ">"], ["\"", "\""] - ], + ] } diff --git a/external-crates/move/crates/move-analyzer/editors/code/package-lock.json b/external-crates/move/crates/move-analyzer/editors/code/package-lock.json index cf0fbf4d40f..8b5bce77a96 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/package-lock.json +++ b/external-crates/move/crates/move-analyzer/editors/code/package-lock.json @@ -1310,12 +1310,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2212,10 +2213,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2776,6 +2778,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -3162,12 +3165,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -4573,6 +4577,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, diff --git a/external-crates/move/crates/move-analyzer/editors/code/package.json b/external-crates/move/crates/move-analyzer/editors/code/package.json index c5199da4812..976eb5edfcd 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/package.json +++ b/external-crates/move/crates/move-analyzer/editors/code/package.json @@ -45,7 +45,12 @@ }, { "command": "iota-move.test", - "title": "Test a Move package", + "title": "Run Move package test", + "category": "Move" + }, + { + "command": "iota-move.trace", + "title": "Trace Move test execution", "category": "Move" } ], @@ -132,8 +137,11 @@ }, { "command": "iota-move.test" + }, + { + "command": "iota-move.trace" } - ] + ] } }, "scripts": { @@ -150,8 +158,9 @@ "publish": "npm run pretest && npm run test && vsce publish" }, "extensionDependencies": [ - "damirka.move-syntax" - ], + "damirka.move-syntax", + "iota.move-trace-debug" +], "dependencies": { "semver": "^7.6.2", "vscode-languageclient": "^9.0.1" diff --git a/external-crates/move/crates/move-analyzer/editors/code/scripts/create.sh b/external-crates/move/crates/move-analyzer/editors/code/scripts/create.sh index f94940ab8fa..4252f6bd59d 100755 --- a/external-crates/move/crates/move-analyzer/editors/code/scripts/create.sh +++ b/external-crates/move/crates/move-analyzer/editors/code/scripts/create.sh @@ -9,7 +9,8 @@ set -e usage() { - >&2 echo "Usage: $0 -pkg|-pub [-h]" + SCRIPT_NAME=$(basename "$1") + >&2 echo "Usage: $SCRIPT_NAME -pkg|-pub [-h]" >&2 echo "" >&2 echo "Options:" >&2 echo " -pub Publish extensions for all targets" @@ -22,14 +23,14 @@ clean_tmp_dir() { } if [[ "$@" == "" ]]; then - usage + usage $0 exit 1 fi for cmd in "$@" do if [[ "$cmd" == "-h" ]]; then - usage + usage $0 exit 0 elif [[ "$cmd" == "-pkg" ]]; then OP="package" @@ -38,7 +39,7 @@ do OP="publish" OPTS="" else - usage + usage $0 exit 1 fi done @@ -57,11 +58,6 @@ SUPPORTED_OS[linux-x86_64]=linux-x64 TMP_DIR=$( mktemp -d -t vscode-createXXX ) trap "clean_tmp_dir $TMP_DIR" EXIT -LANG_SERVER_DIR="language-server" - -rm -rf $LANG_SERVER_DIR -mkdir $LANG_SERVER_DIR - for DIST_OS VSCODE_OS in "${(@kv)SUPPORTED_OS}"; do # IOTA distribution identifier IOTA_VERSION="v"$VERSION @@ -90,9 +86,11 @@ for DIST_OS VSCODE_OS in "${(@kv)SUPPORTED_OS}"; do cp $SRC_SERVER_BIN_LOC $DST_SERVER_BIN_LOC vsce "$OP" ${OPTS//VSCODE_OS/$VSCODE_OS} --target "$VSCODE_OS" + + rm -rf $LANG_SERVER_DIR + done -rm -rf $LANG_SERVER_DIR # build a "generic" version of the extension that does not bundle the move-analyzer binary vsce "$OP" ${OPTS//VSCODE_OS/generic} diff --git a/external-crates/move/crates/move-analyzer/editors/code/src/configuration.ts b/external-crates/move/crates/move-analyzer/editors/code/src/configuration.ts index 919d8086ad7..dbab2acbfdd 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/src/configuration.ts +++ b/external-crates/move/crates/move-analyzer/editors/code/src/configuration.ts @@ -60,7 +60,7 @@ export class Configuration { /** The path to the Iota binary. */ get iotaPath(): string { const iotaBin = process.platform === 'win32' ? 'iota.exe' : 'iota'; - const iotaPath = this.configuration.get(IOTA_PATH_OPT) ?? iotaBin; + const iotaPath = this.configuration.get(IOTA_PATH_OPT) ?? iotaBin; if (iotaPath === iotaBin) { return iotaPath; diff --git a/external-crates/move/crates/move-analyzer/editors/code/src/main.ts b/external-crates/move/crates/move-analyzer/editors/code/src/main.ts index 5b2f073ca0b..51010b40b79 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/src/main.ts +++ b/external-crates/move/crates/move-analyzer/editors/code/src/main.ts @@ -80,11 +80,13 @@ async function iotaMoveCmd(context: Readonly, cmd: string): Promise): Promise { } /** - * An extension command that that builds the current Move project. + * An extension command that that tests the current Move project. */ async function testProject(context: Readonly): Promise { - return iotaMoveCmd(context, 'test'); + const filter = await vscode.window.showInputBox({ + title: 'Testing Move package', + prompt: 'Enter filter string to only run tests whose names contain the string' + + '(leave empty to run all tests)', + ignoreFocusOut: true, // Keeps the input box open when it loses focus + }); + if (filter !== undefined) { + const cmd = filter.length > 0 ? `test ${filter}` : 'test'; + return iotaMoveCmd(context, cmd); + } + return Promise.resolve(); +} + +/** + * An extension command that that traces the current Move project. + */ +async function traceProject(context: Readonly): Promise { + const filter = await vscode.window.showInputBox({ + title: 'Tracing Move package', + prompt: 'Enter filter string to only trace tests whose names contain the string' + + '(leave empty to trace all tests)', + ignoreFocusOut: true, // Keeps the input box open when it loses focus + }); + if (filter !== undefined) { + const cmd = filter.length > 0 ? `test ${filter} --trace-execution` : 'test --trace-execution'; + return iotaMoveCmd(context, cmd); + } + return Promise.resolve(); } /** @@ -133,6 +162,7 @@ export async function activate(extensionContext: Readonly { } // Install vscode and depends extension + // + // TODO: currently, running `npm test` fails with an ENOENT error when spawning Electron; + // make sure that the path is correct and that `npm test` runs correctly to completion + const vscodeExecutablePath = await downloadAndUnzipVSCode(vscodeVersion); const [cli, ...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath); const newCli = cli ?? 'code'; diff --git a/external-crates/move/crates/move-analyzer/src/analysis/parsing_analysis.rs b/external-crates/move/crates/move-analyzer/src/analysis/parsing_analysis.rs index d5dcd543dca..79d6a0314e6 100644 --- a/external-crates/move/crates/move-analyzer/src/analysis/parsing_analysis.rs +++ b/external-crates/move/crates/move-analyzer/src/analysis/parsing_analysis.rs @@ -4,8 +4,10 @@ use crate::{ symbols::{ - add_member_use_def, ignored_function, CallInfo, CursorContext, CursorDefinition, - CursorPosition, DefMap, ModuleDefs, References, UseDef, UseDefMap, + add_member_use_def, ignored_function, parsed_address, + parsing_leading_and_mod_names_to_map_key, parsing_mod_def_to_map_key, CallInfo, + CursorContext, CursorDefinition, CursorPosition, DefMap, ModuleDefs, References, UseDef, + UseDefMap, }, utils::loc_start_to_lsp_position_opt, }; @@ -15,7 +17,6 @@ use lsp_types::Position; use std::collections::BTreeMap; use move_compiler::{ - expansion::ast as E, parser::ast as P, shared::{files::MappedFiles, Identifier, Name, NamedAddressMap, NamedAddressMaps}, }; @@ -424,7 +425,11 @@ impl<'a> ParsingAnalysisContext<'a> { self.exp_symbols(e1); self.exp_symbols(e2); } - E::Abort(e) => self.exp_symbols(e), + E::Abort(oe) => { + if let Some(e) = oe.as_ref() { + self.exp_symbols(e) + } + } E::Return(_, oe) => { if let Some(e) = oe.as_ref() { self.exp_symbols(e) @@ -442,8 +447,8 @@ impl<'a> ParsingAnalysisContext<'a> { self.exp_symbols(e2); } E::Borrow(_, e) => self.exp_symbols(e), - E::Dot(e, _) => self.exp_symbols(e), - E::DotCall(e, name, _, vo, v) => { + E::Dot(e, _, _) => self.exp_symbols(e), + E::DotCall(e, _, name, _, vo, v) => { self.exp_symbols(e); if let Some(v) = vo { v.iter().for_each(|t| self.type_symbols(t)); @@ -481,9 +486,13 @@ impl<'a> ParsingAnalysisContext<'a> { } } - fn match_pattern_symbols(&mut self, sp!(_, pattern): &P::MatchPattern) { + fn match_pattern_symbols(&mut self, pattern: &P::MatchPattern) { use P::MatchPattern_ as MP; - match pattern { + // If the cursor is in this match pattern, mark that down. + // This may be overridden by the recursion below. + update_cursor!(self.cursor, pattern, MatchPattern); + + match &pattern.value { MP::PositionalConstructor(chain, sp!(_, v)) => { self.chain_symbols(chain); v.iter().for_each(|e| { @@ -803,47 +812,3 @@ fn parsing_mod_ident_to_map_key( ) .to_string() } - -/// Produces module ident string of the form pkg::module to be used as a map key. -/// It's important that these are consistent between parsing AST and typed AST. -fn parsing_mod_def_to_map_key( - pkg_addresses: &NamedAddressMap, - mod_def: &P::ModuleDefinition, -) -> Option { - // we assume that modules are declared using the PkgName::ModName pattern (which seems to be the - // standard practice) and while Move allows other ways of defining modules (i.e., with address - // preceding a sequence of modules), this method is now deprecated. - // - // TODO: make this function simply return String when the other way of defining modules is - // removed - mod_def - .address - .map(|a| parsing_leading_and_mod_names_to_map_key(pkg_addresses, a, mod_def.name)) -} - -/// Produces module ident string of the form pkg::module to be used as a map key. -/// It's important that these are consistent between parsing AST and typed AST. -fn parsing_leading_and_mod_names_to_map_key( - pkg_addresses: &NamedAddressMap, - ln: P::LeadingNameAccess, - name: P::ModuleName, -) -> String { - format!("{}::{}", parsed_address(ln, pkg_addresses), name).to_string() -} - -/// Converts parsing AST's `LeadingNameAccess` to expansion AST's `Address` (similarly to -/// expansion::translate::top_level_address but disregarding the name portion of `Address` as we -/// only care about actual address here if it's available). We need this to be able to reliably -/// compare parsing AST's module identifier with expansion/typing AST's module identifier, even in -/// presence of module renaming (i.e., we cannot rely on module names if addresses are available). -fn parsed_address(ln: P::LeadingNameAccess, pkg_addresses: &NamedAddressMap) -> E::Address { - let sp!(loc, ln_) = ln; - match ln_ { - P::LeadingNameAccess_::AnonymousAddress(bytes) => E::Address::anonymous(loc, bytes), - P::LeadingNameAccess_::GlobalAddress(name) => E::Address::NamedUnassigned(name), - P::LeadingNameAccess_::Name(name) => match pkg_addresses.get(&name.value).copied() { - Some(addr) => E::Address::anonymous(loc, addr), - None => E::Address::NamedUnassigned(name), - }, - } -} diff --git a/external-crates/move/crates/move-analyzer/src/analysis/typing_analysis.rs b/external-crates/move/crates/move-analyzer/src/analysis/typing_analysis.rs index 1d5d3aebd1b..0427a1b1331 100644 --- a/external-crates/move/crates/move-analyzer/src/analysis/typing_analysis.rs +++ b/external-crates/move/crates/move-analyzer/src/analysis/typing_analysis.rs @@ -12,7 +12,7 @@ use crate::{ }; use move_compiler::{ - diagnostics as diag, + diagnostics::warning_filters::WarningFilters, expansion::ast::{self as E, ModuleIdent}, naming::ast as N, parser::ast::{self as P, ConstantName}, @@ -139,18 +139,18 @@ impl TypingAnalysisContext<'_> { } /// Add use of a const identifier - fn add_const_use_def(&mut self, module_ident: &E::ModuleIdent, name: &ConstantName) { + fn add_const_use_def(&mut self, module_ident: &E::ModuleIdent_, name: &ConstantName) { if self.traverse_only { return; } let use_pos = name.loc(); let use_name = name.value(); - let mod_ident_str = expansion_mod_ident_to_map_key(&module_ident.value); + let mod_ident_str = expansion_mod_ident_to_map_key(module_ident); let Some(mod_defs) = self.mod_outer_defs.get(&mod_ident_str) else { return; }; // insert use of the const's module - let mod_name = module_ident.value.module; + let mod_name = module_ident.module; if let Some(mod_name_start) = self.file_start_position_opt(&mod_name.loc()) { // a module will not be present if a constant belongs to an implicit module self.use_defs.insert( @@ -389,7 +389,14 @@ impl TypingAnalysisContext<'_> { sp!(_, N::TypeName_::ModuleType(sp!(_, mod_ident), struct_name)), _, ) => { - self.add_field_use_def(mod_ident, &struct_name.value(), None, use_name, use_pos); + self.add_field_use_def( + mod_ident, + &struct_name.value(), + None, + use_name, + use_pos, + /* named_only */ false, + ); } _ => (), } @@ -397,9 +404,9 @@ impl TypingAnalysisContext<'_> { fn add_variant_use_def( &mut self, - module_ident: &mut E::ModuleIdent, - enum_name: &mut P::DatatypeName, - variant_name: &mut P::VariantName, + module_ident: &E::ModuleIdent, + enum_name: &P::DatatypeName, + variant_name: &P::VariantName, ) { let use_name = variant_name.value(); let use_loc = variant_name.loc(); @@ -442,7 +449,8 @@ impl TypingAnalysisContext<'_> { ); } - /// Add use of a variant field identifier + /// Add use of a variant field identifier. In some cases, such as packing (controlled by `named_only`), we only + /// want to add named fields. fn add_field_use_def( &mut self, module_ident: &E::ModuleIdent_, @@ -450,6 +458,7 @@ impl TypingAnalysisContext<'_> { variant_name_opt: Option<&Symbol>, use_name: &Symbol, use_loc: &Loc, + named_only: bool, ) { if self.traverse_only { return; @@ -464,7 +473,7 @@ impl TypingAnalysisContext<'_> { return; }; - let field_defs = if let Some(variant_name) = variant_name_opt { + let (field_defs, positional) = if let Some(variant_name) = variant_name_opt { // get the enum let Some(def) = mod_defs.enums.get(datatype_name) else { return; @@ -475,10 +484,10 @@ impl TypingAnalysisContext<'_> { return; }; // get variant's fields - let Some((_, field_defs, _)) = variants_info.get(variant_name) else { + let Some((_, field_defs, positional)) = variants_info.get(variant_name) else { return; }; - field_defs + (field_defs, positional) } else { // get the struct let Some(def) = mod_defs.structs.get(datatype_name) else { @@ -487,14 +496,18 @@ impl TypingAnalysisContext<'_> { // get variant's fields let MemberDefInfo::Struct { field_defs, - positional: _, + positional, } = &def.info else { return; }; - field_defs + (field_defs, positional) }; + if *positional && named_only { + return; + } + for fdef in field_defs { if fdef.name == *use_name { let field_info = self.def_info.get(&fdef.loc).unwrap(); @@ -520,15 +533,15 @@ impl TypingAnalysisContext<'_> { module: &ModuleIdent, name: &P::FunctionName, method_name: Option, - tyargs: &mut [N::Type], - args: Option<&mut Box>, + tyargs: &[N::Type], + args: Option<&T::Exp>, ) { let fun_name = name.value(); // a function name (same as fun_name) or method name (different from fun_name) let fun_use = method_name.unwrap_or_else(|| sp(name.loc(), name.value())); let call_use_def = self.add_fun_use_def(module, &fun_name, &fun_use.value, &fun_use.loc); // handle type parameters - for t in tyargs.iter_mut() { + for t in tyargs.iter() { self.visit_type(None, t); } if let Some(args) = args { @@ -551,17 +564,17 @@ impl TypingAnalysisContext<'_> { } } - fn process_match_patterm(&mut self, match_pat: &mut T::MatchPattern) { + fn process_match_patterm(&mut self, match_pat: &T::MatchPattern) { use T::UnannotatedPat_ as UA; - self.visit_type(None, &mut match_pat.ty); - match &mut match_pat.pat.value { + self.visit_type(None, &match_pat.ty); + match &match_pat.pat.value { UA::Variant(mident, name, vname, tyargs, fields) | UA::BorrowVariant(_, mident, name, vname, tyargs, fields) => { self.add_datatype_use_def(mident, name); self.add_variant_use_def(mident, name, vname); - tyargs.iter_mut().for_each(|t| self.visit_type(None, t)); - for (fpos, fname, (_, (_, pat))) in fields.iter_mut() { + tyargs.iter().for_each(|t| self.visit_type(None, t)); + for (fpos, fname, (_, (_, pat))) in fields.iter() { if self.compiler_info.ellipsis_binders.get(&fpos).is_none() { self.add_field_use_def( &mident.value, @@ -569,6 +582,7 @@ impl TypingAnalysisContext<'_> { Some(&vname.value()), fname, &fpos, + /* named_only */ false, ); } self.process_match_patterm(pat); @@ -577,15 +591,22 @@ impl TypingAnalysisContext<'_> { UA::Struct(mident, name, tyargs, fields) | UA::BorrowStruct(_, mident, name, tyargs, fields) => { self.add_datatype_use_def(mident, name); - tyargs.iter_mut().for_each(|t| self.visit_type(None, t)); - for (fpos, fname, (_, (_, pat))) in fields.iter_mut() { + tyargs.iter().for_each(|t| self.visit_type(None, t)); + for (fpos, fname, (_, (_, pat))) in fields.iter() { if self.compiler_info.ellipsis_binders.get(&fpos).is_none() { - self.add_field_use_def(&mident.value, &name.value(), None, fname, &fpos); + self.add_field_use_def( + &mident.value, + &name.value(), + None, + fname, + &fpos, + /* named_only */ false, + ); } self.process_match_patterm(pat); } } - UA::Constant(mod_ident, name) => self.add_const_use_def(mod_ident, name), + UA::Constant(mod_ident, name) => self.add_const_use_def(&mod_ident.value, name), UA::Or(pat1, pat2) => { self.process_match_patterm(pat1); self.process_match_patterm(pat2); @@ -600,10 +621,10 @@ impl TypingAnalysisContext<'_> { } } - fn process_match_arm(&mut self, sp!(_, arm): &mut T::MatchArm) { - self.process_match_patterm(&mut arm.pattern); + fn process_match_arm(&mut self, sp!(_, arm): &T::MatchArm) { + self.process_match_patterm(&arm.pattern); let guard_loc = arm.guard.as_ref().map(|exp| exp.exp.loc); - arm.binders.iter_mut().for_each(|(var, ty)| { + arm.binders.iter().for_each(|(var, ty)| { self.add_local_def( &var.loc, &var.value.name, @@ -614,7 +635,7 @@ impl TypingAnalysisContext<'_> { ); }); - if let Some(exp) = &mut arm.guard { + if let Some(exp) = &arm.guard { self.visit_exp(exp); // Enum guard variables have different type (immutable reference) than variables in // patterns and in the RHS of the match arm. However, at the AST level they share @@ -635,13 +656,13 @@ impl TypingAnalysisContext<'_> { .or_default() .insert(guard_loc); } - self.visit_exp(&mut arm.rhs); + self.visit_exp(&arm.rhs); } } impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { // Nothing to do -- we're not producing errors. - fn add_warning_filter_scope(&mut self, _filter: diag::WarningFilters) {} + fn push_warning_filter_scope(&mut self, _filter: WarningFilters) {} // Nothing to do -- we're not producing errors. fn pop_warning_filter_scope(&mut self) {} @@ -659,7 +680,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { &mut self, module: move_compiler::expansion::ast::ModuleIdent, struct_name: P::DatatypeName, - sdef: &mut N::StructDefinition, + sdef: &N::StructDefinition, ) { self.reset_for_module_member(); assert!(self.current_mod_ident_str.is_none()); @@ -684,7 +705,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { for stp in &sdef.type_parameters { self.add_type_param(&stp.param); } - if let N::StructFields::Defined(positional, fields) = &mut sdef.fields { + if let N::StructFields::Defined(positional, fields) = &sdef.fields { for (fpos, fname, (_, ty)) in fields { self.visit_type(None, ty); if !*positional { @@ -720,7 +741,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { &mut self, module: move_compiler::expansion::ast::ModuleIdent, enum_name: P::DatatypeName, - edef: &mut N::EnumDefinition, + edef: &N::EnumDefinition, ) -> bool { self.reset_for_module_member(); assert!(self.current_mod_ident_str.is_none()); @@ -746,7 +767,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { self.add_type_param(&etp.param); } - for (vname, vdef) in edef.variants.key_cloned_iter_mut() { + for (vname, vdef) in edef.variants.key_cloned_iter() { self.visit_variant(&module, &enum_name, vname, vdef); } self.current_mod_ident_str = None; @@ -758,7 +779,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { _module: &move_compiler::expansion::ast::ModuleIdent, _enum_name: &P::DatatypeName, variant_name: P::VariantName, - vdef: &mut N::VariantDefinition, + vdef: &N::VariantDefinition, ) -> bool { let file_hash = variant_name.loc().file_hash(); // enter self-definition for variant name (unwrap safe - done when inserting def) @@ -777,7 +798,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { vtype_def, ), ); - if let N::VariantFields::Defined(positional, fields) = &mut vdef.fields { + if let N::VariantFields::Defined(positional, fields) = &vdef.fields { for (floc, fname, (_, ty)) in fields { self.visit_type(None, ty); if !*positional { @@ -811,7 +832,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { &mut self, module: move_compiler::expansion::ast::ModuleIdent, constant_name: P::ConstantName, - cdef: &mut T::Constant, + cdef: &T::Constant, ) { self.reset_for_module_member(); assert!(self.current_mod_ident_str.is_none()); @@ -833,7 +854,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { ident_type_def_loc, ), ); - self.visit_exp(&mut cdef.value); + self.visit_exp(&cdef.value); self.current_mod_ident_str = None; } @@ -841,7 +862,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { &mut self, module: move_compiler::expansion::ast::ModuleIdent, function_name: P::FunctionName, - fdef: &mut T::Function, + fdef: &T::Function, ) { self.reset_for_module_member(); if ignored_function(function_name.value()) { @@ -871,7 +892,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { self.add_type_param(tp); } - for (mutability, pname, ptype) in &mut fdef.signature.parameters { + for (mutability, pname, ptype) in &fdef.signature.parameters { self.visit_type(None, ptype); // add definition of the parameter @@ -885,27 +906,27 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { ); } - match &mut fdef.body.value { + match &fdef.body.value { T::FunctionBody_::Defined(seq) => { - self.visit_seq(seq); + self.visit_seq(fdef.body.loc, seq); } T::FunctionBody_::Macro | T::FunctionBody_::Native => (), } // process return types - self.visit_type(None, &mut fdef.signature.return_type); + self.visit_type(None, &fdef.signature.return_type); // clear type params from the scope self.type_params.clear(); self.current_mod_ident_str = None; } - fn visit_lvalue(&mut self, kind: &LValueKind, lvalue: &mut T::LValue) { + fn visit_lvalue(&mut self, kind: &LValueKind, lvalue: &T::LValue) { // Visit an lvalue. If it's just avariable, we add it as a local def. If it'x a field // access, we switch modes (`for_unpack` = true) and record them as field use defs instead. let mut for_unpack = false; let mut lvalue_queue = vec![lvalue]; while let Some(next) = lvalue_queue.pop() { - match &mut next.value { + match &next.value { T::LValue_::Ignore => (), T::LValue_::Var { mut_, @@ -931,9 +952,16 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { | T::LValue_::BorrowUnpack(_, mident, name, tyargs, fields) => { for_unpack = true; self.add_datatype_use_def(mident, name); - tyargs.iter_mut().for_each(|t| self.visit_type(None, t)); + tyargs.iter().for_each(|t| self.visit_type(None, t)); for (fpos, fname, (_, (_, lvalue))) in fields { - self.add_field_use_def(&mident.value, &name.value(), None, fname, &fpos); + self.add_field_use_def( + &mident.value, + &name.value(), + None, + fname, + &fpos, + /* named_only */ false, + ); lvalue_queue.push(lvalue); } } @@ -941,7 +969,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { | T::LValue_::BorrowUnpackVariant(_, mident, name, vname, tyargs, fields) => { for_unpack = true; self.add_datatype_use_def(mident, name); - tyargs.iter_mut().for_each(|t| self.visit_type(None, t)); + tyargs.iter().for_each(|t| self.visit_type(None, t)); for (fpos, fname, (_, (_, lvalue))) in fields { self.add_field_use_def( &mident.value, @@ -949,6 +977,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { Some(&vname.value()), fname, &fpos, + /* named_only */ false, ); lvalue_queue.push(lvalue); } @@ -957,7 +986,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { } } - fn visit_seq(&mut self, (use_funs, seq): &mut T::Sequence) { + fn visit_seq(&mut self, _loc: Loc, (use_funs, seq): &T::Sequence) { let old_traverse_mode = self.traverse_only; // start adding new use-defs etc. when processing arguments if use_funs.color == 0 { @@ -976,13 +1005,13 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { } } - fn visit_exp_custom(&mut self, _exp: &mut T::Exp) -> bool { + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { use T::UnannotatedExp_ as TE; - fn visit_exp_inner(visitor: &mut TypingAnalysisContext<'_>, exp: &mut T::Exp) -> bool { + fn visit_exp_inner(visitor: &mut TypingAnalysisContext<'_>, exp: &T::Exp) -> bool { let exp_loc = exp.exp.loc; - visitor.visit_type(Some(exp_loc), &mut exp.ty); - match &mut exp.exp.value { + visitor.visit_type(Some(exp_loc), &exp.ty); + match &exp.exp.value { TE::Move { from_user: _, var } | TE::Copy { from_user: _, var } | TE::Use(var) @@ -991,28 +1020,35 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { true } TE::Constant(mod_ident, name) => { - visitor.add_const_use_def(mod_ident, name); + visitor.add_const_use_def(&mod_ident.value, name); true } TE::ModuleCall(mod_call) => { - let call = &mut **mod_call; + let call = &**mod_call; visitor.process_module_call( &call.module, &call.name, call.method_name, - &mut call.type_arguments, - Some(&mut call.arguments), + &call.type_arguments, + Some(&call.arguments), ); true } TE::Pack(mident, name, tyargs, fields) => { visitor.add_datatype_use_def(mident, name); - for (fpos, fname, (_, (_, init_exp))) in fields.iter_mut() { - visitor.add_field_use_def(&mident.value, &name.value(), None, fname, &fpos); + for (fpos, fname, (_, (_, init_exp))) in fields.iter() { + visitor.add_field_use_def( + &mident.value, + &name.value(), + None, + fname, + &fpos, + /* named_only */ true, + ); visitor.visit_exp(init_exp); } tyargs - .iter_mut() + .iter() .for_each(|t| visitor.visit_type(Some(exp_loc), t)); true } @@ -1023,18 +1059,20 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { } TE::PackVariant(mident, name, vname, tyargs, fields) => { visitor.add_datatype_use_def(mident, name); - for (fpos, fname, (_, (_, init_exp))) in fields.iter_mut() { + visitor.add_variant_use_def(mident, name, vname); + for (fpos, fname, (_, (_, init_exp))) in fields.iter() { visitor.add_field_use_def( &mident.value, &name.value(), Some(&vname.value()), fname, &fpos, + /* named_only */ true, ); visitor.visit_exp(init_exp); } tyargs - .iter_mut() + .iter() .for_each(|t| visitor.visit_type(Some(exp_loc), t)); true } @@ -1045,7 +1083,24 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { } TE::Match(exp, sp!(_, v)) => { visitor.visit_exp(exp); - v.iter_mut().for_each(|arm| visitor.process_match_arm(arm)); + v.iter().for_each(|arm| visitor.process_match_arm(arm)); + true + } + TE::ErrorConstant { + line_number_loc: _, + error_constant, + } => { + // assume that constant is defined in the same module where it's used + // TODO: if above ever changes, we need to update this (presumably + // `ErrorConstant` will carry module ident at this point) + if let Some(name) = error_constant { + if let Some(mod_def) = visitor + .mod_outer_defs + .get(visitor.current_mod_ident_str.as_ref().unwrap()) + { + visitor.add_const_use_def(&mod_def.ident.clone(), name); + } + }; true } TE::Unit { .. } @@ -1070,49 +1125,46 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { | TE::TempBorrow(_, _) | TE::Cast(_, _) | TE::Annotate(_, _) - | TE::ErrorConstant { .. } | TE::UnresolvedError => false, } } - let expanded_lambda = self.compiler_info.is_expanded_lambda(&_exp.exp.loc); - if let Some(macro_call_info) = self.compiler_info.get_macro_info(&_exp.exp.loc) { + let expanded_lambda = self.compiler_info.is_expanded_lambda(&exp.exp.loc); + if let Some(macro_call_info) = self.compiler_info.get_macro_info(&exp.exp.loc) { debug_assert!(!expanded_lambda, "Compiler info issue"); let MacroCallInfo { module, name, method_name, - mut type_arguments, - mut by_value_args, + type_arguments, + by_value_args, } = macro_call_info.clone(); - self.process_module_call(&module, &name, method_name, &mut type_arguments, None); - by_value_args - .iter_mut() - .for_each(|a| self.visit_seq_item(a)); + self.process_module_call(&module, &name, method_name, &type_arguments, None); + by_value_args.iter().for_each(|a| self.visit_seq_item(a)); let old_traverse_mode = self.traverse_only; // stop adding new use-defs etc. self.traverse_only = true; - let result = visit_exp_inner(self, _exp); + let result = visit_exp_inner(self, exp); self.traverse_only = old_traverse_mode; result } else if expanded_lambda { let old_traverse_mode = self.traverse_only; // start adding new use-defs etc. when processing a lambda argument self.traverse_only = false; - let result = visit_exp_inner(self, _exp); + let result = visit_exp_inner(self, exp); self.traverse_only = old_traverse_mode; result } else { - visit_exp_inner(self, _exp) + visit_exp_inner(self, exp) } } - fn visit_type_custom(&mut self, exp_loc: Option, ty: &mut N::Type) -> bool { + fn visit_type_custom(&mut self, exp_loc: Option, ty: &N::Type) -> bool { if self.traverse_only { return true; } let loc = ty.loc; - match &mut ty.value { + match &ty.value { N::Type_::Param(tparam) => { let sp!(use_pos, use_name) = tparam.user_specified_name; let Some(name_start) = self.file_start_position_opt(&loc) else { @@ -1146,7 +1198,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { if let N::TypeName_::ModuleType(mod_ident, struct_name) = type_name { self.add_datatype_use_def(mod_ident, struct_name); } // otherwise nothing to be done for other type names - for t in tyargs.iter_mut() { + for t in tyargs.iter() { self.visit_type(exp_loc, t); } true @@ -1161,7 +1213,7 @@ impl<'a> TypingVisitorContext for TypingAnalysisContext<'a> { } } - fn visit_use_funs(&mut self, use_funs: &mut N::UseFuns) { + fn visit_use_funs(&mut self, use_funs: &N::UseFuns) { let N::UseFuns { resolved, implicit_candidates, diff --git a/external-crates/move/crates/move-analyzer/src/analyzer.rs b/external-crates/move/crates/move-analyzer/src/analyzer.rs index 1c74a033f79..a42e8e14c3e 100644 --- a/external-crates/move/crates/move-analyzer/src/analyzer.rs +++ b/external-crates/move/crates/move-analyzer/src/analyzer.rs @@ -20,7 +20,7 @@ use std::{ }; use crate::{ - completion::on_completion_request, context::Context, inlay_hints, symbols, + completions::on_completion_request, context::Context, inlay_hints, symbols, vfs::on_text_document_sync_notification, }; use url::Url; @@ -46,9 +46,10 @@ pub fn run() { let (connection, io_threads) = Connection::stdio(); let symbols_map = Arc::new(Mutex::new(BTreeMap::new())); - let pkg_deps = Arc::new(Mutex::new( - BTreeMap::::new(), - )); + let pkg_deps = Arc::new(Mutex::new(BTreeMap::< + PathBuf, + symbols::PrecomputedPkgDepsInfo, + >::new())); let ide_files_root: VfsPath = MemoryFS::new().into(); let (id, client_response) = connection @@ -148,7 +149,8 @@ pub fn run() { // main reason for this is to enable unit tests that rely on the symbolication information // to be available right after the client is initialized. if let Some(uri) = initialize_params.root_uri { - if let Some(p) = symbols::SymbolicatorRunner::root_dir(&uri.to_file_path().unwrap()) { + let build_path = uri.to_file_path().unwrap(); + if let Some(p) = symbols::SymbolicatorRunner::root_dir(&build_path) { if let Ok((Some(new_symbols), _)) = symbols::get_symbols( Arc::new(Mutex::new(BTreeMap::new())), ide_files_root.clone(), @@ -278,7 +280,7 @@ fn on_request( context: &Context, request: &Request, ide_files_root: VfsPath, - pkg_dependencies: Arc>>, + pkg_dependencies: Arc>>, shutdown_request_received: bool, ) -> bool { if shutdown_request_received { diff --git a/external-crates/move/crates/move-analyzer/src/completion.rs b/external-crates/move/crates/move-analyzer/src/completion.rs deleted file mode 100644 index a20ed803246..00000000000 --- a/external-crates/move/crates/move-analyzer/src/completion.rs +++ /dev/null @@ -1,1731 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use std::{ - collections::{BTreeMap, BTreeSet, HashSet}, - path::{Path, PathBuf}, - sync::{Arc, Mutex}, -}; - -use itertools::Itertools; -use lsp_server::Request; -use lsp_types::{ - CompletionItem, CompletionItemKind, CompletionItemLabelDetails, CompletionParams, - Documentation, InsertTextFormat, Position, -}; -use move_command_line_common::files::FileHash; -use move_compiler::{ - editions::Edition, - expansion::ast::{Address, ModuleIdent, ModuleIdent_, Visibility}, - linters::LintLevel, - naming::ast::{Type, Type_}, - parser::{ - ast::{self as P, Ability_, LeadingNameAccess, LeadingNameAccess_}, - keywords::{BUILTINS, CONTEXTUAL_KEYWORDS, KEYWORDS, PRIMITIVE_TYPES}, - lexer::{Lexer, Tok}, - }, - shared::{ - ide::{AliasAutocompleteInfo, AutocompleteMethod}, - Identifier, Name, NumericalAddress, - }, -}; -use move_ir_types::location::{sp, Loc}; -use move_symbol_pool::Symbol; -use once_cell::sync::Lazy; -use vfs::VfsPath; - -use crate::{ - context::Context, - symbols::{ - self, mod_ident_to_ide_string, ret_type_to_ide_str, type_args_to_ide_string, - type_list_to_ide_string, type_to_ide_string, ChainCompletionKind, ChainInfo, CursorContext, - CursorDefinition, DefInfo, FunType, PrecompiledPkgDeps, SymbolicatorRunner, Symbols, - VariantInfo, - }, - utils, -}; - -/// Describes kind of the name access chain component. -enum ChainComponentKind { - Package(LeadingNameAccess), - Module(ModuleIdent), - Member(ModuleIdent, Symbol), -} - -/// Information about access chain component - its location and kind. -struct ChainComponentInfo { - loc: Loc, - kind: ChainComponentKind, -} - -impl ChainComponentInfo { - fn new(loc: Loc, kind: ChainComponentKind) -> Self { - Self { loc, kind } - } -} - -/// Constructs an `lsp_types::CompletionItem` with the given `label` and `kind`. -fn completion_item(label: &str, kind: CompletionItemKind) -> CompletionItem { - CompletionItem { - label: label.to_owned(), - kind: Some(kind), - ..Default::default() - } -} - -/// List of completion items corresponding to each one of Move's keywords. -/// -/// Currently, this does not filter keywords out based on whether they are valid -/// at the completion request's cursor position, but in the future it ought to. -/// For example, this function returns all specification language keywords, but -/// in the future it should be modified to only do so within a spec block. -static KEYWORD_COMPLETIONS: Lazy> = Lazy::new(|| { - let mut keywords = KEYWORDS - .iter() - .chain(CONTEXTUAL_KEYWORDS.iter()) - .chain(PRIMITIVE_TYPES.iter()) - .map(|label| { - let kind = if label == &"copy" || label == &"move" { - CompletionItemKind::OPERATOR - } else { - CompletionItemKind::KEYWORD - }; - completion_item(label, kind) - }) - .collect::>(); - keywords.extend(PRIMITIVE_TYPE_COMPLETIONS.clone()); - keywords -}); - -/// List of completion items of Move's primitive types. -static PRIMITIVE_TYPE_COMPLETIONS: Lazy> = Lazy::new(|| { - let mut primitive_types = PRIMITIVE_TYPES - .iter() - .map(|label| completion_item(label, CompletionItemKind::KEYWORD)) - .collect::>(); - primitive_types.push(completion_item("address", CompletionItemKind::KEYWORD)); - primitive_types -}); - -/// List of completion items corresponding to each one of Move's builtin -/// functions. -static BUILTIN_COMPLETIONS: Lazy> = Lazy::new(|| { - BUILTINS - .iter() - .map(|label| completion_item(label, CompletionItemKind::FUNCTION)) - .collect() -}); - -/// Lexes the Move source file at the given path and returns a list of -/// completion items corresponding to the non-keyword identifiers therein. -/// -/// Currently, this does not perform semantic analysis to determine whether the -/// identifiers returned are valid at the request's cursor position. However, -/// this list of identifiers is akin to what editors like Visual Studio Code -/// would provide as completion items if this language server did not initialize -/// with a response indicating it's capable of providing completions. In -/// the future, the server should be modified to return semantically valid -/// completion items, not simple textual suggestions. -fn identifiers(buffer: &str, symbols: &Symbols, path: &Path) -> Vec { - // TODO thread through package configs - let mut lexer = Lexer::new(buffer, FileHash::new(buffer), Edition::LEGACY); - if lexer.advance().is_err() { - return vec![]; - } - let mut ids = HashSet::new(); - while lexer.peek() != Tok::EOF { - // Some tokens, such as "phantom", are contextual keywords that are only - // reserved in certain contexts. Since for now this language server - // doesn't analyze semantic context, tokens such as "phantom" are always - // present in keyword suggestions. To avoid displaying these keywords to - // the user twice in the case that the token "phantom" is present in the - // source program (once as a keyword, and once as an identifier), we filter out - // any identifier token that has the same text as a keyword. - if lexer.peek() == Tok::Identifier && !KEYWORDS.contains(&lexer.content()) { - // The completion item kind "text" indicates the item is not based on any - // semantic context of the request cursor's position. - ids.insert(lexer.content()); - } - if lexer.advance().is_err() { - break; - } - } - - let mods_opt = symbols.file_mods.get(path); - - // The completion item kind "text" indicates that the item is based on simple - // textual matching, not any deeper semantic analysis. - ids.iter() - .map(|label| { - if let Some(mods) = mods_opt { - if mods - .iter() - .any(|m| m.functions().contains_key(&Symbol::from(*label))) - { - completion_item(label, CompletionItemKind::FUNCTION) - } else { - completion_item(label, CompletionItemKind::TEXT) - } - } else { - completion_item(label, CompletionItemKind::TEXT) - } - }) - .collect() -} - -/// Returns the token corresponding to the "trigger character" if it is one of -/// `.`, `:`, '{', or `::`. Otherwise, returns `None` (position points at the -/// potential trigger character itself). -fn get_cursor_token(buffer: &str, position: &Position) -> Option { - let line = match buffer.lines().nth(position.line as usize) { - Some(line) => line, - None => return None, // Our buffer does not contain the line, and so must be out of date. - }; - match line.chars().nth(position.character as usize) { - Some('.') => Some(Tok::Period), - Some(':') => { - if position.character > 0 - && line.chars().nth(position.character as usize - 1) == Some(':') - { - Some(Tok::ColonColon) - } else { - Some(Tok::Colon) - } - } - Some('{') => Some(Tok::LBrace), - _ => None, - } -} - -/// Handle context-specific auto-completion requests with lbrace (`{`) trigger -/// character. -fn context_specific_lbrace( - symbols: &Symbols, - cursor: &CursorContext, -) -> (Vec, bool) { - let mut completions = vec![]; - let mut only_custom_items = false; - // look for a struct definition on the line that contains `{`, check its - // abilities, and do auto-completion if `key` ability is present - let Some(CursorDefinition::Struct(sname)) = &cursor.defn_name else { - return (completions, only_custom_items); - }; - only_custom_items = true; - let Some(mident) = cursor.module else { - return (completions, only_custom_items); - }; - let Some(typed_ast) = symbols.typed_ast.as_ref() else { - return (completions, only_custom_items); - }; - let Some(struct_def) = typed_ast.info.struct_definition_opt(&mident, sname) else { - return (completions, only_custom_items); - }; - if struct_def.abilities.has_ability_(Ability_::Key) { - let obj_snippet = "\n\tid: UID,\n\t$1\n".to_string(); - let init_completion = CompletionItem { - label: "id: UID".to_string(), - kind: Some(CompletionItemKind::SNIPPET), - documentation: Some(Documentation::String("Object snippet".to_string())), - insert_text: Some(obj_snippet), - insert_text_format: Some(InsertTextFormat::SNIPPET), - ..Default::default() - }; - completions.push(init_completion); - } - (completions, only_custom_items) -} - -fn fun_def_info(symbols: &Symbols, mod_ident: ModuleIdent_, name: Symbol) -> Option<&DefInfo> { - let Some(mod_defs) = symbols - .file_mods - .values() - .flatten() - .find(|mdef| mdef.ident == mod_ident) - else { - return None; - }; - - let Some(fdef) = mod_defs.functions.get(&name) else { - return None; - }; - symbols.def_info(&fdef.name_loc) -} - -fn lambda_snippet(sp!(_, ty): &Type, snippet_idx: &mut i32) -> Option { - if let Type_::Fun(vec, _) = ty { - let arg_snippets = vec - .iter() - .map(|_| { - *snippet_idx += 1; - format!("${{{snippet_idx}}}") - }) - .collect::>() - .join(", "); - *snippet_idx += 1; - return Some(format!("|{arg_snippets}| ${{{snippet_idx}}}")); - } - None -} - -fn call_completion_item( - mod_ident: &ModuleIdent_, - is_macro: bool, - method_name_opt: Option<&Symbol>, - function_name: &Symbol, - type_args: &[Type], - arg_names: &[Name], - arg_types: &[Type], - ret_type: &Type, - inside_use: bool, -) -> CompletionItem { - let sig_string = format!( - "fun {}({}){}", - type_args_to_ide_string(type_args, /* verbose */ false), - type_list_to_ide_string(arg_types, /* verbose */ false), - ret_type_to_ide_str(ret_type, /* verbose */ false) - ); - // if it's a method call we omit the first argument which is guaranteed to be - // there as this is a method and needs a receiver - let omitted_arg_count = if method_name_opt.is_some() { 1 } else { 0 }; - let mut snippet_idx = 0; - let arg_snippet = arg_names - .iter() - .zip(arg_types) - .skip(omitted_arg_count) - .map(|(name, ty)| { - lambda_snippet(ty, &mut snippet_idx).unwrap_or_else(|| { - let mut arg_name = name.to_string(); - if arg_name.starts_with('$') { - arg_name = arg_name[1..].to_string(); - } - snippet_idx += 1; - format!("${{{}:{}}}", snippet_idx, arg_name) - }) - }) - .collect::>() - .join(", "); - let macro_suffix = if is_macro { "!" } else { "" }; - let label_details = Some(CompletionItemLabelDetails { - detail: Some(format!( - " ({}::{})", - mod_ident_to_ide_string(mod_ident), - function_name - )), - description: Some(sig_string), - }); - - let method_name = method_name_opt.unwrap_or(function_name); - let (insert_text, insert_text_format) = if inside_use { - ( - Some(format!("{method_name}")), - Some(InsertTextFormat::PLAIN_TEXT), - ) - } else { - ( - Some(format!("{method_name}{macro_suffix}({arg_snippet})")), - Some(InsertTextFormat::SNIPPET), - ) - }; - - CompletionItem { - label: format!("{method_name}{macro_suffix}()"), - label_details, - kind: Some(CompletionItemKind::METHOD), - insert_text, - insert_text_format, - ..Default::default() - } -} - -/// Handle dot auto-completion at a given position. -fn dot_completions( - symbols: &Symbols, - use_fpath: &Path, - position: &Position, -) -> Vec { - let mut completions = vec![]; - let Some(fhash) = symbols.file_hash(use_fpath) else { - eprintln!("no dot completions due to missing file"); - return completions; - }; - let Some(loc) = utils::lsp_position_to_loc(&symbols.files, fhash, position) else { - eprintln!("no dot completions due to missing loc"); - return completions; - }; - let Some(info) = symbols.compiler_info.get_autocomplete_info(fhash, &loc) else { - eprintln!("no dot completions due to no compiler autocomplete info"); - return completions; - }; - for AutocompleteMethod { - method_name, - target_function: (mod_ident, function_name), - } in &info.methods - { - let call_completion = if let Some(DefInfo::Function( - .., - fun_type, - _, - type_args, - arg_names, - arg_types, - ret_type, - _, - )) = fun_def_info(symbols, mod_ident.value, function_name.value()) - { - call_completion_item( - &mod_ident.value, - matches!(fun_type, FunType::Macro), - Some(method_name), - &function_name.value(), - type_args, - arg_names, - arg_types, - ret_type, - // inside_use - false, - ) - } else { - // this shouldn't really happen as we should be able to get - // `DefInfo` for a function but if for some reason we cannot, - // let's generate simpler autotompletion value - eprintln!("incomplete dot item"); - CompletionItem { - label: format!("{method_name}()"), - kind: Some(CompletionItemKind::METHOD), - insert_text: Some(method_name.to_string()), - insert_text_format: Some(InsertTextFormat::PLAIN_TEXT), - ..Default::default() - } - }; - completions.push(call_completion); - } - for (n, t) in &info.fields { - let label_details = Some(CompletionItemLabelDetails { - detail: None, - description: Some(type_to_ide_string(t, /* verbose */ false)), - }); - let init_completion = CompletionItem { - label: n.to_string(), - label_details, - kind: Some(CompletionItemKind::FIELD), - insert_text: Some(n.to_string()), - insert_text_format: Some(InsertTextFormat::PLAIN_TEXT), - ..Default::default() - }; - completions.push(init_completion); - } - completions -} - -/// Returns all possible completions for a module member (e.g., a datatype) -/// component of a name access chain, where the prefix of this component (e.g, -/// in `some_pkg::some_mod::`) represents a module specified in -/// `prefix_mod_ident`. The `inside_use` parameter determines if completion is -/// for "regular" access chain or for completion within a `use` statement. -fn module_member_completions( - symbols: &Symbols, - cursor: &CursorContext, - prefix_mod_ident: &ModuleIdent, - chain_kind: ChainCompletionKind, - inside_use: bool, -) -> Vec { - use ChainCompletionKind as CT; - - let mut completions = vec![]; - - let Some(mod_defs) = symbols - .file_mods - .values() - .flatten() - .find(|mdef| mdef.ident == prefix_mod_ident.value) - else { - return completions; - }; - - // list all members or only publicly visible ones - let mut same_module = false; - let mut same_package = false; - if let Some(cursor_mod_ident) = cursor.module { - if &cursor_mod_ident == prefix_mod_ident { - same_module = true; - } - if cursor_mod_ident.value.address == prefix_mod_ident.value.address { - same_package = true; - } - } - - if matches!(chain_kind, CT::Function) || matches!(chain_kind, CT::All) { - let fun_completions = mod_defs - .functions - .iter() - .filter_map(|(fname, fdef)| { - symbols - .def_info(&fdef.name_loc) - .map(|def_info| (fname, def_info)) - }) - .filter(|(_, def_info)| { - if let DefInfo::Function(_, visibility, ..) = def_info { - match visibility { - Visibility::Internal => same_module, - Visibility::Package(_) => same_package, - _ => true, - } - } else { - false - } - }) - .filter_map(|(fname, def_info)| { - if let DefInfo::Function( - _, - _, - fun_type, - _, - type_args, - arg_names, - arg_types, - ret_type, - _, - ) = def_info - { - Some(call_completion_item( - &prefix_mod_ident.value, - matches!(fun_type, FunType::Macro), - None, - fname, - type_args, - arg_names, - arg_types, - ret_type, - inside_use, - )) - } else { - None - } - }); - completions.extend(fun_completions); - } - - if matches!(chain_kind, CT::Type) || matches!(chain_kind, CT::All) { - completions.extend( - mod_defs - .structs - .keys() - .map(|sname| completion_item(sname, CompletionItemKind::STRUCT)), - ); - completions.extend( - mod_defs - .enums - .keys() - .map(|ename| completion_item(ename, CompletionItemKind::ENUM)), - ); - } - - if matches!(chain_kind, CT::All) && same_module { - completions.extend( - mod_defs - .constants - .keys() - .map(|cname| completion_item(cname, CompletionItemKind::CONSTANT)), - ); - } - - completions -} - -/// Returns completion item if a given name/alias identifies a valid member of a -/// given module available in the completion scope as if it was a single-length -/// name chain. -fn single_name_member_completion( - symbols: &Symbols, - mod_ident: &ModuleIdent_, - member_alias: &Symbol, - member_name: &Symbol, - chain_kind: ChainCompletionKind, -) -> Option { - use ChainCompletionKind as CT; - - let Some(mod_defs) = symbols - .file_mods - .values() - .flatten() - .find(|mdef| mdef.ident == *mod_ident) - else { - return None; - }; - - // is it a function? - if let Some(fdef) = mod_defs.functions.get(member_name) { - if !(matches!(chain_kind, CT::Function) || matches!(chain_kind, CT::All)) { - return None; - } - let Some(DefInfo::Function(.., fun_type, _, type_args, arg_names, arg_types, ret_type, _)) = - symbols.def_info(&fdef.name_loc) - else { - return None; - }; - return Some(call_completion_item( - mod_ident, - matches!(fun_type, FunType::Macro), - None, - member_alias, - type_args, - arg_names, - arg_types, - ret_type, - // inside_use - false, - )); - }; - - // is it a struct? - if mod_defs.structs.get(member_name).is_some() { - if !(matches!(chain_kind, CT::Type) || matches!(chain_kind, CT::All)) { - return None; - } - return Some(completion_item( - member_alias.as_str(), - CompletionItemKind::STRUCT, - )); - } - - // is it an enum? - if mod_defs.enums.get(member_name).is_some() { - if !(matches!(chain_kind, CT::Type) || matches!(chain_kind, CT::All)) { - return None; - } - return Some(completion_item( - member_alias.as_str(), - CompletionItemKind::ENUM, - )); - } - - // is it a const? - if mod_defs.constants.get(member_name).is_some() { - if !matches!(chain_kind, CT::All) { - return None; - } - return Some(completion_item( - member_alias.as_str(), - CompletionItemKind::CONSTANT, - )); - } - - None -} - -/// Returns completion items for all members of a given module as if they were -/// single-length name chains. -fn all_single_name_member_completions( - symbols: &Symbols, - members_info: &BTreeSet<(Symbol, ModuleIdent, Name)>, - chain_kind: ChainCompletionKind, -) -> Vec { - let mut completions = vec![]; - for (member_alias, sp!(_, mod_ident), member_name) in members_info { - let Some(member_completion) = single_name_member_completion( - symbols, - mod_ident, - member_alias, - &member_name.value, - chain_kind, - ) else { - continue; - }; - completions.push(member_completion); - } - completions -} - -/// Checks if a given module identifier represents a module in a package -/// identifier by `leading_name`. -fn is_pkg_mod_ident(mod_ident: &ModuleIdent_, leading_name: &LeadingNameAccess) -> bool { - match mod_ident.address { - Address::NamedUnassigned(name) => matches!(leading_name.value, - LeadingNameAccess_::Name(n) | LeadingNameAccess_::GlobalAddress(n) if name == n), - Address::Numerical { - name, - value, - name_conflict: _, - } => match leading_name.value { - LeadingNameAccess_::AnonymousAddress(addr) if addr == value.value => true, - LeadingNameAccess_::Name(addr_name) | LeadingNameAccess_::GlobalAddress(addr_name) - if Some(addr_name) == name => - { - true - } - _ => false, - }, - } -} - -/// Gets module identifiers for a given package identified by `leading_name`. -fn pkg_mod_identifiers( - symbols: &Symbols, - info: &AliasAutocompleteInfo, - leading_name: &LeadingNameAccess, -) -> BTreeSet { - info.modules - .values() - .filter(|mod_ident| is_pkg_mod_ident(&mod_ident.value, leading_name)) - .copied() - .chain( - symbols - .file_mods - .values() - .flatten() - .map(|mdef| sp(mdef.name_loc, mdef.ident)) - .filter(|mod_ident| is_pkg_mod_ident(&mod_ident.value, leading_name)), - ) - .collect::>() -} - -/// Computes completion for a single enum variant. -fn variant_completion(symbols: &Symbols, vinfo: &VariantInfo) -> Option { - let Some(DefInfo::Variant(_, _, vname, is_positional, field_names, ..)) = - symbols.def_info.get(&vinfo.name.loc) - else { - return None; - }; - - let label = if field_names.is_empty() { - vname.to_string() - } else if *is_positional { - format!("{vname}()") - } else { - format!("{vname}{{}}") - }; - let field_snippet = field_names - .iter() - .enumerate() - .map(|(snippet_idx, fname)| { - if *is_positional { - format!("${{{}}}", snippet_idx + 1) - } else { - format!("${{{}:{}}}", snippet_idx + 1, fname) - } - }) - .collect::>() - .join(", "); - let insert_text = if *is_positional { - format!("{vname}({field_snippet})") - } else { - format!("{vname}{{{field_snippet}}}") - }; - - Some(CompletionItem { - label, - kind: Some(CompletionItemKind::ENUM_MEMBER), - insert_text: Some(insert_text), - insert_text_format: Some(InsertTextFormat::SNIPPET), - ..Default::default() - }) -} - -/// Computes completions for variants of a given enum. -fn all_variant_completions( - symbols: &Symbols, - mod_ident: &ModuleIdent, - datatype_name: Symbol, -) -> Vec { - let Some(mod_defs) = symbols - .file_mods - .values() - .flatten() - .find(|mdef| mdef.ident == mod_ident.value) - else { - return vec![]; - }; - - let Some(edef) = mod_defs.enums.get(&datatype_name) else { - return vec![]; - }; - - let Some(DefInfo::Enum(.., variants, _)) = symbols.def_info.get(&edef.name_loc) else { - return vec![]; - }; - - variants - .iter() - .filter_map(|vinfo| variant_completion(symbols, vinfo)) - .collect_vec() -} - -/// Computes completions for a given chain entry: `prev_kind` determines the -/// kind of previous chain component, and `chain_kind` contains information -/// about the entity that the whole chain may represent (e.g., a type of or a -/// function). -fn name_chain_entry_completions( - symbols: &Symbols, - cursor: &CursorContext, - info: &AliasAutocompleteInfo, - prev_kind: ChainComponentKind, - chain_kind: ChainCompletionKind, - inside_use: bool, - completions: &mut Vec, -) { - match prev_kind { - ChainComponentKind::Package(leading_name) => { - for mod_ident in pkg_mod_identifiers(symbols, info, &leading_name) { - completions.push(completion_item( - mod_ident.value.module.value().as_str(), - CompletionItemKind::MODULE, - )); - } - } - ChainComponentKind::Module(mod_ident) => { - completions.extend(module_member_completions( - symbols, cursor, &mod_ident, chain_kind, inside_use, - )); - } - ChainComponentKind::Member(mod_ident, member_name) => { - completions.extend(all_variant_completions(symbols, &mod_ident, member_name)); - } - } -} - -/// Computes the kind of the next chain component (based on what the previous -/// one, represented by `prev_kind` was). -fn next_name_chain_component_kind( - symbols: &Symbols, - info: &AliasAutocompleteInfo, - prev_kind: ChainComponentKind, - component_name: Name, -) -> Option { - match prev_kind { - ChainComponentKind::Package(leading_name) => { - pkg_mod_identifiers(symbols, info, &leading_name) - .into_iter() - .find(|mod_ident| mod_ident.value.module.value() == component_name.value) - .map(ChainComponentKind::Module) - } - ChainComponentKind::Module(mod_ident) => { - Some(ChainComponentKind::Member(mod_ident, component_name.value)) - } - ChainComponentKind::Member(_, _) => None, // no more "after" completions to be processed - } -} - -/// Walks down a name chain, looking for the relevant portion that contains the -/// cursor. When it finds, it calls to `name_chain_entry_completions` to compute -/// and return the completions. -fn completions_for_name_chain_entry( - symbols: &Symbols, - cursor: &CursorContext, - info: &AliasAutocompleteInfo, - prev_info: ChainComponentInfo, - chain_kind: ChainCompletionKind, - path_entries: &[Name], - path_index: usize, - colon_colon_triggered: bool, - inside_use: bool, - completions: &mut Vec, -) { - let ChainComponentInfo { - loc: prev_loc, - kind: prev_kind, - } = prev_info; - - let mut at_colon_colon = false; - if path_index == path_entries.len() { - // the only reason we would not return here is if we were at `::` which is past - // the location of the last path component - if colon_colon_triggered && cursor.loc.start() > prev_loc.end() { - at_colon_colon = true; - } else { - return; - } - } - - if !at_colon_colon { - // we are not at the last `::` but we may be at an intermediate one - if colon_colon_triggered - && path_index < path_entries.len() - && cursor.loc.start() > prev_loc.end() - && cursor.loc.end() <= path_entries[path_index].loc.start() - { - at_colon_colon = true; - } - } - - // we are at `::`, or at some component's identifier - if at_colon_colon || path_entries[path_index].loc.contains(&cursor.loc) { - name_chain_entry_completions( - symbols, - cursor, - info, - prev_kind, - chain_kind, - inside_use, - completions, - ); - } else { - let component_name = path_entries[path_index]; - if let Some(next_kind) = - next_name_chain_component_kind(symbols, info, prev_kind, component_name) - { - completions_for_name_chain_entry( - symbols, - cursor, - info, - ChainComponentInfo::new(component_name.loc, next_kind), - chain_kind, - path_entries, - path_index + 1, - colon_colon_triggered, - inside_use, - completions, - ); - } - } -} - -/// Check if a given address represents a package within the current program. -fn is_package_address( - symbols: &Symbols, - info: &AliasAutocompleteInfo, - pkg_addr: NumericalAddress, -) -> bool { - if info.addresses.iter().any(|(_, a)| a == &pkg_addr) { - return true; - } - - symbols.file_mods.values().flatten().any(|mdef| { - matches!(mdef.ident.address, - Address::Numerical { value, .. } if value.value == pkg_addr) - }) -} - -/// Check if a given name represents a package within the current program. -fn is_package_name(symbols: &Symbols, info: &AliasAutocompleteInfo, pkg_name: Name) -> bool { - if info.addresses.contains_key(&pkg_name.value) { - return true; - } - - symbols - .file_mods - .values() - .flatten() - .map(|mdef| &mdef.ident) - .any(|mod_ident| match &mod_ident.address { - Address::NamedUnassigned(name) if name == &pkg_name => true, - Address::Numerical { - name: Some(name), .. - } if name == &pkg_name => true, - _ => false, - }) -} - -/// Get all packages that could be a target of auto-completion, whether they are -/// part of `AliasAutocompleteInfo` or not. -fn all_packages(symbols: &Symbols, info: &AliasAutocompleteInfo) -> BTreeSet { - let mut addresses = BTreeSet::new(); - for (n, a) in &info.addresses { - addresses.insert(n.to_string()); - addresses.insert(a.to_string()); - } - - symbols - .file_mods - .values() - .flatten() - .map(|mdef| &mdef.ident) - .for_each(|mod_ident| match &mod_ident.address { - Address::Numerical { name, value, .. } => { - if let Some(n) = name { - addresses.insert(n.to_string()); - } - addresses.insert(value.to_string()); - } - Address::NamedUnassigned(n) => { - addresses.insert(n.to_string()); - } - }); - - addresses -} - -/// Computes the kind of the fist chain component. -fn first_name_chain_component_kind( - symbols: &Symbols, - info: &AliasAutocompleteInfo, - leading_name: LeadingNameAccess, -) -> Option { - match leading_name.value { - LeadingNameAccess_::Name(n) => { - if is_package_name(symbols, info, n) { - Some(ChainComponentKind::Package(leading_name)) - } else if let Some(mod_ident) = info.modules.get(&n.value) { - Some(ChainComponentKind::Module(*mod_ident)) - } else if let Some((mod_ident, member_name)) = - info.members - .iter() - .find_map(|(alias_name, mod_ident, member_name)| { - if alias_name == &n.value { - Some((*mod_ident, member_name)) - } else { - None - } - }) - { - Some(ChainComponentKind::Member(mod_ident, member_name.value)) - } else { - None - } - } - LeadingNameAccess_::AnonymousAddress(addr) => { - if is_package_address(symbols, info, addr) { - Some(ChainComponentKind::Package(leading_name)) - } else { - None - } - } - LeadingNameAccess_::GlobalAddress(n) => { - // if leading name is global address then the first component can only be a - // package - if is_package_name(symbols, info, n) { - Some(ChainComponentKind::Package(leading_name)) - } else { - None - } - } - } -} - -/// Handle name chain auto-completion at a given position. The gist of this -/// approach is to first identify what the first component of the access chain -/// represents (as it may be a package, module or a member) and if the chain has -/// other components, recursively process them in turn to either -/// - finish auto-completion if cursor is on a given component's identifier -/// - identify what the subsequent component represents and keep going -fn name_chain_completions( - symbols: &Symbols, - cursor: &CursorContext, - colon_colon_triggered: bool, -) -> (Vec, bool) { - eprintln!("looking for name access chains"); - let mut completions = vec![]; - let mut only_custom_items = false; - let Some(ChainInfo { - chain, - kind: chain_kind, - inside_use, - }) = cursor.find_access_chain() - else { - eprintln!("no access chain"); - return (completions, only_custom_items); - }; - - let (leading_name, path_entries) = match &chain.value { - P::NameAccessChain_::Single(entry) => ( - sp(entry.name.loc, LeadingNameAccess_::Name(entry.name)), - vec![], - ), - P::NameAccessChain_::Path(name_path) => ( - name_path.root.name, - name_path.entries.iter().map(|e| e.name).collect::>(), - ), - }; - - // there may be access chains for which there is not auto-completion info - // generated by the compiler but which still have to be handled (e.g., - // chains starting with numeric address) - let info = symbols - .compiler_info - .path_autocomplete_info - .get(&leading_name.loc) - .cloned() - .unwrap_or_else(AliasAutocompleteInfo::new); - - eprintln!( - "found access chain for auto-completion (adddreses: {}, modules: {}, members: {}, tparams: {}", - info.addresses.len(), - info.modules.len(), - info.members.len(), - info.type_params.len() - ); - - // if we are auto-completing for an access chain, there is no need to include - // default completions - only_custom_items = true; - - if leading_name.loc.contains(&cursor.loc) { - // at first position of the chain suggest all packages that are available - // regardless of what the leading name represents, as a package always - // fits at that position, for example: OxCAFE::... - // some_name::... - // ::some_name - // - completions.extend( - all_packages(symbols, &info) - .iter() - .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), - ); - - // only if leading name is actually a name, modules or module members are a - // correct auto-completion in the first position - if let LeadingNameAccess_::Name(_) = &leading_name.value { - completions.extend( - info.modules - .keys() - .map(|n| completion_item(n.as_str(), CompletionItemKind::MODULE)), - ); - completions.extend(all_single_name_member_completions( - symbols, - &info.members, - chain_kind, - )); - if matches!(chain_kind, ChainCompletionKind::Type) { - completions.extend(PRIMITIVE_TYPE_COMPLETIONS.clone()); - completions.extend( - info.type_params - .iter() - .map(|t| completion_item(t.as_str(), CompletionItemKind::TYPE_PARAMETER)), - ); - } - } - } else if let Some(next_kind) = first_name_chain_component_kind(symbols, &info, leading_name) { - completions_for_name_chain_entry( - symbols, - cursor, - &info, - ChainComponentInfo::new(leading_name.loc, next_kind), - chain_kind, - &path_entries, - // path_index - 0, - colon_colon_triggered, - inside_use, - &mut completions, - ); - } - - eprintln!("found {} access chain completions", completions.len()); - - (completions, only_custom_items) -} - -/// Computes auto-completions for module uses. -fn module_use_completions( - symbols: &Symbols, - cursor: &CursorContext, - info: &AliasAutocompleteInfo, - mod_use: &P::ModuleUse, - package: &LeadingNameAccess, - mod_name: &P::ModuleName, -) -> Vec { - use P::ModuleUse as MU; - let mut completions = vec![]; - - let Some(mod_ident) = pkg_mod_identifiers(symbols, info, package) - .into_iter() - .find(|mod_ident| &mod_ident.value.module == mod_name) - else { - return completions; - }; - - match mod_use { - MU::Module(_) => (), // nothing to do with just module alias - MU::Members(members) => { - if let Some((first_name, _)) = members.first() { - if cursor.loc.start() > mod_name.loc().end() - && cursor.loc.end() <= first_name.loc.start() - { - // cursor is after `::` succeeding module but before the first module member - completions.extend(module_member_completions( - symbols, - cursor, - &mod_ident, - ChainCompletionKind::All, - // inside_use - true, - )); - // no point in falling through to the members loop below - return completions; - } - } - - for (sp!(mloc, _), _) in members { - if mloc.contains(&cursor.loc) { - // cursor is at identifier representing module member - completions.extend(module_member_completions( - symbols, - cursor, - &mod_ident, - ChainCompletionKind::All, - // inside_use - true, - )); - // no point checking other locations - break; - } - } - } - MU::Partial { - colon_colon, - opening_brace: _, - } => { - if let Some(colon_colon_loc) = colon_colon { - if cursor.loc.start() >= colon_colon_loc.start() { - // cursor is on or past `::` - completions.extend(module_member_completions( - symbols, - cursor, - &mod_ident, - ChainCompletionKind::All, - // inside_use - true, - )); - } - } - } - } - - completions -} - -/// Handles auto-completions for "regular" `use` declarations (name access -/// chains in `use fun` declarations are handled as part of name chain -/// completions). -fn use_decl_completions(symbols: &Symbols, cursor: &CursorContext) -> (Vec, bool) { - eprintln!("looking for use declarations"); - let mut completions = vec![]; - let mut only_custom_items = false; - let Some(use_) = cursor.find_use_decl() else { - eprintln!("no use declaration"); - return (completions, only_custom_items); - }; - eprintln!("use declaration {:?}", use_); - - // if we are auto-completing for a use decl, there is no need to include default - // completions - only_custom_items = true; - - // there is no auto-completion info generated by the compiler for this but - // helper methods used here are shared with name chain completion where it - // may exist, so we create an "empty" one here - let info = AliasAutocompleteInfo::new(); - - match use_ { - P::Use::ModuleUse(sp!(_, mod_ident), mod_use) => { - if mod_ident.address.loc.contains(&cursor.loc) { - // cursor on package (e.g., on `some_pkg` in `some_pkg::some_mod`) - completions.extend( - all_packages(symbols, &info) - .iter() - .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), - ); - } else if cursor.loc.start() > mod_ident.address.loc.end() - && cursor.loc.end() <= mod_ident.module.loc().end() - { - // cursor is either at the `::` succeeding package/address or at the identifier - // following that particular `::` - for ident in pkg_mod_identifiers(symbols, &info, &mod_ident.address) { - completions.push(completion_item( - ident.value.module.value().as_str(), - CompletionItemKind::MODULE, - )); - } - } else { - completions.extend(module_use_completions( - symbols, - cursor, - &info, - &mod_use, - &mod_ident.address, - &mod_ident.module, - )); - } - } - P::Use::NestedModuleUses(leading_name, uses) => { - if leading_name.loc.contains(&cursor.loc) { - // cursor on package - completions.extend( - all_packages(symbols, &info) - .iter() - .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), - ); - } else { - if let Some((first_name, _)) = uses.first() { - if cursor.loc.start() > leading_name.loc.end() - && cursor.loc.end() <= first_name.loc().start() - { - // cursor is after `::` succeeding address/package but before the first - // module - for ident in pkg_mod_identifiers(symbols, &info, &leading_name) { - completions.push(completion_item( - ident.value.module.value().as_str(), - CompletionItemKind::MODULE, - )); - } - // no point in falling through to the uses loop below - return (completions, only_custom_items); - } - } - - for (mod_name, mod_use) in &uses { - if mod_name.loc().contains(&cursor.loc) { - for ident in pkg_mod_identifiers(symbols, &info, &leading_name) { - completions.push(completion_item( - ident.value.module.value().as_str(), - CompletionItemKind::MODULE, - )); - } - // no point checking other locations - break; - } - completions.extend(module_use_completions( - symbols, - cursor, - &info, - mod_use, - &leading_name, - mod_name, - )); - } - } - } - P::Use::Fun { .. } => (), // already handled as part of name chain completion - P::Use::Partial { - package, - colon_colon, - opening_brace: _, - } => { - if package.loc.contains(&cursor.loc) { - // cursor on package name/address - completions.extend( - all_packages(symbols, &info) - .iter() - .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), - ); - } - if let Some(colon_colon_loc) = colon_colon { - if cursor.loc.start() >= colon_colon_loc.start() { - // cursor is on or past `::` - for ident in pkg_mod_identifiers(symbols, &info, &package) { - completions.push(completion_item( - ident.value.module.value().as_str(), - CompletionItemKind::MODULE, - )); - } - } - } - } - } - - (completions, only_custom_items) -} - -/// Handle context-specific auto-completion requests with no trigger character. -fn context_specific_no_trigger( - symbols: &Symbols, - use_fpath: &Path, - buffer: &str, - position: &Position, -) -> (Vec, bool) { - eprintln!("looking for dot"); - let mut completions = dot_completions(symbols, use_fpath, position); - eprintln!("dot found: {}", !completions.is_empty()); - if !completions.is_empty() { - // found dot completions - do not look for any other - return (completions, true); - } - - let mut only_custom_items = false; - - let strings = preceding_strings(buffer, position); - - if strings.is_empty() { - return (completions, only_custom_items); - } - - // at this point only try to auto-complete init function declararation - get the - // last string and see if it represents the beginning of init function - // declaration - const INIT_FN_NAME: &str = "init"; - let (n, use_col) = strings.last().unwrap(); - for u in symbols.line_uses(use_fpath, position.line) { - if *use_col >= u.col_start() && *use_col <= u.col_end() { - let def_loc = u.def_loc(); - let Some(use_file_mod_definition) = symbols.file_mods.get(use_fpath) else { - break; - }; - let Some(use_file_mod_def) = use_file_mod_definition.first() else { - break; - }; - if is_definition( - symbols, - position.line, - u.col_start(), - use_file_mod_def.fhash(), - def_loc, - ) { - // since it's a definition, there is no point in trying to suggest a name - // if one is about to create a fresh identifier - only_custom_items = true; - } - let Some(def_info) = symbols.def_info(&def_loc) else { - break; - }; - let DefInfo::Function(mod_ident, v, ..) = def_info else { - // not a function - break; - }; - if !INIT_FN_NAME.starts_with(n) { - // starting to type "init" - break; - } - if !matches!(v, Visibility::Internal) { - // private (otherwise perhaps it's "init_something") - break; - } - - // get module info containing the init function - let Some(mdef) = symbols.mod_defs(&u.def_loc().file_hash(), *mod_ident) else { - break; - }; - - if mdef.functions().contains_key(&(INIT_FN_NAME.into())) { - // already has init function - break; - } - - let iota_ctx_arg = "ctx: &mut TxContext"; - - // decide on the list of parameters depending on whether a module containing - // the init function has a struct thats an one-time-witness candidate struct - let otw_candidate = Symbol::from(mod_ident.module.value().to_uppercase()); - let init_snippet = if mdef.structs().contains_key(&otw_candidate) { - format!( - "{INIT_FN_NAME}(${{1:witness}}: {otw_candidate}, {iota_ctx_arg}) {{\n\t${{2:}}\n}}\n" - ) - } else { - format!("{INIT_FN_NAME}({iota_ctx_arg}) {{\n\t${{1:}}\n}}\n") - }; - - let init_completion = CompletionItem { - label: INIT_FN_NAME.to_string(), - kind: Some(CompletionItemKind::SNIPPET), - documentation: Some(Documentation::String( - "Module initializer snippet".to_string(), - )), - insert_text: Some(init_snippet), - insert_text_format: Some(InsertTextFormat::SNIPPET), - ..Default::default() - }; - completions.push(init_completion); - break; - } - } - (completions, only_custom_items) -} - -/// Checks if a use at a given position is also a definition. -fn is_definition( - symbols: &Symbols, - use_line: u32, - use_col: u32, - use_fhash: FileHash, - def_loc: Loc, -) -> bool { - if let Some(use_loc) = symbols - .files - .line_char_offset_to_loc_opt(use_fhash, use_line, use_col) - { - // TODO: is overlapping better? - def_loc.contains(&use_loc) - } else { - false - } -} - -/// Finds white-space separated strings on the line containing auto-completion -/// request and their locations. -fn preceding_strings(buffer: &str, position: &Position) -> Vec<(String, u32)> { - let mut strings = vec![]; - let line = match buffer.lines().nth(position.line as usize) { - Some(line) => line, - None => return strings, // Our buffer does not contain the line, and so must be out of date. - }; - - let mut chars = line.chars(); - let mut cur_col = 0; - let mut cur_str_start = 0; - let mut cur_str = "".to_string(); - while cur_col <= position.character { - let Some(c) = chars.next() else { - return strings; - }; - if c == ' ' || c == '\t' { - if !cur_str.is_empty() { - // finish an already started string - strings.push((cur_str, cur_str_start)); - cur_str = "".to_string(); - } - } else { - if cur_str.is_empty() { - // start a new string - cur_str_start = cur_col; - } - cur_str.push(c); - } - - cur_col += c.len_utf8() as u32; - } - if !cur_str.is_empty() { - // finish the last string - strings.push((cur_str, cur_str_start)); - } - strings -} - -/// Sends the given connection a response to a completion request. -/// -/// The completions returned depend upon where the user's cursor is positioned. -pub fn on_completion_request( - context: &Context, - request: &Request, - ide_files_root: VfsPath, - pkg_dependencies: Arc>>, -) { - eprintln!("handling completion request"); - let parameters = serde_json::from_value::(request.params.clone()) - .expect("could not deserialize completion request"); - - let path = parameters - .text_document_position - .text_document - .uri - .to_file_path() - .unwrap(); - - let mut pos = parameters.text_document_position.position; - if pos.character != 0 { - // adjust column to be at the character that has just been inserted rather than - // right after it (unless we are at the very first column) - pos = Position::new(pos.line, pos.character - 1); - } - let items = completions_with_context(context, ide_files_root, pkg_dependencies, &path, pos) - .unwrap_or_default(); - let items_len = items.len(); - - let result = serde_json::to_value(items).expect("could not serialize completion response"); - eprintln!("about to send completion response with {items_len} items"); - let response = lsp_server::Response::new_ok(request.id.clone(), result); - if let Err(err) = context - .connection - .sender - .send(lsp_server::Message::Response(response)) - { - eprintln!("could not send completion response: {:?}", err); - } -} - -pub fn completions_with_context( - context: &Context, - ide_files_root: VfsPath, - pkg_dependencies: Arc>>, - path: &Path, - pos: Position, -) -> Option> { - let Some(pkg_path) = SymbolicatorRunner::root_dir(path) else { - eprintln!("failed completion for {:?} (package root not found)", path); - return None; - }; - let symbol_map = context.symbols.lock().unwrap(); - let current_symbols = symbol_map.get(&pkg_path)?; - Some(completion_items( - current_symbols, - ide_files_root, - pkg_dependencies, - path, - pos, - )) -} - -pub fn completion_items( - current_symbols: &Symbols, - ide_files_root: VfsPath, - pkg_dependencies: Arc>>, - path: &Path, - pos: Position, -) -> Vec { - compute_cursor_completion_items(ide_files_root, pkg_dependencies, path, pos) - .unwrap_or_else(|| compute_completion_items(current_symbols, path, pos)) -} - -fn compute_cursor_completion_items( - ide_files_root: VfsPath, - pkg_dependencies: Arc>>, - path: &Path, - cursor_position: Position, -) -> Option> { - let Some(pkg_path) = SymbolicatorRunner::root_dir(path) else { - eprintln!("failed completion for {:?} (package root not found)", path); - return None; - }; - let cursor_path = path.to_path_buf(); - let cursor_info = Some((&cursor_path, cursor_position)); - let (symbols, _diags) = symbols::get_symbols( - pkg_dependencies, - ide_files_root, - &pkg_path, - LintLevel::None, - cursor_info, - ) - .ok()?; - let symbols = symbols?; - Some(compute_completion_items(&symbols, path, cursor_position)) -} - -/// Computes completion items for a given completion request. -fn compute_completion_items(symbols: &Symbols, path: &Path, pos: Position) -> Vec { - let mut items = vec![]; - - let Some(fhash) = symbols.file_hash(path) else { - return items; - }; - let Some(file_id) = symbols.files.file_mapping().get(&fhash) else { - return items; - }; - let Ok(file) = symbols.files.files().get(*file_id) else { - return items; - }; - - let file_source = file.source().clone(); - if !file_source.is_empty() { - let only_custom_items; - match &symbols.cursor_context { - Some(cursor_context) => { - eprintln!("cursor completion"); - let (new_items, only_has_custom_items) = - cursor_completion_items(symbols, path, &file_source, pos, cursor_context); - only_custom_items = only_has_custom_items; - items.extend(new_items); - } - None => { - eprintln!("non-cursor completion"); - let (new_items, only_has_custom_items) = - default_items(symbols, path, &file_source, pos); - only_custom_items = only_has_custom_items; - items.extend(new_items); - } - } - if !only_custom_items { - eprintln!("including identifiers"); - let identifiers = identifiers(&file_source, symbols, path); - items.extend(identifiers); - } - } else { - // no file content - items.extend(KEYWORD_COMPLETIONS.clone()); - items.extend(BUILTIN_COMPLETIONS.clone()); - } - items -} - -/// Return completion items, plus a flag indicating if we should only use the -/// custom items returned (i.e., when the flag is false, default items and -/// identifiers should also be added). -fn cursor_completion_items( - symbols: &Symbols, - path: &Path, - file_source: &str, - pos: Position, - cursor: &CursorContext, -) -> (Vec, bool) { - let cursor_leader = get_cursor_token(file_source, &pos); - match cursor_leader { - // TODO: consider using `cursor.position` for this instead - Some(Tok::Period) => { - eprintln!("found period"); - let items = dot_completions(symbols, path, &pos); - let items_is_empty = items.is_empty(); - eprintln!("found items: {}", !items_is_empty); - // whether completions have been found for the dot or not - // it makes no sense to try offering "dumb" autocompletion - // options here as they will not fit (an example would - // be dot completion of u64 variable without any methods - // with u64 receiver being visible) - (items, true) - } - Some(Tok::ColonColon) => { - let mut items = vec![]; - let mut only_custom_items = false; - let (path_items, path_custom) = - name_chain_completions(symbols, cursor, /* colon_colon_triggered */ true); - items.extend(path_items); - only_custom_items |= path_custom; - if !only_custom_items { - let (path_items, path_custom) = use_decl_completions(symbols, cursor); - items.extend(path_items); - only_custom_items |= path_custom; - } - (items, only_custom_items) - } - // Carve out to suggest UID for struct with key ability - Some(Tok::LBrace) => { - let mut items = vec![]; - let mut only_custom_items = false; - let (path_items, path_custom) = context_specific_lbrace(symbols, cursor); - items.extend(path_items); - only_custom_items |= path_custom; - if !only_custom_items { - let (path_items, path_custom) = use_decl_completions(symbols, cursor); - items.extend(path_items); - only_custom_items |= path_custom; - } - (items, only_custom_items) - } - // TODO: should we handle auto-completion on `:`? If we model our support after - // rust-analyzer then it does not do this - it starts auto-completing types after the first - // character beyond `:` is typed - _ => { - eprintln!("no relevant cursor leader"); - let mut items = vec![]; - let mut only_custom_items = false; - let (path_items, path_custom) = - name_chain_completions(symbols, cursor, /* colon_colon_triggered */ false); - items.extend(path_items); - only_custom_items |= path_custom; - if !only_custom_items { - if matches!(cursor_leader, Some(Tok::Colon)) { - // much like rust-analyzer we do not auto-complete in the middle of `::` - only_custom_items = true; - } else { - let (path_items, path_custom) = use_decl_completions(symbols, cursor); - items.extend(path_items); - only_custom_items |= path_custom; - } - } - if !only_custom_items { - eprintln!("checking default items"); - let (default_items, default_custom) = - default_items(symbols, path, file_source, pos); - items.extend(default_items); - only_custom_items |= default_custom; - } - (items, only_custom_items) - } - } -} - -fn default_items( - symbols: &Symbols, - path: &Path, - file_source: &str, - pos: Position, -) -> (Vec, bool) { - // If the user's cursor is positioned anywhere other than following a `.`, `:`, - // or `::`, offer them context-specific autocompletion items as well as - // Move's keywords, operators, and builtins. - let (custom_items, only_custom_items) = - context_specific_no_trigger(symbols, path, file_source, &pos); - let mut items = custom_items; - if !only_custom_items { - items.extend(KEYWORD_COMPLETIONS.clone()); - items.extend(BUILTIN_COMPLETIONS.clone()); - } - (items, only_custom_items) -} diff --git a/external-crates/move/crates/move-analyzer/src/completions/dot.rs b/external-crates/move/crates/move-analyzer/src/completions/dot.rs new file mode 100644 index 00000000000..d16bffcd761 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/src/completions/dot.rs @@ -0,0 +1,116 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// Auto-completion for the dot operator, e.g., `struct.` or `value.foo()`.` + +use crate::{ + completions::utils::{call_completion_item, mod_defs}, + symbols::{type_to_ide_string, DefInfo, FunType, Symbols}, + utils::lsp_position_to_loc, +}; +use lsp_types::{ + CompletionItem, CompletionItemKind, CompletionItemLabelDetails, InsertTextFormat, Position, +}; +use move_compiler::{ + expansion::ast::ModuleIdent_, + shared::{ide::AutocompleteMethod, Identifier}, +}; +use move_symbol_pool::Symbol; + +use std::path::Path; + +/// Handle "dot" auto-completion at a given position. +pub fn dot_completions( + symbols: &Symbols, + use_fpath: &Path, + position: &Position, +) -> (Vec, bool) { + let mut completions = vec![]; + let mut completion_finalized = false; + let Some(fhash) = symbols.file_hash(use_fpath) else { + eprintln!("no dot completions due to missing file"); + return (completions, completion_finalized); + }; + let Some(loc) = lsp_position_to_loc(&symbols.files, fhash, position) else { + eprintln!("no dot completions due to missing loc"); + return (completions, completion_finalized); + }; + let Some(info) = symbols.compiler_info.get_autocomplete_info(fhash, &loc) else { + return (completions, completion_finalized); + }; + // we found auto-completion info, so don't look for any more completions + // even if if it does not contain any + completion_finalized = true; + for AutocompleteMethod { + method_name, + target_function: (mod_ident, function_name), + } in &info.methods + { + let call_completion = if let Some(DefInfo::Function( + .., + fun_type, + _, + type_args, + arg_names, + arg_types, + ret_type, + _, + )) = fun_def_info(symbols, mod_ident.value, function_name.value()) + { + call_completion_item( + &mod_ident.value, + matches!(fun_type, FunType::Macro), + Some(method_name), + &function_name.value(), + type_args, + arg_names, + arg_types, + ret_type, + /* inside_use */ false, + ) + } else { + // this shouldn't really happen as we should be able to get + // `DefInfo` for a function but if for some reason we cannot, + // let's generate simpler autotompletion value + eprintln!("incomplete dot item"); + CompletionItem { + label: format!("{method_name}()"), + kind: Some(CompletionItemKind::METHOD), + insert_text: Some(method_name.to_string()), + insert_text_format: Some(InsertTextFormat::PLAIN_TEXT), + ..Default::default() + } + }; + completions.push(call_completion); + } + for (n, t) in &info.fields { + let label_details = Some(CompletionItemLabelDetails { + detail: None, + description: Some(type_to_ide_string(t, /* verbose */ false)), + }); + let init_completion = CompletionItem { + label: n.to_string(), + label_details, + kind: Some(CompletionItemKind::FIELD), + insert_text: Some(n.to_string()), + insert_text_format: Some(InsertTextFormat::PLAIN_TEXT), + ..Default::default() + }; + completions.push(init_completion); + } + + (completions, completion_finalized) +} + +/// Get the `DefInfo` for a function definition. +fn fun_def_info(symbols: &Symbols, mod_ident: ModuleIdent_, name: Symbol) -> Option<&DefInfo> { + let Some(mod_defs) = mod_defs(symbols, &mod_ident) else { + return None; + }; + + let Some(fdef) = mod_defs.functions.get(&name) else { + return None; + }; + symbols.def_info(&fdef.name_loc) +} diff --git a/external-crates/move/crates/move-analyzer/src/completions/mod.rs b/external-crates/move/crates/move-analyzer/src/completions/mod.rs new file mode 100644 index 00000000000..3ef739fc910 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/src/completions/mod.rs @@ -0,0 +1,430 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + completions::{ + dot::dot_completions, + name_chain::{name_chain_completions, use_decl_completions}, + snippets::{init_completion, object_completion}, + utils::{completion_item, PRIMITIVE_TYPE_COMPLETIONS}, + }, + context::Context, + symbols::{self, CursorContext, PrecomputedPkgDepsInfo, SymbolicatorRunner, Symbols}, +}; +use lsp_server::Request; +use lsp_types::{CompletionItem, CompletionItemKind, CompletionParams, Position}; +use move_command_line_common::files::FileHash; +use move_compiler::{ + editions::Edition, + linters::LintLevel, + parser::{ + keywords::{BUILTINS, CONTEXTUAL_KEYWORDS, KEYWORDS, PRIMITIVE_TYPES}, + lexer::{Lexer, Tok}, + }, +}; +use move_symbol_pool::Symbol; + +use once_cell::sync::Lazy; + +use std::{ + collections::{BTreeMap, HashSet}, + path::{Path, PathBuf}, + sync::{Arc, Mutex}, +}; +use vfs::VfsPath; + +mod dot; +mod name_chain; +mod snippets; +mod utils; + +/// List of completion items corresponding to each one of Move's keywords. +/// +/// Currently, this does not filter keywords out based on whether they are valid at the completion +/// request's cursor position, but in the future it ought to. For example, this function returns +/// all specification language keywords, but in the future it should be modified to only do so +/// within a spec block. +static KEYWORD_COMPLETIONS: Lazy> = Lazy::new(|| { + let mut keywords = KEYWORDS + .iter() + .chain(CONTEXTUAL_KEYWORDS.iter()) + .chain(PRIMITIVE_TYPES.iter()) + .map(|label| { + let kind = if label == &"copy" || label == &"move" { + CompletionItemKind::OPERATOR + } else { + CompletionItemKind::KEYWORD + }; + completion_item(label, kind) + }) + .collect::>(); + keywords.extend(PRIMITIVE_TYPE_COMPLETIONS.clone()); + keywords +}); + +/// List of completion items corresponding to each one of Move's builtin functions. +static BUILTIN_COMPLETIONS: Lazy> = Lazy::new(|| { + BUILTINS + .iter() + .map(|label| completion_item(label, CompletionItemKind::FUNCTION)) + .collect() +}); + +/// Sends the given connection a response to a completion request. +/// +/// The completions returned depend upon where the user's cursor is positioned. +pub fn on_completion_request( + context: &Context, + request: &Request, + ide_files_root: VfsPath, + pkg_dependencies: Arc>>, +) { + eprintln!("handling completion request"); + let parameters = serde_json::from_value::(request.params.clone()) + .expect("could not deserialize completion request"); + + let path = parameters + .text_document_position + .text_document + .uri + .to_file_path() + .unwrap(); + + let mut pos = parameters.text_document_position.position; + if pos.character != 0 { + // adjust column to be at the character that has just been inserted rather than right after + // it (unless we are at the very first column) + pos = Position::new(pos.line, pos.character - 1); + } + let completions = + completions(context, ide_files_root, pkg_dependencies, &path, pos).unwrap_or_default(); + let completions_len = completions.len(); + + let result = + serde_json::to_value(completions).expect("could not serialize completion response"); + eprintln!("about to send completion response with {completions_len} items"); + let response = lsp_server::Response::new_ok(request.id.clone(), result); + if let Err(err) = context + .connection + .sender + .send(lsp_server::Message::Response(response)) + { + eprintln!("could not send completion response: {:?}", err); + } +} + +/// Computes a list of auto-completions for a given position in a file, +/// given the current context. +fn completions( + context: &Context, + ide_files_root: VfsPath, + pkg_dependencies: Arc>>, + path: &Path, + pos: Position, +) -> Option> { + let Some(pkg_path) = SymbolicatorRunner::root_dir(path) else { + eprintln!("failed completion for {:?} (package root not found)", path); + return None; + }; + let symbol_map = context.symbols.lock().unwrap(); + let current_symbols = symbol_map.get(&pkg_path)?; + Some(compute_completions( + current_symbols, + ide_files_root, + pkg_dependencies, + path, + pos, + )) +} + +/// Computes a list of auto-completions for a given position in a file, +/// based on the current symbols. +pub fn compute_completions( + current_symbols: &Symbols, + ide_files_root: VfsPath, + pkg_dependencies: Arc>>, + path: &Path, + pos: Position, +) -> Vec { + compute_completions_new_symbols(ide_files_root, pkg_dependencies, path, pos) + .unwrap_or_else(|| compute_completions_with_symbols(current_symbols, path, pos)) +} + +/// Computes a list of auto-completions for a given position in a file, +/// after attempting to re-compute the symbols to get the most up-to-date +/// view of the code (returns `None` if the symbols could not be re-computed). +fn compute_completions_new_symbols( + ide_files_root: VfsPath, + pkg_dependencies: Arc>>, + path: &Path, + cursor_position: Position, +) -> Option> { + let Some(pkg_path) = SymbolicatorRunner::root_dir(path) else { + eprintln!("failed completion for {:?} (package root not found)", path); + return None; + }; + let cursor_path = path.to_path_buf(); + let cursor_info = Some((&cursor_path, cursor_position)); + let (symbols, _diags) = symbols::get_symbols( + pkg_dependencies, + ide_files_root, + &pkg_path, + LintLevel::None, + cursor_info, + ) + .ok()?; + let symbols = symbols?; + Some(compute_completions_with_symbols( + &symbols, + path, + cursor_position, + )) +} + +/// Computes a list of auto-completions for a given position in a file +/// using the symbols provided as argument. +pub fn compute_completions_with_symbols( + symbols: &Symbols, + path: &Path, + pos: Position, +) -> Vec { + let mut completions = vec![]; + + let Some(fhash) = symbols.file_hash(path) else { + return completions; + }; + let Some(file_id) = symbols.files.file_mapping().get(&fhash) else { + return completions; + }; + let Ok(file) = symbols.files.files().get(*file_id) else { + return completions; + }; + + let file_source = file.source().clone(); + if !file_source.is_empty() { + let completion_finalized; + match &symbols.cursor_context { + Some(cursor_context) => { + eprintln!("cursor completion"); + let (cursor_completions, cursor_finalized) = + cursor_completion_items(symbols, path, &file_source, pos, cursor_context); + completion_finalized = cursor_finalized; + completions.extend(cursor_completions); + } + None => { + eprintln!("non-cursor completion"); + let (no_cursor_completions, no_cursor_finalized) = + no_cursor_completion_items(symbols, path, &file_source, pos); + completion_finalized = no_cursor_finalized; + completions.extend(no_cursor_completions); + } + } + if !completion_finalized { + eprintln!("including identifiers"); + let identifiers = identifiers(&file_source, symbols, path); + completions.extend(identifiers); + } + } else { + // no file content + completions.extend(KEYWORD_COMPLETIONS.clone()); + completions.extend(BUILTIN_COMPLETIONS.clone()); + } + completions +} + +/// Return completion items in case cursor is available plus a flag indicating +/// if we should continue searching for more completions. +fn cursor_completion_items( + symbols: &Symbols, + path: &Path, + file_source: &str, + pos: Position, + cursor: &CursorContext, +) -> (Vec, bool) { + let cursor_leader = get_cursor_token(file_source, &pos); + match cursor_leader { + // TODO: consider using `cursor.position` for this instead + Some(Tok::Period) => dot_completions(symbols, path, &pos), + Some(Tok::ColonColon) => { + let mut completions = vec![]; + let mut completion_finalized = false; + let (name_chain_completions, name_chain_finalized) = + name_chain_completions(symbols, cursor, /* colon_colon_triggered */ true); + completions.extend(name_chain_completions); + completion_finalized |= name_chain_finalized; + if !completion_finalized { + let (use_decl_completions, use_decl_finalized) = + use_decl_completions(symbols, cursor); + completions.extend(use_decl_completions); + completion_finalized |= use_decl_finalized; + } + (completions, completion_finalized) + } + // Carve out to suggest UID for struct with key ability + Some(Tok::LBrace) => { + let mut completions = vec![]; + let mut completion_finalized = false; + let (custom_completions, custom_finalized) = lbrace_cursor_completions(symbols, cursor); + completions.extend(custom_completions); + completion_finalized |= custom_finalized; + if !completion_finalized { + let (use_decl_completions, _) = use_decl_completions(symbols, cursor); + completions.extend(use_decl_completions); + } + // do not offer default completions after `{` as this may get annoying + // when simply starting a body of a function and hitting enter triggers + // auto-completion of an essentially random identifier + (completions, true) + } + // TODO: should we handle auto-completion on `:`? If we model our support after + // rust-analyzer then it does not do this - it starts auto-completing types after the first + // character beyond `:` is typed + _ => { + eprintln!("no relevant cursor leader"); + let mut completions = vec![]; + let mut completion_finalized = false; + let (name_chain_completions, name_chain_finalized) = + name_chain_completions(symbols, cursor, /* colon_colon_triggered */ false); + completions.extend(name_chain_completions); + completion_finalized |= name_chain_finalized; + if !completion_finalized { + if matches!(cursor_leader, Some(Tok::Colon)) { + // much like rust-analyzer we do not auto-complete in the middle of `::` + completion_finalized = true; + } else { + let (use_decl_completions, use_decl_finalized) = + use_decl_completions(symbols, cursor); + completions.extend(use_decl_completions); + completion_finalized |= use_decl_finalized; + } + } + if !completion_finalized { + eprintln!("checking default items"); + let (default_completions, default_finalized) = + no_cursor_completion_items(symbols, path, file_source, pos); + completions.extend(default_completions); + completion_finalized |= default_finalized; + } + (completions, completion_finalized) + } + } +} + +/// Returns the token corresponding to the "trigger character" if it is one of `.`, `:`, '{', or +/// `::`. Otherwise, returns `None` (position points at the potential trigger character itself). +fn get_cursor_token(buffer: &str, position: &Position) -> Option { + let line = match buffer.lines().nth(position.line as usize) { + Some(line) => line, + None => return None, // Our buffer does not contain the line, and so must be out of date. + }; + match line.chars().nth(position.character as usize) { + Some('.') => Some(Tok::Period), + Some(':') => { + if position.character > 0 + && line.chars().nth(position.character as usize - 1) == Some(':') + { + Some(Tok::ColonColon) + } else { + Some(Tok::Colon) + } + } + Some('{') => Some(Tok::LBrace), + _ => None, + } +} + +/// Handle auto-completion requests with lbrace (`{`) trigger character +/// when cursor is available. +fn lbrace_cursor_completions( + symbols: &Symbols, + cursor: &CursorContext, +) -> (Vec, bool) { + let completions = vec![]; + let (completion_item_opt, completion_finalized) = object_completion(symbols, cursor); + if let Some(completion_item) = completion_item_opt { + return (vec![completion_item], completion_finalized); + } + (completions, completion_finalized) +} + +/// Return completion items no cursor is available plus a flag indicating +/// if we should continue searching for more completions. +fn no_cursor_completion_items( + symbols: &Symbols, + path: &Path, + file_source: &str, + pos: Position, +) -> (Vec, bool) { + // If the user's cursor is positioned anywhere other than following a `.`, `:`, or `::`, + // offer them context-specific autocompletion items and, if needed, + // Move's keywords, and builtins. + let (mut completions, mut completion_finalized) = dot_completions(symbols, path, &pos); + if !completion_finalized { + let (init_completions, init_finalized) = init_completion(symbols, path, file_source, &pos); + completions.extend(init_completions); + completion_finalized |= init_finalized; + } + + if !completion_finalized { + completions.extend(KEYWORD_COMPLETIONS.clone()); + completions.extend(BUILTIN_COMPLETIONS.clone()); + } + (completions, true) +} + +/// Lexes the Move source file at the given path and returns a list of completion items +/// corresponding to the non-keyword identifiers therein. +/// +/// Currently, this does not perform semantic analysis to determine whether the identifiers +/// returned are valid at the request's cursor position. However, this list of identifiers is akin +/// to what editors like Visual Studio Code would provide as completion items if this language +/// server did not initialize with a response indicating it's capable of providing completions. In +/// the future, the server should be modified to return semantically valid completion items, not +/// simple textual suggestions. +fn identifiers(buffer: &str, symbols: &Symbols, path: &Path) -> Vec { + // TODO thread through package configs + let mut lexer = Lexer::new(buffer, FileHash::new(buffer), Edition::LEGACY); + if lexer.advance().is_err() { + return vec![]; + } + let mut ids = HashSet::new(); + while lexer.peek() != Tok::EOF { + // Some tokens, such as "phantom", are contextual keywords that are only reserved in + // certain contexts. Since for now this language server doesn't analyze semantic context, + // tokens such as "phantom" are always present in keyword suggestions. To avoid displaying + // these keywords to the user twice in the case that the token "phantom" is present in the + // source program (once as a keyword, and once as an identifier), we filter out any + // identifier token that has the same text as a keyword. + if lexer.peek() == Tok::Identifier && !KEYWORDS.contains(&lexer.content()) { + // The completion item kind "text" indicates the item is not based on any semantic + // context of the request cursor's position. + ids.insert(lexer.content()); + } + if lexer.advance().is_err() { + break; + } + } + + let mods_opt = symbols.file_mods.get(path); + + // The completion item kind "text" indicates that the item is based on simple textual matching, + // not any deeper semantic analysis. + ids.iter() + .map(|label| { + if let Some(mods) = mods_opt { + if mods + .iter() + .any(|m| m.functions().contains_key(&Symbol::from(*label))) + { + completion_item(label, CompletionItemKind::FUNCTION) + } else { + completion_item(label, CompletionItemKind::TEXT) + } + } else { + completion_item(label, CompletionItemKind::TEXT) + } + }) + .collect() +} diff --git a/external-crates/move/crates/move-analyzer/src/completions/name_chain.rs b/external-crates/move/crates/move-analyzer/src/completions/name_chain.rs new file mode 100644 index 00000000000..3a84034c629 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/src/completions/name_chain.rs @@ -0,0 +1,997 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// Auto-completions for name chains, such as `mod::struct::field` or `mod::function`, +// both in the code (e.g., types) and in `use` statements. + +use crate::{ + completions::utils::{ + call_completion_item, completion_item, mod_defs, PRIMITIVE_TYPE_COMPLETIONS, + }, + symbols::{ + expansion_mod_ident_to_map_key, ChainCompletionKind, ChainInfo, CursorContext, DefInfo, + FunType, MemberDef, MemberDefInfo, Symbols, VariantInfo, + }, +}; +use itertools::Itertools; +use lsp_types::{CompletionItem, CompletionItemKind, InsertTextFormat}; +use move_compiler::{ + expansion::ast::{Address, ModuleIdent, ModuleIdent_, Visibility}, + parser::ast as P, + shared::{ide::AliasAutocompleteInfo, Identifier, Name, NumericalAddress}, +}; +use move_ir_types::location::{sp, Loc}; +use move_symbol_pool::Symbol; +use std::collections::BTreeSet; + +/// Describes kind of the name access chain component. +enum ChainComponentKind { + Package(P::LeadingNameAccess), + Module(ModuleIdent), + Member(ModuleIdent, Symbol), +} + +/// Information about access chain component - its location and kind. +struct ChainComponentInfo { + loc: Loc, + kind: ChainComponentKind, +} + +impl ChainComponentInfo { + fn new(loc: Loc, kind: ChainComponentKind) -> Self { + Self { loc, kind } + } +} + +/// Handle name chain auto-completion at a given position. The gist of this approach is to first +/// identify what the first component of the access chain represents (as it may be a package, module +/// or a member) and if the chain has other components, recursively process them in turn to either +/// - finish auto-completion if cursor is on a given component's identifier +/// - identify what the subsequent component represents and keep going +pub fn name_chain_completions( + symbols: &Symbols, + cursor: &CursorContext, + colon_colon_triggered: bool, +) -> (Vec, bool) { + eprintln!("looking for name access chains"); + let mut completions = vec![]; + let mut completion_finalized = false; + let Some(ChainInfo { + chain, + kind: chain_kind, + inside_use, + }) = cursor.find_access_chain() + else { + eprintln!("no access chain"); + return (completions, completion_finalized); + }; + + let (leading_name, path_entries) = match &chain.value { + P::NameAccessChain_::Single(entry) => ( + sp(entry.name.loc, P::LeadingNameAccess_::Name(entry.name)), + vec![], + ), + P::NameAccessChain_::Path(name_path) => ( + name_path.root.name, + name_path.entries.iter().map(|e| e.name).collect::>(), + ), + }; + + // there may be access chains for which there is not auto-completion info generated by the + // compiler but which still have to be handled (e.g., chains starting with numeric address) + let info = symbols + .compiler_info + .path_autocomplete_info + .get(&leading_name.loc) + .cloned() + .unwrap_or_else(AliasAutocompleteInfo::new); + + eprintln!("found access chain for auto-completion (adddreses: {}, modules: {}, members: {}, tparams: {}", + info.addresses.len(), info.modules.len(), info.members.len(), info.type_params.len()); + + // if we are auto-completing for an access chain, there is no need to include default completions + completion_finalized = true; + + if leading_name.loc.contains(&cursor.loc) { + // at first position of the chain suggest all packages that are available regardless of what + // the leading name represents, as a package always fits at that position, for example: + // OxCAFE::... + // some_name::... + // ::some_name + // + completions.extend( + all_packages(symbols, &info) + .iter() + .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), + ); + + // only if leading name is actually a name, modules or module members are a correct + // auto-completion in the first position + if let P::LeadingNameAccess_::Name(_) = &leading_name.value { + completions.extend( + info.modules + .keys() + .map(|n| completion_item(n.as_str(), CompletionItemKind::MODULE)), + ); + completions.extend(all_single_name_member_completions( + symbols, + cursor, + &info.members, + chain_kind, + )); + if matches!(chain_kind, ChainCompletionKind::Type) { + completions.extend(PRIMITIVE_TYPE_COMPLETIONS.clone()); + completions.extend( + info.type_params + .iter() + .map(|t| completion_item(t.as_str(), CompletionItemKind::TYPE_PARAMETER)), + ); + } + } + } else if let Some(next_kind) = first_name_chain_component_kind(symbols, &info, leading_name) { + completions_for_name_chain_entry( + symbols, + cursor, + &info, + ChainComponentInfo::new(leading_name.loc, next_kind), + chain_kind, + &path_entries, + /* path_index */ 0, + colon_colon_triggered, + inside_use, + &mut completions, + ); + } + + eprintln!("found {} access chain completions", completions.len()); + + (completions, completion_finalized) +} + +/// Handles auto-completions for "regular" `use` declarations (name access chains in `use fun` +/// declarations are handled as part of name chain completions). +pub fn use_decl_completions( + symbols: &Symbols, + cursor: &CursorContext, +) -> (Vec, bool) { + eprintln!("looking for use declarations"); + let mut completions = vec![]; + let mut completion_finalized = false; + let Some(use_) = cursor.find_use_decl() else { + eprintln!("no use declaration"); + return (completions, completion_finalized); + }; + eprintln!("use declaration {:?}", use_); + + // if we are auto-completing for a use decl, there is no need to include default completions + completion_finalized = true; + + // there is no auto-completion info generated by the compiler for this but helper methods used + // here are shared with name chain completion where it may exist, so we create an "empty" one + // here + let info = AliasAutocompleteInfo::new(); + + match use_ { + P::Use::ModuleUse(sp!(_, mod_ident), mod_use) => { + if mod_ident.address.loc.contains(&cursor.loc) { + // cursor on package (e.g., on `some_pkg` in `some_pkg::some_mod`) + completions.extend( + all_packages(symbols, &info) + .iter() + .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), + ); + } else if cursor.loc.start() > mod_ident.address.loc.end() + && cursor.loc.end() <= mod_ident.module.loc().end() + { + // cursor is either at the `::` succeeding package/address or at the identifier + // following that particular `::` + for ident in pkg_mod_identifiers(symbols, &info, &mod_ident.address) { + completions.push(completion_item( + ident.value.module.value().as_str(), + CompletionItemKind::MODULE, + )); + } + } else { + completions.extend(module_use_completions( + symbols, + cursor, + &info, + &mod_use, + &mod_ident.address, + &mod_ident.module, + )); + } + } + P::Use::NestedModuleUses(leading_name, uses) => { + if leading_name.loc.contains(&cursor.loc) { + // cursor on package + completions.extend( + all_packages(symbols, &info) + .iter() + .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), + ); + } else { + if let Some((first_name, _)) = uses.first() { + if cursor.loc.start() > leading_name.loc.end() + && cursor.loc.end() <= first_name.loc().start() + { + // cursor is after `::` succeeding address/package but before the first + // module + for ident in pkg_mod_identifiers(symbols, &info, &leading_name) { + completions.push(completion_item( + ident.value.module.value().as_str(), + CompletionItemKind::MODULE, + )); + } + // no point in falling through to the uses loop below + return (completions, completion_finalized); + } + } + + for (mod_name, mod_use) in &uses { + if mod_name.loc().contains(&cursor.loc) { + for ident in pkg_mod_identifiers(symbols, &info, &leading_name) { + completions.push(completion_item( + ident.value.module.value().as_str(), + CompletionItemKind::MODULE, + )); + } + // no point checking other locations + break; + } + completions.extend(module_use_completions( + symbols, + cursor, + &info, + mod_use, + &leading_name, + mod_name, + )); + } + } + } + P::Use::Fun { .. } => (), // already handled as part of name chain completion + P::Use::Partial { + package, + colon_colon, + opening_brace: _, + } => { + if package.loc.contains(&cursor.loc) { + // cursor on package name/address + completions.extend( + all_packages(symbols, &info) + .iter() + .map(|n| completion_item(n.as_str(), CompletionItemKind::UNIT)), + ); + } + if let Some(colon_colon_loc) = colon_colon { + if cursor.loc.start() >= colon_colon_loc.start() { + // cursor is on or past `::` + for ident in pkg_mod_identifiers(symbols, &info, &package) { + completions.push(completion_item( + ident.value.module.value().as_str(), + CompletionItemKind::MODULE, + )); + } + } + } + } + } + + (completions, completion_finalized) +} + +/// Handles auto-completion for structs and enums variants, including fields contained +/// by the struct or variant. +fn datatype_completion( + cursor: &CursorContext, + defining_mod_ident: &ModuleIdent_, + field_container: Symbol, + kind: CompletionItemKind, + field_names: &[Name], + named_fields: bool, +) -> Vec { + // always add a completion for the datatype itself (for type completion) + let mut completions = vec![completion_item(&field_container, kind)]; + + let defining_mod_ident_str = expansion_mod_ident_to_map_key(defining_mod_ident); + let current_mod_ident_str = + expansion_mod_ident_to_map_key(&cursor.module.as_ref().unwrap().value); + + // only add fields if there are some and we are in the same module as the datatype + if field_names.is_empty() || defining_mod_ident_str != current_mod_ident_str { + return completions; + } + + // fields on separate lines if there is more than two and if they are named + let separator = if field_names.len() > 2 && named_fields { + ",\n\t" + } else { + ", " + }; + let fields_list = field_names + .iter() + .enumerate() + .map(|(idx, name)| { + if named_fields { + format!("${{{}:{}}}", idx + 1, name) + } else { + format!("${{{}}}", idx + 1) + } + }) + .collect::>() + .join(separator); + + let (label, insert_text) = if !named_fields { + ( + format!("{field_container}(..)"), + // positional fields always on the same line + format!("{field_container}({fields_list})"), + ) + } else if field_names.len() > 2 { + ( + format!("{field_container}{{..}}"), + // more than two named fields, each on a separate line + format!("{field_container} {{\n\t{fields_list},\n}}"), + ) + } else { + ( + format!("{field_container}{{..}}"), + // fewer than three named fields, all on the same line + format!("{field_container} {{ {fields_list} }}"), + ) + }; + let field_completion = CompletionItem { + label, + kind: Some(kind), + insert_text: Some(insert_text), + insert_text_format: Some(InsertTextFormat::SNIPPET), + ..Default::default() + }; + completions.push(field_completion); + completions +} + +/// Returns all possible completions for a module member (e.g., a datatype) component of a name +/// access chain, where the prefix of this component (e.g, in `some_pkg::some_mod::`) represents a +/// module specified in `prefix_mod_ident`. The `inside_use` parameter determines if completion is +/// for "regular" access chain or for completion within a `use` statement. +fn module_member_completions( + symbols: &Symbols, + cursor: &CursorContext, + prefix_mod_ident: &ModuleIdent, + chain_kind: ChainCompletionKind, + inside_use: bool, +) -> Vec { + use ChainCompletionKind as CT; + + let mut completions = vec![]; + + let Some(mod_defs) = mod_defs(symbols, &prefix_mod_ident.value) else { + return completions; + }; + + // list all members or only publicly visible ones + let mut same_module = false; + let mut same_package = false; + if let Some(cursor_mod_ident) = cursor.module { + if &cursor_mod_ident == prefix_mod_ident { + same_module = true; + } + if cursor_mod_ident.value.address == prefix_mod_ident.value.address { + same_package = true; + } + } + + if matches!(chain_kind, CT::Function) || matches!(chain_kind, CT::All) { + let fun_completions = mod_defs + .functions + .iter() + .filter_map(|(fname, fdef)| { + symbols + .def_info(&fdef.name_loc) + .map(|def_info| (fname, def_info)) + }) + .filter(|(_, def_info)| { + if let DefInfo::Function(_, visibility, ..) = def_info { + match visibility { + Visibility::Internal => same_module, + Visibility::Package(_) => same_package, + _ => true, + } + } else { + false + } + }) + .filter_map(|(fname, def_info)| { + if let DefInfo::Function( + _, + _, + fun_type, + _, + type_args, + arg_names, + arg_types, + ret_type, + _, + ) = def_info + { + Some(call_completion_item( + &prefix_mod_ident.value, + matches!(fun_type, FunType::Macro), + None, + fname, + type_args, + arg_names, + arg_types, + ret_type, + inside_use, + )) + } else { + None + } + }); + completions.extend(fun_completions); + } + + if matches!(chain_kind, CT::Type) || matches!(chain_kind, CT::All) { + completions.extend(mod_defs.structs.iter().flat_map(|(sname, member_def)| { + struct_completion(cursor, &mod_defs.ident, *sname, member_def) + })); + completions.extend( + mod_defs + .enums + .keys() + .map(|ename| completion_item(ename, CompletionItemKind::ENUM)), + ); + } + + if matches!(chain_kind, CT::All) && same_module { + completions.extend( + mod_defs + .constants + .keys() + .map(|cname| completion_item(cname, CompletionItemKind::CONSTANT)), + ); + } + + completions +} + +/// Computes completions for a struct. +fn struct_completion( + cursor: &CursorContext, + defining_mod_ident: &ModuleIdent_, + name: Symbol, + member_def: &MemberDef, +) -> Vec { + let MemberDef { + info: MemberDefInfo::Struct { + field_defs, + positional, + }, + .. + } = member_def + else { + return vec![completion_item(&name, CompletionItemKind::STRUCT)]; + }; + datatype_completion( + cursor, + defining_mod_ident, + name, + CompletionItemKind::STRUCT, + &field_defs.iter().map(|d| sp(d.loc, d.name)).collect_vec(), + !positional, + ) +} + +/// Returns completion item if a given name/alias identifies a valid member of a given module +/// available in the completion scope as if it was a single-length name chain. +fn single_name_member_completion( + symbols: &Symbols, + cursor: &CursorContext, + mod_ident: &ModuleIdent_, + member_alias: &Symbol, + member_name: &Symbol, + chain_kind: ChainCompletionKind, +) -> Vec { + use ChainCompletionKind as CT; + + let Some(mod_defs) = mod_defs(symbols, mod_ident) else { + return vec![]; + }; + + // is it a function? + if let Some(fdef) = mod_defs.functions.get(member_name) { + if !(matches!(chain_kind, CT::Function) || matches!(chain_kind, CT::All)) { + return vec![]; + } + let Some(DefInfo::Function(.., fun_type, _, type_args, arg_names, arg_types, ret_type, _)) = + symbols.def_info(&fdef.name_loc) + else { + return vec![]; + }; + return vec![call_completion_item( + mod_ident, + matches!(fun_type, FunType::Macro), + None, + member_alias, + type_args, + arg_names, + arg_types, + ret_type, + /* inside_use */ false, + )]; + }; + + // is it a struct? + if let Some(member_def) = mod_defs.structs.get(member_name) { + if !(matches!(chain_kind, CT::Type) || matches!(chain_kind, CT::All)) { + return vec![]; + } + return struct_completion(cursor, &mod_defs.ident, *member_alias, member_def); + } + + // is it an enum? + if mod_defs.enums.get(member_name).is_some() { + if !(matches!(chain_kind, CT::Type) || matches!(chain_kind, CT::All)) { + return vec![]; + } + return vec![completion_item( + member_alias.as_str(), + CompletionItemKind::ENUM, + )]; + } + + // is it a const? + if mod_defs.constants.get(member_name).is_some() { + if !matches!(chain_kind, CT::All) { + return vec![]; + } + return vec![completion_item( + member_alias.as_str(), + CompletionItemKind::CONSTANT, + )]; + } + + vec![] +} + +/// Returns completion items for all members of a given module as if they were single-length name +/// chains. +fn all_single_name_member_completions( + symbols: &Symbols, + cursor: &CursorContext, + members_info: &BTreeSet<(Symbol, ModuleIdent, Name)>, + chain_kind: ChainCompletionKind, +) -> Vec { + let mut completions = vec![]; + for (member_alias, sp!(_, mod_ident), member_name) in members_info { + let member_completions = single_name_member_completion( + symbols, + cursor, + mod_ident, + member_alias, + &member_name.value, + chain_kind, + ); + completions.extend(member_completions); + } + completions +} + +/// Checks if a given module identifier represents a module in a package identifier by +/// `leading_name`. +fn is_pkg_mod_ident(mod_ident: &ModuleIdent_, leading_name: &P::LeadingNameAccess) -> bool { + match mod_ident.address { + Address::NamedUnassigned(name) => matches!(leading_name.value, + P::LeadingNameAccess_::Name(n) | P::LeadingNameAccess_::GlobalAddress(n) if name == n), + Address::Numerical { + name, + value, + name_conflict: _, + } => match leading_name.value { + P::LeadingNameAccess_::AnonymousAddress(addr) if addr == value.value => true, + P::LeadingNameAccess_::Name(addr_name) + | P::LeadingNameAccess_::GlobalAddress(addr_name) + if Some(addr_name) == name => + { + true + } + _ => false, + }, + } +} + +/// Gets module identifiers for a given package identified by `leading_name`. +fn pkg_mod_identifiers( + symbols: &Symbols, + info: &AliasAutocompleteInfo, + leading_name: &P::LeadingNameAccess, +) -> BTreeSet { + info.modules + .values() + .filter(|mod_ident| is_pkg_mod_ident(&mod_ident.value, leading_name)) + .copied() + .chain( + symbols + .file_mods + .values() + .flatten() + .map(|mdef| sp(mdef.name_loc, mdef.ident)) + .filter(|mod_ident| is_pkg_mod_ident(&mod_ident.value, leading_name)), + ) + .collect::>() +} + +/// Computes completions for a single enum variant. +fn variant_completion( + symbols: &Symbols, + cursor: &CursorContext, + defining_mod_ident: &ModuleIdent_, + vinfo: &VariantInfo, +) -> Vec { + let Some(DefInfo::Variant(_, _, _, positional, field_names, ..)) = + symbols.def_info.get(&vinfo.name.loc) + else { + return vec![completion_item( + vinfo.name.value.as_str(), + CompletionItemKind::ENUM_MEMBER, + )]; + }; + + datatype_completion( + cursor, + defining_mod_ident, + vinfo.name.value, + CompletionItemKind::ENUM_MEMBER, + field_names, + !positional, + ) +} + +/// Computes completions for variants of a given enum. +fn all_variant_completions( + symbols: &Symbols, + cursor: &CursorContext, + mod_ident: &ModuleIdent, + datatype_name: Symbol, +) -> Vec { + let Some(mod_defs) = mod_defs(symbols, &mod_ident.value) else { + return vec![]; + }; + + let Some(edef) = mod_defs.enums.get(&datatype_name) else { + return vec![]; + }; + + let Some(DefInfo::Enum(.., variants, _)) = symbols.def_info.get(&edef.name_loc) else { + return vec![]; + }; + + variants + .iter() + .flat_map(|vinfo| variant_completion(symbols, cursor, &mod_defs.ident, vinfo)) + .collect_vec() +} + +/// Computes completions for a given chain entry: `prev_kind` determines the kind of previous chain +/// component, and `chain_kind` contains information about the entity that the whole chain may +/// represent (e.g., a type of or a function). +fn name_chain_entry_completions( + symbols: &Symbols, + cursor: &CursorContext, + info: &AliasAutocompleteInfo, + prev_kind: ChainComponentKind, + chain_kind: ChainCompletionKind, + inside_use: bool, + completions: &mut Vec, +) { + match prev_kind { + ChainComponentKind::Package(leading_name) => { + for mod_ident in pkg_mod_identifiers(symbols, info, &leading_name) { + completions.push(completion_item( + mod_ident.value.module.value().as_str(), + CompletionItemKind::MODULE, + )); + } + } + ChainComponentKind::Module(mod_ident) => { + completions.extend(module_member_completions( + symbols, cursor, &mod_ident, chain_kind, inside_use, + )); + } + ChainComponentKind::Member(mod_ident, member_name) => { + completions.extend(all_variant_completions( + symbols, + cursor, + &mod_ident, + member_name, + )); + } + } +} + +/// Computes the kind of the next chain component (based on what the previous one, represented by +/// `prev_kind` was). +fn next_name_chain_component_kind( + symbols: &Symbols, + info: &AliasAutocompleteInfo, + prev_kind: ChainComponentKind, + component_name: Name, +) -> Option { + match prev_kind { + ChainComponentKind::Package(leading_name) => { + pkg_mod_identifiers(symbols, info, &leading_name) + .into_iter() + .find(|mod_ident| mod_ident.value.module.value() == component_name.value) + .map(ChainComponentKind::Module) + } + ChainComponentKind::Module(mod_ident) => { + Some(ChainComponentKind::Member(mod_ident, component_name.value)) + } + ChainComponentKind::Member(_, _) => None, // no more "after" completions to be processed + } +} + +/// Walks down a name chain, looking for the relevant portion that contains the cursor. When it +/// finds, it calls to `name_chain_entry_completions` to compute and return the completions. +fn completions_for_name_chain_entry( + symbols: &Symbols, + cursor: &CursorContext, + info: &AliasAutocompleteInfo, + prev_info: ChainComponentInfo, + chain_kind: ChainCompletionKind, + path_entries: &[Name], + path_index: usize, + colon_colon_triggered: bool, + inside_use: bool, + completions: &mut Vec, +) { + let ChainComponentInfo { + loc: prev_loc, + kind: prev_kind, + } = prev_info; + + let mut at_colon_colon = false; + if path_index == path_entries.len() { + // the only reason we would not return here is if we were at `::` which is past the location + // of the last path component + if colon_colon_triggered && cursor.loc.start() > prev_loc.end() { + at_colon_colon = true; + } else { + return; + } + } + + if !at_colon_colon { + // we are not at the last `::` but we may be at an intermediate one + if colon_colon_triggered + && path_index < path_entries.len() + && cursor.loc.start() > prev_loc.end() + && cursor.loc.end() <= path_entries[path_index].loc.start() + { + at_colon_colon = true; + } + } + + // we are at `::`, or at some component's identifier + if at_colon_colon || path_entries[path_index].loc.contains(&cursor.loc) { + name_chain_entry_completions( + symbols, + cursor, + info, + prev_kind, + chain_kind, + inside_use, + completions, + ); + } else { + let component_name = path_entries[path_index]; + if let Some(next_kind) = + next_name_chain_component_kind(symbols, info, prev_kind, component_name) + { + completions_for_name_chain_entry( + symbols, + cursor, + info, + ChainComponentInfo::new(component_name.loc, next_kind), + chain_kind, + path_entries, + path_index + 1, + colon_colon_triggered, + inside_use, + completions, + ); + } + } +} + +/// Check if a given address represents a package within the current program. +fn is_package_address( + symbols: &Symbols, + info: &AliasAutocompleteInfo, + pkg_addr: NumericalAddress, +) -> bool { + if info.addresses.iter().any(|(_, a)| a == &pkg_addr) { + return true; + } + + symbols.file_mods.values().flatten().any(|mdef| { + matches!(mdef.ident.address, + Address::Numerical { value, .. } if value.value == pkg_addr) + }) +} + +/// Check if a given name represents a package within the current program. +fn is_package_name(symbols: &Symbols, info: &AliasAutocompleteInfo, pkg_name: Name) -> bool { + if info.addresses.contains_key(&pkg_name.value) { + return true; + } + + symbols + .file_mods + .values() + .flatten() + .map(|mdef| &mdef.ident) + .any(|mod_ident| match &mod_ident.address { + Address::NamedUnassigned(name) if name == &pkg_name => true, + Address::Numerical { + name: Some(name), .. + } if name == &pkg_name => true, + _ => false, + }) +} + +/// Get all packages that could be a target of auto-completion, whether they are part of +/// `AliasAutocompleteInfo` or not. +fn all_packages(symbols: &Symbols, info: &AliasAutocompleteInfo) -> BTreeSet { + let mut addresses = BTreeSet::new(); + for (n, a) in &info.addresses { + addresses.insert(n.to_string()); + addresses.insert(a.to_string()); + } + + symbols + .file_mods + .values() + .flatten() + .map(|mdef| &mdef.ident) + .for_each(|mod_ident| match &mod_ident.address { + Address::Numerical { name, value, .. } => { + if let Some(n) = name { + addresses.insert(n.to_string()); + } + addresses.insert(value.to_string()); + } + Address::NamedUnassigned(n) => { + addresses.insert(n.to_string()); + } + }); + + addresses +} + +/// Computes the kind of the fist chain component. +fn first_name_chain_component_kind( + symbols: &Symbols, + info: &AliasAutocompleteInfo, + leading_name: P::LeadingNameAccess, +) -> Option { + match leading_name.value { + P::LeadingNameAccess_::Name(n) => { + if is_package_name(symbols, info, n) { + Some(ChainComponentKind::Package(leading_name)) + } else if let Some(mod_ident) = info.modules.get(&n.value) { + Some(ChainComponentKind::Module(*mod_ident)) + } else if let Some((mod_ident, member_name)) = + info.members + .iter() + .find_map(|(alias_name, mod_ident, member_name)| { + if alias_name == &n.value { + Some((*mod_ident, member_name)) + } else { + None + } + }) + { + Some(ChainComponentKind::Member(mod_ident, member_name.value)) + } else { + None + } + } + P::LeadingNameAccess_::AnonymousAddress(addr) => { + if is_package_address(symbols, info, addr) { + Some(ChainComponentKind::Package(leading_name)) + } else { + None + } + } + P::LeadingNameAccess_::GlobalAddress(n) => { + // if leading name is global address then the first component can only be a + // package + if is_package_name(symbols, info, n) { + Some(ChainComponentKind::Package(leading_name)) + } else { + None + } + } + } +} + +/// Computes auto-completions for module uses. +fn module_use_completions( + symbols: &Symbols, + cursor: &CursorContext, + info: &AliasAutocompleteInfo, + mod_use: &P::ModuleUse, + package: &P::LeadingNameAccess, + mod_name: &P::ModuleName, +) -> Vec { + use P::ModuleUse as MU; + let mut completions = vec![]; + + let Some(mod_ident) = pkg_mod_identifiers(symbols, info, package) + .into_iter() + .find(|mod_ident| &mod_ident.value.module == mod_name) + else { + return completions; + }; + + match mod_use { + MU::Module(_) => (), // nothing to do with just module alias + MU::Members(members) => { + if let Some((first_name, _)) = members.first() { + if cursor.loc.start() > mod_name.loc().end() + && cursor.loc.end() <= first_name.loc.start() + { + // cursor is after `::` succeeding module but before the first module member + completions.extend(module_member_completions( + symbols, + cursor, + &mod_ident, + ChainCompletionKind::All, + /* inside_use */ true, + )); + // no point in falling through to the members loop below + return completions; + } + } + + for (sp!(mloc, _), _) in members { + if mloc.contains(&cursor.loc) { + // cursor is at identifier representing module member + completions.extend(module_member_completions( + symbols, + cursor, + &mod_ident, + ChainCompletionKind::All, + /* inside_use */ true, + )); + // no point checking other locations + break; + } + } + } + MU::Partial { + colon_colon, + opening_brace: _, + } => { + if let Some(colon_colon_loc) = colon_colon { + if cursor.loc.start() >= colon_colon_loc.start() { + // cursor is on or past `::` + completions.extend(module_member_completions( + symbols, + cursor, + &mod_ident, + ChainCompletionKind::All, + /* inside_use */ true, + )); + } + } + } + } + + completions +} diff --git a/external-crates/move/crates/move-analyzer/src/completions/snippets.rs b/external-crates/move/crates/move-analyzer/src/completions/snippets.rs new file mode 100644 index 00000000000..1f2fe123fe6 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/src/completions/snippets.rs @@ -0,0 +1,216 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// Snippets auto-completion for various language elements, such as `init` function +// or structs representing objects. + +use crate::{ + completions::utils::mod_defs, + symbols::{CursorContext, CursorDefinition, DefInfo, Symbols}, +}; +use lsp_types::{CompletionItem, CompletionItemKind, Documentation, InsertTextFormat, Position}; +use move_command_line_common::files::FileHash; +use move_compiler::{expansion::ast::Visibility, parser::ast::Ability_, shared::Identifier}; +use move_ir_types::location::Loc; +use move_symbol_pool::Symbol; + +use std::path::Path; + +/// Checks if the cursor is at the opening brace of a struct definition and returns +/// auto-completion of this struct into an object if the struct has the `key` ability. +pub fn object_completion( + symbols: &Symbols, + cursor: &CursorContext, +) -> (Option, bool) { + let mut completion_finalized = false; + // look for a struct definition on the line that contains `{`, check its abilities, + // and do auto-completion if `key` ability is present + let Some(CursorDefinition::Struct(sname)) = &cursor.defn_name else { + return (None, completion_finalized); + }; + completion_finalized = true; + let Some(mod_ident) = cursor.module else { + return (None, completion_finalized); + }; + let Some(mod_defs) = mod_defs(symbols, &mod_ident.value) else { + return (None, completion_finalized); + }; + let Some(struct_def) = mod_defs.structs.get(&sname.value()) else { + return (None, completion_finalized); + }; + + let Some(DefInfo::Struct(_, _, _, _, abilities, ..)) = + symbols.def_info.get(&struct_def.name_loc) + else { + return (None, completion_finalized); + }; + + if !abilities.has_ability_(Ability_::Key) { + return (None, completion_finalized); + } + let obj_snippet = "\n\tid: UID,\n\t$1\n".to_string(); + let init_completion = CompletionItem { + label: "id: UID".to_string(), + kind: Some(CompletionItemKind::SNIPPET), + documentation: Some(Documentation::String("Object snippet".to_string())), + insert_text: Some(obj_snippet), + insert_text_format: Some(InsertTextFormat::SNIPPET), + ..Default::default() + }; + (Some(init_completion), completion_finalized) +} + +/// Auto-completion for `init` function snippet. +pub fn init_completion( + symbols: &Symbols, + use_fpath: &Path, + buffer: &str, + position: &Position, +) -> (Vec, bool) { + let mut completions = vec![]; + let mut completion_finalized = false; + + let strings = preceding_strings(buffer, position); + + if strings.is_empty() { + return (completions, completion_finalized); + } + + // try to auto-complete init function declararation - get the last string + // and see if it represents the beginning of init function declaration + const INIT_FN_NAME: &str = "init"; + let (n, use_col) = strings.last().unwrap(); + for u in symbols.line_uses(use_fpath, position.line) { + if *use_col >= u.col_start() && *use_col <= u.col_end() { + let def_loc = u.def_loc(); + let Some(use_file_mod_definition) = symbols.file_mods.get(use_fpath) else { + break; + }; + let Some(use_file_mod_def) = use_file_mod_definition.first() else { + break; + }; + if is_definition( + symbols, + position.line, + u.col_start(), + use_file_mod_def.fhash(), + def_loc, + ) { + // since it's a definition, there is no point in trying to suggest a name + // if one is about to create a fresh identifier + completion_finalized = true; + } + let Some(def_info) = symbols.def_info(&def_loc) else { + break; + }; + let DefInfo::Function(mod_ident, v, ..) = def_info else { + // not a function + break; + }; + if !INIT_FN_NAME.starts_with(n) { + // starting to type "init" + break; + } + if !matches!(v, Visibility::Internal) { + // private (otherwise perhaps it's "init_something") + break; + } + + // get module info containing the init function + let Some(mdef) = symbols.mod_defs(&u.def_loc().file_hash(), *mod_ident) else { + break; + }; + + if mdef.functions().contains_key(&(INIT_FN_NAME.into())) { + // already has init function + break; + } + + let iota_ctx_arg = "ctx: &mut TxContext"; + + // decide on the list of parameters depending on whether a module containing + // the init function has a struct thats an one-time-witness candidate struct + let otw_candidate = Symbol::from(mod_ident.module.value().to_uppercase()); + let init_snippet = if mdef.structs().contains_key(&otw_candidate) { + format!("{INIT_FN_NAME}(${{1:witness}}: {otw_candidate}, {iota_ctx_arg}) {{\n\t${{2:}}\n}}\n") + } else { + format!("{INIT_FN_NAME}({iota_ctx_arg}) {{\n\t${{1:}}\n}}\n") + }; + + let init_completion = CompletionItem { + label: INIT_FN_NAME.to_string(), + kind: Some(CompletionItemKind::SNIPPET), + documentation: Some(Documentation::String( + "Module initializer snippet".to_string(), + )), + insert_text: Some(init_snippet), + insert_text_format: Some(InsertTextFormat::SNIPPET), + ..Default::default() + }; + completions.push(init_completion); + break; + } + } + + (completions, completion_finalized) +} + +/// Finds white-space separated strings on the line containing auto-completion request and their +/// locations. +fn preceding_strings(buffer: &str, position: &Position) -> Vec<(String, u32)> { + let mut strings = vec![]; + let line = match buffer.lines().nth(position.line as usize) { + Some(line) => line, + None => return strings, // Our buffer does not contain the line, and so must be out of date. + }; + + let mut chars = line.chars(); + let mut cur_col = 0; + let mut cur_str_start = 0; + let mut cur_str = "".to_string(); + while cur_col <= position.character { + let Some(c) = chars.next() else { + return strings; + }; + if c == ' ' || c == '\t' { + if !cur_str.is_empty() { + // finish an already started string + strings.push((cur_str, cur_str_start)); + cur_str = "".to_string(); + } + } else { + if cur_str.is_empty() { + // start a new string + cur_str_start = cur_col; + } + cur_str.push(c); + } + + cur_col += c.len_utf8() as u32; + } + if !cur_str.is_empty() { + // finish the last string + strings.push((cur_str, cur_str_start)); + } + strings +} + +/// Checks if a use at a given position is also a definition. +fn is_definition( + symbols: &Symbols, + use_line: u32, + use_col: u32, + use_fhash: FileHash, + def_loc: Loc, +) -> bool { + if let Some(use_loc) = symbols + .files + .line_char_offset_to_loc_opt(use_fhash, use_line, use_col) + { + // TODO: is overlapping better? + def_loc.contains(&use_loc) + } else { + false + } +} diff --git a/external-crates/move/crates/move-analyzer/src/completions/utils.rs b/external-crates/move/crates/move-analyzer/src/completions/utils.rs new file mode 100644 index 00000000000..b9dbb353afc --- /dev/null +++ b/external-crates/move/crates/move-analyzer/src/completions/utils.rs @@ -0,0 +1,131 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crate::symbols::{ + mod_ident_to_ide_string, ret_type_to_ide_str, type_args_to_ide_string, type_list_to_ide_string, + ModuleDefs, Symbols, +}; +use lsp_types::{CompletionItem, CompletionItemKind, CompletionItemLabelDetails, InsertTextFormat}; +use move_compiler::{ + expansion::ast::ModuleIdent_, + naming::ast::{Type, Type_}, + parser::keywords::PRIMITIVE_TYPES, + shared::Name, +}; +use move_symbol_pool::Symbol; +use once_cell::sync::Lazy; + +/// List of completion items of Move's primitive types. +pub static PRIMITIVE_TYPE_COMPLETIONS: Lazy> = Lazy::new(|| { + let mut primitive_types = PRIMITIVE_TYPES + .iter() + .map(|label| completion_item(label, CompletionItemKind::KEYWORD)) + .collect::>(); + primitive_types.push(completion_item("address", CompletionItemKind::KEYWORD)); + primitive_types +}); + +/// Get definitions for a given module. +pub fn mod_defs<'a>(symbols: &'a Symbols, mod_ident: &ModuleIdent_) -> Option<&'a ModuleDefs> { + symbols + .file_mods + .values() + .flatten() + .find(|mdef| mdef.ident == *mod_ident) +} + +/// Constructs an `lsp_types::CompletionItem` with the given `label` and `kind`. +pub fn completion_item(label: &str, kind: CompletionItemKind) -> CompletionItem { + CompletionItem { + label: label.to_owned(), + kind: Some(kind), + ..Default::default() + } +} + +pub fn call_completion_item( + mod_ident: &ModuleIdent_, + is_macro: bool, + method_name_opt: Option<&Symbol>, + function_name: &Symbol, + type_args: &[Type], + arg_names: &[Name], + arg_types: &[Type], + ret_type: &Type, + inside_use: bool, +) -> CompletionItem { + let sig_string = format!( + "fun {}({}){}", + type_args_to_ide_string(type_args, /* separate_lines */ false, /* verbose */ false), + type_list_to_ide_string(arg_types, /* separate_lines */ false, /* verbose */ false), + ret_type_to_ide_str(ret_type, /* verbose */ false) + ); + // if it's a method call we omit the first argument which is guaranteed to be there as this is a + // method and needs a receiver + let omitted_arg_count = if method_name_opt.is_some() { 1 } else { 0 }; + let mut snippet_idx = 0; + let arg_snippet = arg_names + .iter() + .zip(arg_types) + .skip(omitted_arg_count) + .map(|(name, ty)| { + lambda_snippet(ty, &mut snippet_idx).unwrap_or_else(|| { + let mut arg_name = name.to_string(); + if arg_name.starts_with('$') { + arg_name = arg_name[1..].to_string(); + } + snippet_idx += 1; + format!("${{{}:{}}}", snippet_idx, arg_name) + }) + }) + .collect::>() + .join(", "); + let macro_suffix = if is_macro { "!" } else { "" }; + let label_details = Some(CompletionItemLabelDetails { + detail: Some(format!( + " ({}{})", + mod_ident_to_ide_string(mod_ident, None, true), + function_name + )), + description: Some(sig_string), + }); + + let method_name = method_name_opt.unwrap_or(function_name); + let (insert_text, insert_text_format) = if inside_use { + ( + Some(format!("{method_name}")), + Some(InsertTextFormat::PLAIN_TEXT), + ) + } else { + ( + Some(format!("{method_name}{macro_suffix}({arg_snippet})")), + Some(InsertTextFormat::SNIPPET), + ) + }; + + CompletionItem { + label: format!("{method_name}{macro_suffix}()"), + label_details, + kind: Some(CompletionItemKind::METHOD), + insert_text, + insert_text_format, + ..Default::default() + } +} + +fn lambda_snippet(sp!(_, ty): &Type, snippet_idx: &mut i32) -> Option { + if let Type_::Fun(vec, _) = ty { + let arg_snippets = vec + .iter() + .map(|_| { + *snippet_idx += 1; + format!("${{{snippet_idx}}}") + }) + .collect::>() + .join(", "); + *snippet_idx += 1; + return Some(format!("|{arg_snippets}| ${{{snippet_idx}}}")); + } + None +} diff --git a/external-crates/move/crates/move-analyzer/src/diagnostics.rs b/external-crates/move/crates/move-analyzer/src/diagnostics.rs index 741e5ccbf6e..a00efbb014b 100644 --- a/external-crates/move/crates/move-analyzer/src/diagnostics.rs +++ b/external-crates/move/crates/move-analyzer/src/diagnostics.rs @@ -24,12 +24,12 @@ pub fn lsp_diagnostics( files: &MappedFiles, ) -> BTreeMap> { let mut lsp_diagnostics = BTreeMap::new(); - for (s, _, (loc, msg), labels, _) in diagnostics { + for (s, _, (loc, msg), labels, notes) in diagnostics { let fpath = files.file_path(&loc.file_hash()); if let Some(start) = loc_start_to_lsp_position_opt(files, loc) { if let Some(end) = loc_end_to_lsp_position_opt(files, loc) { let range = Range::new(start, end); - let related_info_opt = if labels.is_empty() { + let related_info_opt = if labels.is_empty() && notes.is_empty() { None } else { Some( @@ -48,6 +48,16 @@ pub fn lsp_diagnostics( message: lmsg.to_string(), }) }) + .chain(notes.iter().map(|note| { + // for notes use the same location as for the main message + let fpath = files.file_path(&loc.file_hash()); + let fpos = + Location::new(Url::from_file_path(fpath).unwrap(), range); + DiagnosticRelatedInformation { + location: fpos, + message: format!("Note: {note}"), + } + })) .collect(), ) }; diff --git a/external-crates/move/crates/move-analyzer/src/lib.rs b/external-crates/move/crates/move-analyzer/src/lib.rs index a1b3565aa85..19c54b3e443 100644 --- a/external-crates/move/crates/move-analyzer/src/lib.rs +++ b/external-crates/move/crates/move-analyzer/src/lib.rs @@ -9,7 +9,7 @@ extern crate move_ir_types; pub mod analysis; pub mod analyzer; pub mod compiler_info; -pub mod completion; +pub mod completions; pub mod context; pub mod diagnostics; pub mod inlay_hints; diff --git a/external-crates/move/crates/move-analyzer/src/symbols.rs b/external-crates/move/crates/move-analyzer/src/symbols.rs index 6c2889b2cb5..bd87f3ffe55 100644 --- a/external-crates/move/crates/move-analyzer/src/symbols.rs +++ b/external-crates/move/crates/move-analyzer/src/symbols.rs @@ -61,35 +61,42 @@ use std::{ cmp, - collections::{BTreeMap, BTreeSet, HashMap}, + collections::{BTreeMap, BTreeSet}, fmt, path::{Path, PathBuf}, sync::{Arc, Condvar, Mutex}, thread, + time::Instant, }; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; use crossbeam::channel::Sender; use derivative::*; use im::ordmap::OrdMap; use lsp_server::{Request, RequestId}; use lsp_types::{ - request::GotoTypeDefinitionParams, Diagnostic, DocumentSymbol, DocumentSymbolParams, - GotoDefinitionParams, Hover, HoverContents, HoverParams, Location, MarkupContent, MarkupKind, - Position, Range, ReferenceParams, SymbolKind, + Diagnostic, DocumentSymbol, DocumentSymbolParams, GotoDefinitionParams, Hover, HoverContents, + HoverParams, Location, MarkupContent, MarkupKind, Position, Range, ReferenceParams, SymbolKind, + request::GotoTypeDefinitionParams, }; use move_command_line_common::files::FileHash; use move_compiler::{ - command_line::compiler::{construct_pre_compiled_lib, FullyCompiledProgram}, + PASS_CFGIR, PASS_PARSER, PASS_TYPING, + command_line::compiler::{FullyCompiledProgram, construct_pre_compiled_lib}, editions::{Edition, FeatureGate, Flavor}, - expansion::ast::{self as E, AbilitySet, ModuleIdent, ModuleIdent_, Value, Value_, Visibility}, + expansion::{ + ast::{self as E, AbilitySet, ModuleIdent, ModuleIdent_, Value, Value_, Visibility}, + name_validation::{IMPLICIT_STD_MEMBERS, IMPLICIT_STD_MODULES}, + }, linters::LintLevel, - naming::ast::{DatatypeTypeParameter, StructFields, Type, TypeName_, Type_, VariantFields}, - parser::ast as P, + naming::ast::{DatatypeTypeParameter, StructFields, Type, Type_, TypeName_, VariantFields}, + parser::{ + ast::{self as P}, + comments::CommentMap, + }, shared::{ - files::{FileId, MappedFiles}, + Identifier, Name, NamedAddressMap, NamedAddressMaps, files::MappedFiles, unique_map::UniqueMap, - Identifier, Name, NamedAddressMap, }, typing::{ ast::{ @@ -99,8 +106,8 @@ use move_compiler::{ visitor::TypingVisitorContext, }, unit_test::filter_test_members::UNIT_TEST_POISON_FUN_NAME, - PASS_CFGIR, PASS_PARSER, PASS_TYPING, }; +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; use move_package::{ compilation::{build_plan::BuildPlan, compiled_package::ModuleFormat}, @@ -112,8 +119,8 @@ use sha2::{Digest, Sha256}; use tempfile::tempdir; use url::Url; use vfs::{ - impls::{memory::MemoryFS, overlay::OverlayFS, physical::PhysicalFS}, VfsPath, + impls::{memory::MemoryFS, overlay::OverlayFS, physical::PhysicalFS}, }; use crate::{ @@ -125,15 +132,93 @@ use crate::{ }; const MANIFEST_FILE_NAME: &str = "Move.toml"; +const STD_LIB_PKG_ADDRESS: &str = "0x1"; +type SourceFiles = BTreeMap; +/// Information about compiled program (ASTs at different levels) #[derive(Clone)] -pub struct PrecompiledPkgDeps { +struct CompiledProgram { + parsed: P::Program, + typed: T::Program, +} + +/// Information about cached dependencies used during compilation and analysis +#[derive(Clone)] +struct CachedDeps { + /// Cached fully compiled program representing dependencies + compiled_program: Arc, + /// Cached symbols computation data for dependencies + symbols_data: Option>, +} + +/// Information about the compiled package and data structures +/// computed during compilation and analysis +#[derive(Clone)] +pub struct CompiledPkgInfo { + /// Package path + path: PathBuf, + /// Manifest hash + manifest_hash: Option, + /// A combined hash for manifest files of the dependencies + deps_hash: String, + /// Information about cached dependencies + cached_deps: Option, + /// Compiled user program + program: CompiledProgram, + /// Source files + source_files: SourceFiles, + /// Maped files + mapped_files: MappedFiles, + /// Edition of the compiler + edition: Option, + /// Compiler info + compiler_info: Option, + /// Comments for both user code and the dependencies + all_comments: CommentMap, +} + +/// Data used during symbols computation +#[derive(Clone)] +pub struct SymbolsComputationData { + /// Outermost definitions in a module (structs, consts, functions), keyed on + /// a ModuleIdent string + mod_outer_defs: BTreeMap, + /// A UseDefMap for a given module (needs to be appropriately set before the + /// module processing starts) keyed on a ModuleIdent string + mod_use_defs: BTreeMap, + /// Uses (references) for a definition at a given location + references: BTreeMap>, + /// Additional information about a definitions at a given location + def_info: BTreeMap, + /// Module name lengths in access paths for a given module (needs to be + /// appropriately set before the module processing starts) keyed on a + /// ModuleIdent string + mod_to_alias_lengths: BTreeMap>, +} + +impl SymbolsComputationData { + pub fn new() -> Self { + Self { + mod_outer_defs: BTreeMap::new(), + mod_use_defs: BTreeMap::new(), + references: BTreeMap::new(), + def_info: BTreeMap::new(), + mod_to_alias_lengths: BTreeMap::new(), + } + } +} + +/// Precomputed information about package dependencies. +#[derive(Clone)] +pub struct PrecomputedPkgDepsInfo { /// Hash of the manifest file for a given package manifest_hash: Option, /// Hash of dependency source files deps_hash: String, /// Precompiled deps deps: Arc, + /// Symbols computation data + deps_symbols_data: Arc, } /// Location of a use's identifier @@ -361,6 +446,28 @@ impl CallInfo { } } +/// Map from struct name to field order information +pub type StructFieldOrderInfo = BTreeMap>; +/// Map from enum name to variant name to field order information +pub type VariantFieldOrderInfo = BTreeMap>>; + +/// Information about field order in structs and enums needed for +/// auto-completion to be consistent with field order in the source code +#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq)] +pub struct FieldOrderInfo { + structs: BTreeMap, + variants: BTreeMap, +} + +impl FieldOrderInfo { + pub fn new() -> Self { + Self { + structs: BTreeMap::new(), + variants: BTreeMap::new(), + } + } +} + /// Module-level definitions and other module-related info #[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq)] pub struct ModuleDefs { @@ -432,6 +539,20 @@ impl CursorContext { } } + /// Returns access chain for a match pattern, if any + fn find_access_chain_in_match_pattern(&self, p: &P::MatchPattern_) -> Option { + use ChainCompletionKind as CT; + use P::MatchPattern_ as MP; + match p { + MP::PositionalConstructor(chain, _) => { + Some(ChainInfo::new(chain.clone(), CT::Type, false)) + } + MP::FieldConstructor(chain, _) => Some(ChainInfo::new(chain.clone(), CT::Type, false)), + MP::Name(_, chain) => Some(ChainInfo::new(chain.clone(), CT::All, false)), + MP::Literal(_) | MP::Or(..) | MP::At(..) => None, + } + } + /// Returns access chain at cursor position (if any) along with the /// information of what the chain's auto-completed target kind should /// be, and weather it is part of the use statement. @@ -477,6 +598,7 @@ impl CursorContext { return Some(ChainInfo::new(*(ty.clone()), CT::Type, true)); } } + CP::MatchPattern(sp!(_, p)) => return self.find_access_chain_in_match_pattern(p), _ => (), }; None @@ -502,6 +624,7 @@ pub enum CursorPosition { DefName, Attribute(P::AttributeValue), Use(Spanned), + MatchPattern(P::MatchPattern), Unknown, // FIXME: These two are currently unused because these forms don't have enough location // recorded on them during parsing. @@ -546,13 +669,11 @@ pub struct Symbols { pub compiler_info: CompilerInfo, /// Cursor information gathered up during analysis pub cursor_context: Option, - /// Typed Program - pub typed_ast: Option, } #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] enum RunnerState { - Run(PathBuf), + Run(BTreeSet), Wait, Quit, } @@ -609,21 +730,37 @@ impl fmt::Display for DefInfo { ret_type, _, ) => { - let type_args_str = type_args_to_ide_string(type_args, /* verbose */ true); + const SINGLE_LINE_TYPE_ARGS_NUM: usize = 2; + // The strategy for displaying function signature is as follows: + // - if there are more than SINGLE_LINE_TYPE_ARGS_NUM type args, they are + // displayed on separate lines + // - "regular" args are always displayed on separate lines, which which is + // motivated by the fact that datatypes are displayed in a fully-qualified + // form (i.e., with package and module name), and that makes the function name + // already long and (likely) the length of each individual type also long + // (modulo primitive types of course, but I think we can live with that) + let type_args_str = type_args_to_ide_string( + type_args, + // separate_lines + type_args.len() > SINGLE_LINE_TYPE_ARGS_NUM, + // verbose + true, + ); + let args_str = typed_id_list_to_ide_string( + arg_names, arg_types, '(', ')', // separate_lines + true, // verbose + true, + ); let ret_type_str = ret_type_to_ide_str(ret_type, /* verbose */ true); write!( f, - "{}{}fun {}::{}{}({}){}", + "{}{}fun {}{}{}{}{}", visibility_to_ide_string(visibility), fun_type_to_ide_string(fun_type), - mod_ident_to_ide_string(mod_ident), + mod_ident_to_ide_string(mod_ident, None, true), name, type_args_str, - typed_id_list_to_ide_string( - arg_names, arg_types, // separate_lines - false, // verbose - true - ), + args_str, ret_type_str, ) } @@ -643,9 +780,9 @@ impl fmt::Display for DefInfo { if field_names.is_empty() { write!( f, - "{}struct {}::{}{}{} {{}}", + "{}struct {}{}{}{} {{}}", visibility_to_ide_string(visibility), - mod_ident_to_ide_string(mod_ident), + mod_ident_to_ide_string(mod_ident, Some(name), true), name, type_args_str, abilities_str, @@ -653,15 +790,17 @@ impl fmt::Display for DefInfo { } else { write!( f, - "{}struct {}::{}{}{} {{\n{}\n}}", + "{}struct {}{}{}{} {}", visibility_to_ide_string(visibility), - mod_ident_to_ide_string(mod_ident), + mod_ident_to_ide_string(mod_ident, Some(name), true), name, type_args_str, abilities_str, typed_id_list_to_ide_string( field_names, field_types, + '{', + '}', // separate_lines true, // verbose @@ -677,9 +816,9 @@ impl fmt::Display for DefInfo { if variants.is_empty() { write!( f, - "{}enum {}::{}{}{} {{}}", + "{}enum {}{}{}{} {{}}", visibility_to_ide_string(visibility), - mod_ident_to_ide_string(mod_ident), + mod_ident_to_ide_string(mod_ident, Some(name), true), name, type_args_str, abilities_str, @@ -687,9 +826,9 @@ impl fmt::Display for DefInfo { } else { write!( f, - "{}enum {}::{}{}{} {{\n{}\n}}", + "{}enum {}{}{}{} {{\n{}\n}}", visibility_to_ide_string(visibility), - mod_ident_to_ide_string(mod_ident), + mod_ident_to_ide_string(mod_ident, Some(name), true), name, type_args_str, abilities_str, @@ -701,30 +840,38 @@ impl fmt::Display for DefInfo { if field_types.is_empty() { write!( f, - "{}::{}::{}", - mod_ident_to_ide_string(mod_ident), + "{}{}::{}", + mod_ident_to_ide_string(mod_ident, Some(enum_name), true), enum_name, name ) } else if *positional { write!( f, - "{}::{}::{}({})", - mod_ident_to_ide_string(mod_ident), + "{}{}::{}({})", + mod_ident_to_ide_string(mod_ident, Some(enum_name), true), enum_name, name, - type_list_to_ide_string(field_types, /* verbose */ true) + type_list_to_ide_string( + field_types, + // separate_lines + false, + // verbose + true + ) ) } else { write!( f, - "{}::{}::{}{{{}}}", - mod_ident_to_ide_string(mod_ident), + "{}{}::{}{}", + mod_ident_to_ide_string(mod_ident, Some(enum_name), true), enum_name, name, typed_id_list_to_ide_string( field_names, field_types, + '{', + '}', // separate_lines false, // verbose @@ -736,8 +883,8 @@ impl fmt::Display for DefInfo { Self::Field(mod_ident, struct_name, name, t, _) => { write!( f, - "{}::{}\n{}: {}", - mod_ident_to_ide_string(mod_ident), + "{}{}\n{}: {}", + mod_ident_to_ide_string(mod_ident, Some(struct_name), true), struct_name, name, type_to_ide_string(t, /* verbose */ true) @@ -852,6 +999,10 @@ impl fmt::Display for CursorContext { writeln!(f, "parameter")?; writeln!(f, "- value: {:#?}", value)?; } + CursorPosition::MatchPattern(value) => { + writeln!(f, "match pattern")?; + writeln!(f, "- value: {:#?}", value)?; + } CursorPosition::DatatypeTypeParameter(value) => { writeln!(f, "datatype type param")?; writeln!(f, "- value: {:#?}", value)?; @@ -874,11 +1025,17 @@ fn visibility_to_ide_string(visibility: &Visibility) -> String { visibility_str } -pub fn type_args_to_ide_string(type_args: &[Type], verbose: bool) -> String { +pub fn type_args_to_ide_string(type_args: &[Type], separate_lines: bool, verbose: bool) -> String { let mut type_args_str = "".to_string(); if !type_args.is_empty() { type_args_str.push('<'); - type_args_str.push_str(&type_list_to_ide_string(type_args, verbose)); + if separate_lines { + type_args_str.push('\n'); + } + type_args_str.push_str(&type_list_to_ide_string(type_args, separate_lines, verbose)); + if separate_lines { + type_args_str.push('\n'); + } type_args_str.push('>'); } type_args_str @@ -897,10 +1054,12 @@ fn datatype_type_args_to_ide_string(type_args: &[(Type, bool)], verbose: bool) - fn typed_id_list_to_ide_string( names: &[Name], types: &[Type], + list_start: char, + list_end: char, separate_lines: bool, verbose: bool, ) -> String { - names + let list = names .iter() .zip(types.iter()) .map(|(n, t)| { @@ -911,7 +1070,12 @@ fn typed_id_list_to_ide_string( } }) .collect::>() - .join(if separate_lines { ",\n" } else { ", " }) + .join(if separate_lines { ",\n" } else { ", " }); + if separate_lines && !list.is_empty() { + format!("{}\n{}\n{}", list_start, list, list_end) + } else { + format!("{}{}{}", list_start, list, list_end) + } } pub fn type_to_ide_string(sp!(_, t): &Type, verbose: bool) -> String { @@ -927,32 +1091,47 @@ pub fn type_to_ide_string(sp!(_, t): &Type, verbose: bool) -> String { } Type_::Apply(_, sp!(_, type_name), ss) => match type_name { TypeName_::Multiple(_) => { - format!("({})", type_list_to_ide_string(ss, verbose)) + format!( + "({})", + type_list_to_ide_string(ss, /* separate_lines */ false, verbose) + ) } TypeName_::Builtin(name) => { if ss.is_empty() { format!("{}", name) } else { - format!("{}<{}>", name, type_list_to_ide_string(ss, verbose)) + format!( + "{}<{}>", + name, + type_list_to_ide_string(ss, /* separate_lines */ false, verbose) + ) } } - TypeName_::ModuleType(sp!(_, module_ident), struct_name) => { + TypeName_::ModuleType(sp!(_, mod_ident), datatype_name) => { let type_args = if ss.is_empty() { "".to_string() } else { - format!("<{}>", type_list_to_ide_string(ss, verbose)) + format!( + "<{}>", + type_list_to_ide_string(ss, /* separate_lines */ false, verbose) + ) }; if verbose { - format!("{}::{}{}", module_ident, struct_name, type_args,) + format!( + "{}{}{}", + mod_ident_to_ide_string(mod_ident, Some(&datatype_name.value()), true), + datatype_name, + type_args + ) } else { - struct_name.to_string() + datatype_name.to_string() } } }, Type_::Fun(args, ret) => { format!( "|{}| -> {}", - type_list_to_ide_string(args, verbose), + type_list_to_ide_string(args, /* separate_lines */ false, verbose), type_to_ide_string(ret, verbose) ) } @@ -962,12 +1141,18 @@ pub fn type_to_ide_string(sp!(_, t): &Type, verbose: bool) -> String { } } -pub fn type_list_to_ide_string(types: &[Type], verbose: bool) -> String { +pub fn type_list_to_ide_string(types: &[Type], separate_lines: bool, verbose: bool) -> String { types .iter() - .map(|t| type_to_ide_string(t, verbose)) + .map(|t| { + if separate_lines { + format!("\t{}", type_to_ide_string(t, verbose)) + } else { + type_to_ide_string(t, verbose) + } + }) .collect::>() - .join(", ") + .join(if separate_lines { ",\n" } else { ", " }) } fn datatype_type_list_to_ide_string(types: &[(Type, bool)], verbose: bool) -> String { @@ -1085,15 +1270,60 @@ fn ast_value_to_ide_string(sp!(_, val): &Value) -> String { } } -pub fn mod_ident_to_ide_string(mod_ident: &E::ModuleIdent_) -> String { +/// Creates a string representing a module ID, either on it's owne as in +/// `pkg::module` or as part of a datatype or function type, in which it should +/// be `pkg::module::`. If it's part of the datatype, name of the datatype is +/// passed in `datatype_name_opt`. +pub fn mod_ident_to_ide_string( + mod_ident: &ModuleIdent_, + datatype_name_opt: Option<&Symbol>, + is_access_chain_prefix: bool, // part of access chaing that should end with `::` +) -> String { use E::Address as A; + // the module ID is to be a prefix to a data + let suffix = if is_access_chain_prefix { "::" } else { "" }; match mod_ident.address { - A::Numerical { - name: None, value, .. - } => format!("{value}::{}", mod_ident.module).to_string(), - A::Numerical { name: Some(n), .. } | A::NamedUnassigned(n) => { - format!("{n}::{}", mod_ident.module).to_string() + A::Numerical { name, value, .. } => { + let pkg_name = match name { + Some(n) => n.to_string(), + None => value.to_string(), + }; + + let Ok(std_lib_pkg_address) = AccountAddress::from_hex_literal(STD_LIB_PKG_ADDRESS) + else { + // getting stdlib address did not work - use the whole thing + return format!("{pkg_name}::{}{}", mod_ident.module, suffix); + }; + if value.value.into_inner() != std_lib_pkg_address { + // it's not a stdlib package - use the whole thing + return format!("{pkg_name}::{}{}", mod_ident.module, suffix); + } + // try stripping both package and module if this conversion + // is for a datatype, oherwise try only stripping package + if let Some(datatype_name) = datatype_name_opt { + if IMPLICIT_STD_MEMBERS.iter().any( + |(implicit_mod_name, implicit_datatype_name, _)| { + mod_ident.module.value() == *implicit_mod_name + && datatype_name == implicit_datatype_name + }, + ) { + // strip both package and module (whether its meant to be + // part of access chain or not, if there is not module, + // there should be no `::` at the end) + return "".to_string(); + } + } + if IMPLICIT_STD_MODULES + .iter() + .any(|implicit_mod_name| mod_ident.module.value() == *implicit_mod_name) + { + // strip package + return format!("{}{}", mod_ident.module.value(), suffix); + } + // stripping prefix didn't work - use the whole thing + format!("{pkg_name}::{}{}", mod_ident.module, suffix) } + A::NamedUnassigned(n) => format!("{n}::{}", mod_ident.module).to_string(), } } @@ -1155,7 +1385,7 @@ impl SymbolicatorRunner { pub fn new( ide_files_root: VfsPath, symbols_map: Arc>>, - pkg_deps: Arc>>, + pkg_deps: Arc>>, sender: Sender>>>, lint: LintLevel, ) -> Self { @@ -1172,10 +1402,9 @@ impl SymbolicatorRunner { // infinite loop to wait for symbolication requests eprintln!("starting symbolicator runner loop"); loop { - let starting_path_opt = { - // hold the lock only as long as it takes to get the data, rather than - // through the whole symbolication process (hence a - // separate scope here) + let all_starting_paths_opt = { + // hold the lock only as long as it takes to get the data, rather than through + // the whole symbolication process (hence a separate scope here) let mut symbolicate = mtx.lock().unwrap(); match symbolicate.clone() { RunnerState::Quit => break, @@ -1197,57 +1426,64 @@ impl SymbolicatorRunner { } } }; - if let Some(starting_path) = starting_path_opt { - let root_dir = Self::root_dir(&starting_path); - if root_dir.is_none() && !missing_manifests.contains(&starting_path) { - eprintln!("reporting missing manifest"); - - // report missing manifest file only once to avoid cluttering IDE's UI - // in cases when developer indeed intended - // to open a standalone file that was - // not meant to compile - missing_manifests.insert(starting_path); - if let Err(err) = sender.send(Err(anyhow!( - "Unable to find package manifest. Make sure that - the source files are located in a sub-directory of a package containing - a Move.toml file. " - ))) { - eprintln!("could not pass missing manifest error: {:?}", err); + if let Some(all_starting_paths) = all_starting_paths_opt { + let mut pkgs_to_analyze = BTreeMap::new(); + for starting_path in &all_starting_paths { + let root_dir = Self::root_dir(starting_path); + if root_dir.is_none() { + if !missing_manifests.contains(starting_path) { + eprintln!("reporting missing manifest"); + + // report missing manifest file only once to avoid cluttering IDE's UI in + // cases when developer indeed intended to open a standalone file that was + // not meant to compile + missing_manifests.insert(starting_path.clone()); + if let Err(err) = sender.send(Err(anyhow!( + "Unable to find package manifest. Make sure that + the source files are located in a sub-directory of a package containing + a Move.toml file. " + ))) { + eprintln!("could not pass missing manifest error: {:?}", err); + } + } + continue; } - continue; + pkgs_to_analyze + .entry(root_dir.unwrap()) + .or_insert_with(BTreeSet::new) + .insert(starting_path.clone()); } - eprintln!("symbolication started"); - let pkg_path = root_dir.unwrap(); - match get_symbols( - pkg_deps.clone(), - ide_files_root.clone(), - pkg_path.as_path(), - lint, - None, - ) { - Ok((symbols_opt, lsp_diagnostics)) => { - eprintln!("symbolication finished"); - if let Some(new_symbols) = symbols_opt { - // replace symbolication info for a given package - // - // TODO: we may consider "unloading" symbolication information - // when files/directories - // are being closed but as with other performance - // optimizations (e.g. incrementalizatino of the vfs), let's - // wait until we know we - // actually need it - let mut old_symbols_map = symbols_map.lock().unwrap(); - old_symbols_map.insert(pkg_path, new_symbols); - } - // set/reset (previous) diagnostics - if let Err(err) = sender.send(Ok(lsp_diagnostics)) { - eprintln!("could not pass diagnostics: {:?}", err); + for pkg_path in pkgs_to_analyze.keys() { + eprintln!("symbolication started"); + match get_symbols( + pkg_deps.clone(), + ide_files_root.clone(), + pkg_path.as_path(), + lint, + None, + ) { + Ok((symbols_opt, lsp_diagnostics)) => { + eprintln!("symbolication finished"); + if let Some(new_symbols) = symbols_opt { + // replace symbolication info for a given package + // + // TODO: we may consider "unloading" symbolication information when + // files/directories are being closed but as with other performance + // optimizations (e.g. incrementalizatino of the vfs), let's wait + // until we know we actually need it + let mut old_symbols_map = symbols_map.lock().unwrap(); + old_symbols_map.insert(pkg_path.clone(), new_symbols); + } + // set/reset (previous) diagnostics + if let Err(err) = sender.send(Ok(lsp_diagnostics)) { + eprintln!("could not pass diagnostics: {:?}", err); + } } - } - Err(err) => { - eprintln!("symbolication failed: {:?}", err); - if let Err(err) = sender.send(Err(err)) { - eprintln!("could not pass compiler error: {:?}", err); + Err(err) => { + eprintln!("symbolication failed: {:?}", err); + if let Err(err) = sender.send(Err(err)) { + eprintln!("could not pass compiler error: {:?}", err); + } } } } @@ -1263,7 +1499,18 @@ impl SymbolicatorRunner { eprintln!("scheduling run for {:?}", starting_path); let (mtx, cvar) = &*self.mtx_cvar; let mut symbolicate = mtx.lock().unwrap(); - *symbolicate = RunnerState::Run(starting_path); + match symbolicate.clone() { + RunnerState::Quit => (), // do nothing as we are quitting + RunnerState::Run(mut all_starting_paths) => { + all_starting_paths.insert(starting_path); + *symbolicate = RunnerState::Run(all_starting_paths); + } + RunnerState::Wait => { + let mut all_starting_paths = BTreeSet::new(); + all_starting_paths.insert(starting_path); + *symbolicate = RunnerState::Run(all_starting_paths); + } + } cvar.notify_one(); eprintln!("scheduled run"); } @@ -1500,17 +1747,11 @@ impl UseDefMap { self.0.len() } - pub fn extend_inner(&mut self, use_defs: BTreeMap>) { + pub fn extend(&mut self, use_defs: BTreeMap>) { for (k, v) in use_defs { self.0.entry(k).or_default().extend(v); } } - - pub fn extend(&mut self, use_defs: Self) { - for (k, v) in use_defs.0 { - self.0.entry(k).or_default().extend(v); - } - } } impl Symbols { @@ -1545,24 +1786,20 @@ impl Symbols { fn has_precompiled_deps( pkg_path: &Path, - pkg_dependencies: Arc>>, + pkg_dependencies: Arc>>, ) -> bool { let pkg_deps = pkg_dependencies.lock().unwrap(); pkg_deps.contains_key(pkg_path) } -/// Main driver to get symbols for the whole package. Returned symbols is an -/// option as only the correctly computed symbols should be a replacement for -/// the old set - if symbols are not actually (re)computed and the diagnostics -/// are returned, the old symbolic information should be retained even if it's -/// getting out-of-date. -pub fn get_symbols( - pkg_dependencies: Arc>>, +/// Builds a package at a given path and, if successful, returns parsed AST +/// and typed AST as well as (regardless of success) diagnostics. +pub fn get_compiled_pkg( + pkg_dependencies: Arc>>, ide_files_root: VfsPath, pkg_path: &Path, lint: LintLevel, - cursor_info: Option<(&PathBuf, Position)>, -) -> Result<(Option, BTreeMap>)> { +) -> Result<(Option, BTreeMap>)> { let build_config = move_package::BuildConfig { test_mode: true, install_dir: Some(tempdir().unwrap().path().to_path_buf()), @@ -1619,7 +1856,7 @@ pub fn get_symbols( let mut diagnostics = None; let mut dependencies = build_plan.compute_dependencies(); - let compiled_libs = if let Ok(deps_package_paths) = dependencies.make_deps_for_compiler() { + let cached_deps = if let Ok(deps_package_paths) = dependencies.make_deps_for_compiler() { // Partition deps_package according whether src is available let src_deps = deps_package_paths .iter() @@ -1637,16 +1874,19 @@ pub fn get_symbols( .filter_map(|p| p.name.as_ref().map(|(n, _)| *n)) .collect::>(); - let mut pkg_deps = pkg_dependencies.lock().unwrap(); - let compiled_deps = match pkg_deps.get(pkg_path) { + let pkg_deps = pkg_dependencies.lock().unwrap(); + let pkg_cached_deps = match pkg_deps.get(pkg_path) { Some(d) if manifest_hash.is_some() && manifest_hash == d.manifest_hash && deps_hash == d.deps_hash => { - eprintln!("found pre-compiled libs for {:?}", pkg_path); + eprintln!("found cached deps for {:?}", pkg_path); mapped_files.extend_with_duplicates(d.deps.files.clone()); - Some(d.deps.clone()) + Some(CachedDeps { + compiled_program: d.deps.clone(), + symbols_data: Some(d.deps_symbols_data.clone()), + }) } _ => construct_pre_compiled_lib( src_deps, @@ -1659,36 +1899,34 @@ pub fn get_symbols( .map(|libs| { eprintln!("created pre-compiled libs for {:?}", pkg_path); mapped_files.extend_with_duplicates(libs.files.clone()); - let deps = Arc::new(libs); - pkg_deps.insert( - pkg_path.to_path_buf(), - PrecompiledPkgDeps { - manifest_hash, - deps_hash, - deps: deps.clone(), - }, - ); - deps + CachedDeps { + compiled_program: Arc::new(libs), + symbols_data: None, + } }), }; - if compiled_deps.is_some() { + if pkg_cached_deps.is_some() { // if successful, remove only source deps but keep bytecode deps as they // were not used to construct pre-compiled lib in the first place dependencies.remove_deps(src_names); } - compiled_deps + pkg_cached_deps } else { None }; let mut edition = None; + let mut comments = None; + let compiled_libs = cached_deps + .clone() + .map(|deps| deps.compiled_program.clone()); build_plan.compile_with_driver_and_deps(dependencies, &mut std::io::sink(), |compiler| { let compiler = compiler.set_ide_mode(); // extract expansion AST let (files, compilation_result) = compiler .set_pre_compiled_lib_opt(compiled_libs.clone()) .run::()?; - let (_, compiler) = match compilation_result { + let (comments_map, compiler) = match compilation_result { Ok(v) => v, Err((_pass, diags)) => { let failure = true; @@ -1697,10 +1935,11 @@ pub fn get_symbols( return Ok((files, vec![])); } }; + comments = Some(comments_map); eprintln!("compiled to parsed AST"); let (compiler, parsed_program) = compiler.into_ast(); parsed_ast = Some(parsed_program.clone()); - mapped_files.extend_with_duplicates(compiler.compilation_env_ref().mapped_files().clone()); + mapped_files.extend_with_duplicates(compiler.compilation_env().mapped_files().clone()); // extract typed AST let compilation_result = compiler.at_parser(parsed_program).run::(); @@ -1715,17 +1954,17 @@ pub fn get_symbols( } }; eprintln!("compiled to typed AST"); - let (mut compiler, typed_program) = compiler.into_ast(); + let (compiler, typed_program) = compiler.into_ast(); typed_ast = Some(typed_program.clone()); compiler_info = Some(CompilerInfo::from( - compiler.compilation_env().ide_information.clone(), + compiler.compilation_env().ide_information().clone(), )); edition = Some(compiler.compilation_env().edition(Some(root_pkg_name))); // compile to CFGIR for accurate diags eprintln!("compiling to CFGIR"); let compilation_result = compiler.at_typing(typed_program).run::(); - let mut compiler = match compilation_result { + let compiler = match compilation_result { Ok(v) => v, Err((_pass, diags)) => { let failure = false; @@ -1760,135 +1999,362 @@ pub fn get_symbols( // uwrap's are safe - this function returns earlier (during diagnostics // processing) when failing to produce the ASTs let parsed_program = parsed_ast.unwrap(); - let mut typed_program = typed_ast.clone().unwrap(); - - let mut mod_outer_defs = BTreeMap::new(); - let mut mod_use_defs = BTreeMap::new(); - let mut references = BTreeMap::new(); - let mut def_info = BTreeMap::new(); - - let mut file_id_to_lines = HashMap::new(); - for file_id in mapped_files.file_mapping().values() { - let Ok(file) = mapped_files.files().get(*file_id) else { - eprintln!("file id without source code"); - continue; - }; - let source = file.source(); - let lines: Vec = source.lines().map(String::from).collect(); - file_id_to_lines.insert(*file_id, lines); - } + let typed_program = typed_ast.clone().unwrap(); + let mut all_comments = comments.unwrap(); + if let Some(libs) = &compiled_libs { + all_comments.extend(libs.comments.clone()); + } + let compiled_pkg_info = CompiledPkgInfo { + path: pkg_path.into(), + manifest_hash, + deps_hash, + cached_deps, + program: CompiledProgram { + parsed: parsed_program, + typed: typed_program, + }, + source_files, + mapped_files, + edition, + compiler_info, + all_comments, + }; + Ok((Some(compiled_pkg_info), ide_diagnostics)) +} - let mut cursor_context = compute_cursor_context(&mapped_files, cursor_info); +/// Preprocess parsed and typed programs prior to actual symbols computation. +pub fn compute_symbols_pre_process( + computation_data: &mut SymbolsComputationData, + computation_data_deps: &mut SymbolsComputationData, + compiled_pkg_info: &mut CompiledPkgInfo, + cursor_info: Option<(&PathBuf, Position)>, +) -> Option { + let mut fields_order_info = FieldOrderInfo::new(); + let parsed_program = &compiled_pkg_info.program.parsed; + let typed_program = &compiled_pkg_info.program.typed; + pre_process_parsed_program(parsed_program, &mut fields_order_info); + let mut cursor_context = compute_cursor_context(&compiled_pkg_info.mapped_files, cursor_info); pre_process_typed_modules( &typed_program.modules, - &mapped_files, - &file_id_to_lines, - &mut mod_outer_defs, - &mut mod_use_defs, - &mut references, - &mut def_info, - &edition, + &fields_order_info, + &compiled_pkg_info.mapped_files, + &mut computation_data.mod_outer_defs, + &mut computation_data.mod_use_defs, + &mut computation_data.references, + &mut computation_data.def_info, + &compiled_pkg_info.edition, cursor_context.as_mut(), + &compiled_pkg_info.all_comments, ); - if let Some(libs) = compiled_libs.clone() { - pre_process_typed_modules( - &libs.typing.modules, - &mapped_files, - &file_id_to_lines, - &mut mod_outer_defs, - &mut mod_use_defs, - &mut references, - &mut def_info, - &edition, - None, // Cursor can never be in a compiled library(?) - ); + if let Some(cached_deps) = compiled_pkg_info.cached_deps.clone() { + // we have at least compiled program available + let (deps_mod_outer_defs, deps_def_info) = + if let Some(cached_symbols_data) = cached_deps.symbols_data { + // We have cached results of the dependency symbols computation from the + // previous run. + ( + cached_symbols_data.mod_outer_defs.clone(), + cached_symbols_data.def_info.clone(), + ) + } else { + // No cached dependency symbols data but we still have cached compilation + // results. Fill out dependency symbols from compiled package + // info to cache them at the end of analysis + pre_process_typed_modules( + &cached_deps.compiled_program.typing.modules, + &FieldOrderInfo::new(), + &compiled_pkg_info.mapped_files, + &mut computation_data_deps.mod_outer_defs, + &mut computation_data_deps.mod_use_defs, + &mut computation_data_deps.references, + &mut computation_data_deps.def_info, + &compiled_pkg_info.edition, + None, // Cursor can never be in a compiled library(?) + &compiled_pkg_info.all_comments, + ); + ( + computation_data_deps.mod_outer_defs.clone(), + computation_data_deps.def_info.clone(), + ) + }; + // We need to update definitions for the code being currently processed + // so that these definitions are available when ASTs for this code are visited + computation_data.mod_outer_defs.extend(deps_mod_outer_defs); + computation_data.def_info.extend(deps_def_info); } - eprintln!("get_symbols loaded"); - - let mut file_use_defs = BTreeMap::new(); - let mut mod_to_alias_lengths = BTreeMap::new(); + cursor_context +} +/// Run parsing analysis for either main program or dependencies +fn run_parsing_analysis( + computation_data: &mut SymbolsComputationData, + compiled_pkg_info: &CompiledPkgInfo, + cursor_context: Option<&mut CursorContext>, + parsed_program: &P::Program, +) { let mut parsing_symbolicator = parsing_analysis::ParsingAnalysisContext { - mod_outer_defs: &mut mod_outer_defs, - files: &mapped_files, - references: &mut references, - def_info: &mut def_info, + mod_outer_defs: &mut computation_data.mod_outer_defs, + files: &compiled_pkg_info.mapped_files, + references: &mut computation_data.references, + def_info: &mut computation_data.def_info, use_defs: UseDefMap::new(), current_mod_ident_str: None, alias_lengths: BTreeMap::new(), pkg_addresses: &NamedAddressMap::new(), - cursor: cursor_context.as_mut(), + cursor: cursor_context, }; parsing_symbolicator.prog_symbols( - &parsed_program, - &mut mod_use_defs, - &mut mod_to_alias_lengths, + parsed_program, + &mut computation_data.mod_use_defs, + &mut computation_data.mod_to_alias_lengths, ); - if let Some(libs) = compiled_libs.clone() { - parsing_symbolicator.cursor = None; - parsing_symbolicator.prog_symbols( - &libs.parser, - &mut mod_use_defs, - &mut mod_to_alias_lengths, - ); +} + +/// Process parsed program for symbols computation. +pub fn compute_symbols_parsed_program( + computation_data: &mut SymbolsComputationData, + computation_data_deps: &mut SymbolsComputationData, + compiled_pkg_info: &CompiledPkgInfo, + mut cursor_context: Option, +) -> Option { + run_parsing_analysis( + computation_data, + compiled_pkg_info, + cursor_context.as_mut(), + &compiled_pkg_info.program.parsed, + ); + if let Some(cached_deps) = &compiled_pkg_info.cached_deps { + // run parsing analysis only if cached symbols computation data + // is not available to fill out dependency symbols from compiled package info + // to cache them at the end of analysis + if cached_deps.symbols_data.is_none() { + run_parsing_analysis( + computation_data_deps, + compiled_pkg_info, + None, + &cached_deps.compiled_program.parser, + ); + } } + cursor_context +} - let mut compiler_info = compiler_info.unwrap(); +/// Run typing analysis for either main program or dependencies +fn run_typing_analysis( + mut computation_data: SymbolsComputationData, + mapped_files: &MappedFiles, + compiler_info: &mut CompilerInfo, + typed_program: &T::Program, +) -> SymbolsComputationData { let mut typing_symbolicator = typing_analysis::TypingAnalysisContext { - mod_outer_defs: &mut mod_outer_defs, - files: &mapped_files, - references: &mut references, - def_info: &mut def_info, + mod_outer_defs: &mut computation_data.mod_outer_defs, + files: mapped_files, + references: &mut computation_data.references, + def_info: &mut computation_data.def_info, use_defs: UseDefMap::new(), current_mod_ident_str: None, alias_lengths: &BTreeMap::new(), traverse_only: false, - compiler_info: &mut compiler_info, + compiler_info, type_params: BTreeMap::new(), expression_scope: OrdMap::new(), }; process_typed_modules( - &mut typed_program.modules, - &source_files, - &mod_to_alias_lengths, + &typed_program.modules, + &computation_data.mod_to_alias_lengths, &mut typing_symbolicator, - &mut file_use_defs, - &mut mod_use_defs, + &mut computation_data.mod_use_defs, ); + computation_data +} - if let Some(libs) = compiled_libs { - process_typed_modules( - &mut libs.typing.modules.clone(), - &source_files, - &mod_to_alias_lengths, - &mut typing_symbolicator, - &mut file_use_defs, - &mut mod_use_defs, - ); - } +// Given use-defs for a the main program or dependencies, update the per-file +// use-def map +fn update_file_use_defs( + computation_data: &SymbolsComputationData, + source_files: &SourceFiles, + file_use_defs: &mut FileUseDefs, +) { + for (module_ident_str, use_defs) in &computation_data.mod_use_defs { + // unwrap here is safe as all modules in a given program have the module_defs + // entry in the map + let module_defs = computation_data + .mod_outer_defs + .get(module_ident_str) + .unwrap(); + let fpath = match source_files.get(&module_defs.fhash) { + Some((p, _, _)) => p, + None => return, + }; + + let fpath_buffer = + dunce::canonicalize(fpath.as_str()).unwrap_or_else(|_| PathBuf::from(fpath.as_str())); + + file_use_defs + .entry(fpath_buffer) + .or_default() + .extend(use_defs.clone().elements()); + } +} + +/// Process typed program for symbols computation. +pub fn compute_symbols_typed_program( + computation_data: SymbolsComputationData, + computation_data_deps: SymbolsComputationData, + mut compiled_pkg_info: CompiledPkgInfo, + cursor_context: Option, +) -> (Symbols, Option>) { + // run typing analysis for the main user program + let compiler_info = &mut compiled_pkg_info.compiler_info.as_mut().unwrap(); + let mapped_files = &compiled_pkg_info.mapped_files; + let source_files = &compiled_pkg_info.source_files; + let mut computation_data = run_typing_analysis( + computation_data, + mapped_files, + compiler_info, + &compiled_pkg_info.program.typed, + ); + let mut file_use_defs = BTreeMap::new(); + update_file_use_defs(&computation_data, source_files, &mut file_use_defs); + + let cacheable_symbols_data_opt = + if let Some(cached_deps) = compiled_pkg_info.cached_deps.clone() { + // we have at least compiled program available + let deps_symbols_data = if let Some(cached_symbols_data) = cached_deps.symbols_data { + // We have cached results of the dependency symbols computation from the + // previous run. + cached_symbols_data + } else { + // No cached dependency symbols data but we still have cached compilation + // results. Fill out dependency symbols from compiled package + // info to cache them at the end of analysis + let computation_data_deps = run_typing_analysis( + computation_data_deps, + mapped_files, + compiler_info, + &cached_deps.compiled_program.typing, + ); + Arc::new(computation_data_deps) + }; + // create `file_use_defs` map and merge references to produce complete symbols + // data (mod_outer_defs and def_info have already been merged to + // facilitate user program analysis) + update_file_use_defs(&deps_symbols_data, source_files, &mut file_use_defs); + for (def_loc, uses) in &deps_symbols_data.references { + computation_data + .references + .entry(*def_loc) + .or_default() + .extend(uses); + } + Some(deps_symbols_data) + } else { + None + }; let mut file_mods: FileModules = BTreeMap::new(); - for d in mod_outer_defs.into_values() { - let path = mapped_files.file_path(&d.fhash.clone()); + for d in computation_data.mod_outer_defs.into_values() { + let path = compiled_pkg_info.mapped_files.file_path(&d.fhash.clone()); file_mods.entry(path.to_path_buf()).or_default().insert(d); } - let symbols = Symbols { - references, - file_use_defs, - file_mods, - def_info, - files: mapped_files, - compiler_info, + ( + Symbols { + references: computation_data.references, + file_use_defs, + file_mods, + def_info: computation_data.def_info, + files: compiled_pkg_info.mapped_files, + compiler_info: compiled_pkg_info.compiler_info.unwrap(), + cursor_context, + }, + cacheable_symbols_data_opt, + ) +} + +/// Compute symbols for a given package from the parsed and typed ASTs, +/// as well as other auxiliary data provided in `compiled_pkg_info`. +pub fn compute_symbols( + pkg_dependencies: Arc>>, + mut compiled_pkg_info: CompiledPkgInfo, + cursor_info: Option<(&PathBuf, Position)>, +) -> Symbols { + let pkg_path = compiled_pkg_info.path.clone(); + let manifest_hash = compiled_pkg_info.manifest_hash; + let cached_dep_opt = compiled_pkg_info.cached_deps.clone(); + let deps_hash = compiled_pkg_info.deps_hash.clone(); + let mut symbols_computation_data = SymbolsComputationData::new(); + let mut symbols_computation_data_deps = SymbolsComputationData::new(); + let cursor_context = compute_symbols_pre_process( + &mut symbols_computation_data, + &mut symbols_computation_data_deps, + &mut compiled_pkg_info, + cursor_info, + ); + let cursor_context = compute_symbols_parsed_program( + &mut symbols_computation_data, + &mut symbols_computation_data_deps, + &compiled_pkg_info, cursor_context, - typed_ast, - }; + ); + + let (symbols, cacheable_symbols_data_opt) = compute_symbols_typed_program( + symbols_computation_data, + symbols_computation_data_deps, + compiled_pkg_info, + cursor_context, + ); + let mut pkg_deps = pkg_dependencies.lock().unwrap(); + + if let Some(cached_deps) = cached_dep_opt { + // we have at least compiled program available, either already cached + // or created for the purpose of this analysis + if cached_deps.symbols_data.is_none() { + // if no symbols computation data was cached, it means that + // compiled program was created for the purpose of this analysis + // and we need to cache both + if let Some(deps_symbols_data) = cacheable_symbols_data_opt { + eprintln!("caching pre-compiled program and pre-computed symbols"); + pkg_deps.insert(pkg_path, PrecomputedPkgDepsInfo { + manifest_hash, + deps_hash, + deps: cached_deps.compiled_program.clone(), + deps_symbols_data, + }); + } + } + } + symbols +} + +/// Main driver to get symbols for the whole package. Returned symbols is an +/// option as only the correctly computed symbols should be a replacement for +/// the old set - if symbols are not actually (re)computed and the diagnostics +/// are returned, the old symbolic information should be retained even if it's +/// getting out-of-date. +pub fn get_symbols( + pkg_dependencies: Arc>>, + ide_files_root: VfsPath, + pkg_path: &Path, + lint: LintLevel, + cursor_info: Option<(&PathBuf, Position)>, +) -> Result<(Option, BTreeMap>)> { + let compilation_start = Instant::now(); + let (compiled_pkg_info_opt, ide_diagnostics) = + get_compiled_pkg(pkg_dependencies.clone(), ide_files_root, pkg_path, lint)?; + eprintln!("compilation complete in: {:?}", compilation_start.elapsed()); + let Some(compiled_pkg_info) = compiled_pkg_info_opt else { + return Ok((None, ide_diagnostics)); + }; + let analysis_start = Instant::now(); + let symbols = compute_symbols(pkg_dependencies, compiled_pkg_info, cursor_info); + eprintln!("analysis complete in {:?}", analysis_start.elapsed()); eprintln!("get_symbols load complete"); Ok((Some(symbols), ide_diagnostics)) @@ -1905,16 +2371,79 @@ fn compute_cursor_context( Some(CursorContext::new(loc)) } +/// Pre-process parsed program to get initial info before AST traversals +fn pre_process_parsed_program(prog: &P::Program, fields_order_info: &mut FieldOrderInfo) { + prog.source_definitions.iter().for_each(|pkg_def| { + pre_process_parsed_pkg(pkg_def, &prog.named_address_maps, fields_order_info); + }); + prog.lib_definitions.iter().for_each(|pkg_def| { + pre_process_parsed_pkg(pkg_def, &prog.named_address_maps, fields_order_info); + }); +} + +/// Pre-process parsed package to get initial info before AST traversals +fn pre_process_parsed_pkg( + pkg_def: &P::PackageDefinition, + named_address_maps: &NamedAddressMaps, + fields_order_info: &mut FieldOrderInfo, +) { + if let P::Definition::Module(mod_def) = &pkg_def.def { + for member in &mod_def.members { + let pkg_addresses = named_address_maps.get(pkg_def.named_address_map); + let Some(mod_ident_str) = parsing_mod_def_to_map_key(pkg_addresses, mod_def) else { + continue; + }; + if let P::ModuleMember::Struct(sdef) = member { + if let P::StructFields::Named(fields) = &sdef.fields { + let indexed_fields = fields + .iter() + .enumerate() + .map(|(i, (f, _))| (f.value(), i)) + .collect::>(); + fields_order_info + .structs + .entry(mod_ident_str.clone()) + .or_default() + .entry(sdef.name.value()) + .or_default() + .extend(indexed_fields); + } + } + if let P::ModuleMember::Enum(edef) = member { + for vdef in &edef.variants { + if let P::VariantFields::Named(fields) = &vdef.fields { + let indexed_fields = fields + .iter() + .enumerate() + .map(|(i, (f, _))| (f.value(), i)) + .collect::>(); + fields_order_info + .variants + .entry(mod_ident_str.clone()) + .or_default() + .entry(edef.name.value()) + .or_default() + .entry(vdef.name.value()) + .or_default() + .extend(indexed_fields); + } + } + } + } + } +} + fn pre_process_typed_modules( typed_modules: &UniqueMap, + fields_order_info: &FieldOrderInfo, files: &MappedFiles, - file_id_to_lines: &HashMap>, mod_outer_defs: &mut BTreeMap, mod_use_defs: &mut BTreeMap, references: &mut References, def_info: &mut DefMap, edition: &Option, mut cursor_context: Option<&mut CursorContext>, + all_comments: &CommentMap, ) { for (pos, module_ident, module_def) in typed_modules { // If the cursor is in this module, mark that down. @@ -1928,12 +2457,14 @@ fn pre_process_typed_modules( let (defs, symbols) = get_mod_outer_defs( &pos, &sp(pos, *module_ident), + mod_ident_str.clone(), module_def, + fields_order_info, files, - file_id_to_lines, references, def_info, edition, + all_comments, ); mod_outer_defs.insert(mod_ident_str.clone(), defs); mod_use_defs.insert(mod_ident_str, symbols); @@ -1941,39 +2472,23 @@ fn pre_process_typed_modules( } fn process_typed_modules<'a>( - typed_modules: &mut UniqueMap, - source_files: &BTreeMap, + typed_modules: &UniqueMap, mod_to_alias_lengths: &'a BTreeMap>, typing_symbolicator: &mut typing_analysis::TypingAnalysisContext<'a>, - file_use_defs: &mut FileUseDefs, mod_use_defs: &mut BTreeMap, ) { - for (module_ident, module_def) in typed_modules.key_cloned_iter_mut() { + for (module_ident, module_def) in typed_modules.key_cloned_iter() { let mod_ident_str = expansion_mod_ident_to_map_key(&module_ident.value); typing_symbolicator.use_defs = mod_use_defs.remove(&mod_ident_str).unwrap(); typing_symbolicator.alias_lengths = mod_to_alias_lengths.get(&mod_ident_str).unwrap(); typing_symbolicator.visit_module(module_ident, module_def); - let fpath = match source_files.get(&module_ident.loc.file_hash()) { - Some((p, _, _)) => p, - None => continue, - }; - - let fpath_buffer = - dunce::canonicalize(fpath.as_str()).unwrap_or_else(|_| PathBuf::from(fpath.as_str())); - let use_defs = std::mem::replace(&mut typing_symbolicator.use_defs, UseDefMap::new()); - file_use_defs - .entry(fpath_buffer) - .or_default() - .extend_inner(use_defs.elements()); + mod_use_defs.insert(mod_ident_str, use_defs); } } -fn file_sources( - resolved_graph: &ResolvedGraph, - overlay_fs: VfsPath, -) -> BTreeMap { +fn file_sources(resolved_graph: &ResolvedGraph, overlay_fs: VfsPath) -> SourceFiles { resolved_graph .package_table .iter() @@ -2012,11 +2527,78 @@ fn file_sources( pub fn expansion_mod_ident_to_map_key(mod_ident: &E::ModuleIdent_) -> String { use E::Address as A; match mod_ident.address { - A::Numerical { value, .. } => format!("{value}::{}", mod_ident.module).to_string(), + A::Numerical { + name, + value, + name_conflict: _, + } => { + if let Some(n) = name { + format!("({n}={value})::{}", mod_ident.module).to_string() + } else { + format!("{value}::{}", mod_ident.module).to_string() + } + } A::NamedUnassigned(n) => format!("{n}::{}", mod_ident.module).to_string(), } } +/// Converts parsing AST's `LeadingNameAccess` to expansion AST's `Address` +/// (similarly to expansion::translate::top_level_address but disregarding the +/// name portion of `Address` as we only care about actual address here if it's +/// available). We need this to be able to reliably compare parsing AST's module +/// identifier with expansion/typing AST's module identifier, even in +/// presence of module renaming (i.e., we cannot rely on module names if +/// addresses are available). +pub fn parsed_address(ln: P::LeadingNameAccess, pkg_addresses: &NamedAddressMap) -> E::Address { + let sp!(loc, ln_) = ln; + match ln_ { + P::LeadingNameAccess_::AnonymousAddress(bytes) => E::Address::anonymous(loc, bytes), + P::LeadingNameAccess_::GlobalAddress(name) => E::Address::NamedUnassigned(name), + P::LeadingNameAccess_::Name(name) => match pkg_addresses.get(&name.value).copied() { + // set `name_conflict` to `true` to force displaying (addr==pkg_name) so that the string + // representing map key is consistent with what's generated for expansion ModuleIdent in + // `expansion_mod_ident_to_map_key` + Some(addr) => E::Address::Numerical { + name: Some(name), + value: sp(loc, addr), + name_conflict: true, + }, + None => E::Address::NamedUnassigned(name), + }, + } +} + +/// Produces module ident string of the form pkg::module to be used as a map +/// key. It's important that these are consistent between parsing AST and typed +/// AST. +pub fn parsing_leading_and_mod_names_to_map_key( + pkg_addresses: &NamedAddressMap, + ln: P::LeadingNameAccess, + name: P::ModuleName, +) -> String { + let parsed_addr = parsed_address(ln, pkg_addresses); + format!("{}::{}", parsed_addr, name).to_string() +} + +/// Produces module ident string of the form pkg::module to be used as a map +/// key. It's important that these are consistent between parsing AST and typed +/// AST. +pub fn parsing_mod_def_to_map_key( + pkg_addresses: &NamedAddressMap, + mod_def: &P::ModuleDefinition, +) -> Option { + // we assume that modules are declared using the PkgName::ModName pattern (which + // seems to be the standard practice) and while Move allows other ways of + // defining modules (i.e., with address preceding a sequence of modules), + // this method is now deprecated. + // + // TODO: make this function simply return String when the other way of defining + // modules is removed + mod_def + .address + .map(|a| parsing_leading_and_mod_names_to_map_key(pkg_addresses, a, mod_def.name)) +} + /// Get empty symbols pub fn empty_symbols() -> Symbols { Symbols { @@ -2027,38 +2609,52 @@ pub fn empty_symbols() -> Symbols { files: MappedFiles::empty(), compiler_info: CompilerInfo::new(), cursor_context: None, - typed_ast: None, } } +/// Get optional doc comment string at a given location. +fn get_doc_string(all_comments: &CommentMap, loc: Loc) -> Option { + all_comments + .get(&loc.file_hash()) + .and_then(|m| m.get(&loc.start())) + .cloned() +} + fn field_defs_and_types( datatype_name: Symbol, - datatype_loc: Loc, fields: &E::Fields, + fields_order_opt: Option<&BTreeMap>, mod_ident: &ModuleIdent, - files: &MappedFiles, - file_id_to_lines: &HashMap>, def_info: &mut DefMap, + all_comments: &CommentMap, ) -> (Vec, Vec) { let mut field_defs = vec![]; let mut field_types = vec![]; - for (floc, fname, (_, t)) in fields { + let mut ordered_fields = fields + .iter() + .map(|(floc, fname, (_, ftype))| (floc, fname, ftype)) + .collect::>(); + // sort fields by order if available for correct auto-completion + if let Some(fields_order) = fields_order_opt { + ordered_fields.sort_by_key(|(_, fname, _)| fields_order.get(fname).copied()); + } + for (floc, fname, ftype) in ordered_fields { field_defs.push(FieldDef { name: *fname, loc: floc, }); - let doc_string = extract_doc_string(files, file_id_to_lines, &floc, Some(datatype_loc)); + let doc_string = get_doc_string(all_comments, floc); def_info.insert( floc, DefInfo::Field( mod_ident.value, datatype_name, *fname, - t.clone(), + ftype.clone(), doc_string, ), ); - field_types.push(t.clone()); + field_types.push(ftype.clone()); } (field_defs, field_types) } @@ -2092,12 +2688,14 @@ pub fn ignored_function(name: Symbol) -> bool { fn get_mod_outer_defs( loc: &Loc, mod_ident: &ModuleIdent, + mod_ident_str: String, mod_def: &ModuleDefinition, + fields_order_info: &FieldOrderInfo, files: &MappedFiles, - file_id_to_lines: &HashMap>, references: &mut References, def_info: &mut DefMap, edition: &Option, + all_comments: &CommentMap, ) -> (ModuleDefs, UseDefMap) { let mut structs = BTreeMap::new(); let mut enums = BTreeMap::new(); @@ -2112,29 +2710,29 @@ fn get_mod_outer_defs( let mut field_types = vec![]; if let StructFields::Defined(pos_fields, fields) = &def.fields { positional = *pos_fields; + let fields_order_opt = fields_order_info + .structs + .get(&mod_ident_str) + .and_then(|s| s.get(name)); (field_defs, field_types) = field_defs_and_types( *name, - name_loc, fields, + fields_order_opt, mod_ident, - files, - file_id_to_lines, def_info, + all_comments, ); }; // process the struct itself let field_names = field_defs.iter().map(|f| sp(f.loc, f.name)).collect(); - structs.insert( - *name, - MemberDef { - name_loc, - info: MemberDefInfo::Struct { - field_defs, - positional, - }, + structs.insert(*name, MemberDef { + name_loc, + info: MemberDefInfo::Struct { + field_defs, + positional, }, - ); + }); let pub_struct = edition .map(|e| e.supports(FeatureGate::PositionalFields)) .unwrap_or(false); @@ -2144,7 +2742,7 @@ fn get_mod_outer_defs( } else { Visibility::Internal }; - let doc_string = extract_doc_string(files, file_id_to_lines, &name_loc, None); + let doc_string = get_doc_string(all_comments, def.loc); def_info.insert( name_loc, DefInfo::Struct( @@ -2167,14 +2765,18 @@ fn get_mod_outer_defs( for (vname_loc, vname, vdef) in &def.variants { let (field_defs, field_types, positional) = match &vdef.fields { VariantFields::Defined(pos_fields, fields) => { + let fields_order_opt = fields_order_info + .variants + .get(&mod_ident_str) + .and_then(|v| v.get(name)) + .and_then(|v| v.get(vname)); let (defs, types) = field_defs_and_types( *name, - name_loc, fields, + fields_order_opt, mod_ident, - files, - file_id_to_lines, def_info, + all_comments, ); (defs, types, *pos_fields) } @@ -2188,8 +2790,7 @@ fn get_mod_outer_defs( }); variants_info.insert(*vname, (vname_loc, field_defs, positional)); - let vdoc_string = - extract_doc_string(files, file_id_to_lines, &vname_loc, Some(name_loc)); + let vdoc_string = get_doc_string(all_comments, def.loc); def_info.insert( vname_loc, DefInfo::Variant( @@ -2204,14 +2805,11 @@ fn get_mod_outer_defs( ); } // process the enum itself - enums.insert( - *name, - MemberDef { - name_loc, - info: MemberDefInfo::Enum { variants_info }, - }, - ); - let enum_doc_string = extract_doc_string(files, file_id_to_lines, &name_loc, None); + enums.insert(*name, MemberDef { + name_loc, + info: MemberDefInfo::Enum { variants_info }, + }); + let enum_doc_string = get_doc_string(all_comments, def.loc); def_info.insert( name_loc, DefInfo::Enum( @@ -2227,14 +2825,11 @@ fn get_mod_outer_defs( } for (name_loc, name, c) in &mod_def.constants { - constants.insert( - *name, - MemberDef { - name_loc, - info: MemberDefInfo::Const, - }, - ); - let doc_string = extract_doc_string(files, file_id_to_lines, &name_loc, None); + constants.insert(*name, MemberDef { + name_loc, + info: MemberDefInfo::Const, + }); + let doc_string = get_doc_string(all_comments, c.loc); def_info.insert( name_loc, DefInfo::Const( @@ -2258,7 +2853,7 @@ fn get_mod_outer_defs( } else { FunType::Regular }; - let doc_string = extract_doc_string(files, file_id_to_lines, &name_loc, None); + let doc_string = get_doc_string(all_comments, fun.loc); let fun_info = DefInfo::Function( mod_ident.value, fun.visibility, @@ -2282,27 +2877,24 @@ fn get_mod_outer_defs( fun.signature.return_type.clone(), doc_string, ); - functions.insert( - *name, - MemberDef { - name_loc, - info: MemberDefInfo::Fun { - attrs: fun - .attributes - .clone() - .iter() - .map(|(_loc, name, _attr)| name.to_string()) - .collect(), - }, + functions.insert(*name, MemberDef { + name_loc, + info: MemberDefInfo::Fun { + attrs: fun + .attributes + .clone() + .iter() + .map(|(_loc, name, _attr)| name.to_string()) + .collect(), }, - ); + }); def_info.insert(name_loc, fun_info); } let mut use_def_map = UseDefMap::new(); let ident = mod_ident.value; - let doc_comment = extract_doc_string(files, file_id_to_lines, loc, None); + let doc_string = get_doc_string(all_comments, mod_def.loc); let mod_defs = ModuleDefs { fhash, ident, @@ -2332,7 +2924,7 @@ fn get_mod_outer_defs( ); def_info.insert( mod_defs.name_loc, - DefInfo::Module(mod_ident_to_ide_string(&ident), doc_comment), + DefInfo::Module(mod_ident_to_ide_string(&ident, None, false), doc_string), ); } @@ -2430,96 +3022,6 @@ pub fn find_datatype(mod_defs: &ModuleDefs, datatype_name: &Symbol) -> Option>, - loc: &Loc, - outer_def_loc: Option, -) -> Option { - let file_hash = loc.file_hash(); - let file_id = files.file_hash_to_file_id(&file_hash)?; - let start_position = files.start_position_opt(loc)?; - let file_lines = file_id_to_lines.get(&file_id)?; - - if let Some(outer_loc) = outer_def_loc { - if let Some(outer_pos) = files.start_position_opt(&outer_loc) { - if outer_pos.line_offset() == start_position.line_offset() { - // It's a bit of a hack but due to the way we extract doc strings - // we should not do it for a definition if this definition is placed - // on the same line as another (outer) one as this way we'd pick - // doc comment of the outer definition. For example (where field - // of the struct would pick up struct's doc comment) - // - // /// Struct doc comment - // public struct Tmp { field: u64 } - return None; - } - } - } - - if start_position.line_offset() == 0 { - return None; - } - - let mut iter = start_position.line_offset() - 1; - let mut line_before = file_lines[iter].trim(); - - let mut doc_string = String::new(); - // Detect the two different types of docstrings - if line_before.starts_with("///") { - while let Some(stripped_line) = line_before.strip_prefix("///") { - doc_string = format!("{}\n{}", stripped_line.trim(), doc_string); - if iter == 0 { - break; - } - iter -= 1; - line_before = file_lines[iter].trim(); - } - } else if line_before.ends_with("*/") { - let mut doc_string_found = false; - line_before = file_lines[iter].strip_suffix("*/").unwrap_or("").trim(); - - // Loop condition is a safe guard. - while !doc_string_found { - // We found the start of the multi-line comment/docstring - if line_before.starts_with("/*") { - let is_doc = line_before.starts_with("/**") && !line_before.starts_with("/***"); - - // Invalid doc_string start prefix. - if !is_doc { - return None; - } - - line_before = line_before.strip_prefix("/**").unwrap_or("").trim(); - doc_string_found = true; - } - - doc_string = format!("{}\n{}", line_before, doc_string); - - if iter == 0 { - break; - } - - iter -= 1; - line_before = file_lines[iter].trim(); - } - - // No doc_string found - return String::new(); - if !doc_string_found { - return None; - } - } - - // No point in trying to print empty comment - if doc_string.is_empty() { - return None; - } - - Some(doc_string) -} - /// Handles go-to-def request of the language server pub fn on_go_to_def_request(context: &Context, request: &Request) { let symbols_map = &context.symbols.lock().unwrap(); diff --git a/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.exp b/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.exp index da343069e48..3ef070bbec6 100644 --- a/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.exp +++ b/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.exp @@ -2,7 +2,15 @@ -- test 0 ------------------- use line: 15, use_col: 68 Struct 'CompletionStruct' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' @@ -18,6 +26,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Enum 'SE' Constant 'SOME_CONST' @@ -32,10 +48,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -82,10 +110,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -111,19 +151,28 @@ Method 'targ_type()' TARGET : '(Completion::colon_colon::targ_type)' TYPE : 'fun (SOME_TYPE)' Struct 'CompletionStruct' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' Constant 'SOME_CONST' -- test 4 ------------------- use line: 21, use_col: 57 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 5 ------------------- use line: 22, use_col: 11 @@ -135,12 +184,13 @@ Unit 'std' -- test 6 ------------------- use line: 22, use_col: 46 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 7 ------------------- use line: 23, use_col: 25 @@ -171,12 +221,13 @@ Unit 'std' -- test 9 ------------------- use line: 24, use_col: 40 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 10 ------------------- use line: 25, use_col: 9 @@ -197,10 +248,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -230,119 +293,119 @@ Method 'targ_type()' use line: 25, use_col: 17 Method 'and!()' INSERT TEXT: 'and!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::and)' + TARGET : '(option::and)' TYPE : 'fun <$T, $U>(Option, |$T| -> Option): Option' Method 'and_ref!()' INSERT TEXT: 'and_ref!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::and_ref)' + TARGET : '(option::and_ref)' TYPE : 'fun <$T, $U>(&Option, |&$T| -> Option): Option' Method 'borrow()' INSERT TEXT: 'borrow(${1:t})' - TARGET : '(std::option::borrow)' + TARGET : '(option::borrow)' TYPE : 'fun (&Option): &Element' Method 'borrow_mut()' INSERT TEXT: 'borrow_mut(${1:t})' - TARGET : '(std::option::borrow_mut)' + TARGET : '(option::borrow_mut)' TYPE : 'fun (&mut Option): &mut Element' Method 'borrow_with_default()' INSERT TEXT: 'borrow_with_default(${1:t}, ${2:default_ref})' - TARGET : '(std::option::borrow_with_default)' + TARGET : '(option::borrow_with_default)' TYPE : 'fun (&Option, &Element): &Element' Method 'contains()' INSERT TEXT: 'contains(${1:t}, ${2:e_ref})' - TARGET : '(std::option::contains)' + TARGET : '(option::contains)' TYPE : 'fun (&Option, &Element): bool' Method 'destroy!()' INSERT TEXT: 'destroy!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::destroy)' + TARGET : '(option::destroy)' TYPE : 'fun <$T>(Option, |$T| -> ())' Method 'destroy_none()' INSERT TEXT: 'destroy_none(${1:t})' - TARGET : '(std::option::destroy_none)' + TARGET : '(option::destroy_none)' TYPE : 'fun (Option)' Method 'destroy_or!()' INSERT TEXT: 'destroy_or!(${1:o}, ${2:default})' - TARGET : '(std::option::destroy_or)' + TARGET : '(option::destroy_or)' TYPE : 'fun <$T>(Option, $T): $T' Method 'destroy_some()' INSERT TEXT: 'destroy_some(${1:t})' - TARGET : '(std::option::destroy_some)' + TARGET : '(option::destroy_some)' TYPE : 'fun (Option): Element' Method 'destroy_with_default()' INSERT TEXT: 'destroy_with_default(${1:t}, ${2:default})' - TARGET : '(std::option::destroy_with_default)' + TARGET : '(option::destroy_with_default)' TYPE : 'fun (Option, Element): Element' Method 'do!()' INSERT TEXT: 'do!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::do)' + TARGET : '(option::do)' TYPE : 'fun <$T>(Option, |$T| -> ())' Method 'do_mut!()' INSERT TEXT: 'do_mut!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::do_mut)' + TARGET : '(option::do_mut)' TYPE : 'fun <$T>(&mut Option, |&mut $T| -> ())' Method 'do_ref!()' INSERT TEXT: 'do_ref!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::do_ref)' + TARGET : '(option::do_ref)' TYPE : 'fun <$T>(&Option, |&$T| -> ())' Method 'extract()' INSERT TEXT: 'extract(${1:t})' - TARGET : '(std::option::extract)' + TARGET : '(option::extract)' TYPE : 'fun (&mut Option): Element' Method 'fill()' INSERT TEXT: 'fill(${1:t}, ${2:e})' - TARGET : '(std::option::fill)' + TARGET : '(option::fill)' TYPE : 'fun (&mut Option, Element)' Method 'filter!()' INSERT TEXT: 'filter!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::filter)' + TARGET : '(option::filter)' TYPE : 'fun <$T>(Option, |&$T| -> bool): Option' Method 'get_with_default()' INSERT TEXT: 'get_with_default(${1:t}, ${2:default})' - TARGET : '(std::option::get_with_default)' + TARGET : '(option::get_with_default)' TYPE : 'fun (&Option, Element): Element' Method 'is_none()' INSERT TEXT: 'is_none(${1:t})' - TARGET : '(std::option::is_none)' + TARGET : '(option::is_none)' TYPE : 'fun (&Option): bool' Method 'is_some()' INSERT TEXT: 'is_some(${1:t})' - TARGET : '(std::option::is_some)' + TARGET : '(option::is_some)' TYPE : 'fun (&Option): bool' Method 'is_some_and!()' INSERT TEXT: 'is_some_and!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::is_some_and)' + TARGET : '(option::is_some_and)' TYPE : 'fun <$T>(&Option, |&$T| -> bool): bool' Method 'map!()' INSERT TEXT: 'map!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::map)' + TARGET : '(option::map)' TYPE : 'fun <$T, $U>(Option, |$T| -> $U): Option' Method 'map_ref!()' INSERT TEXT: 'map_ref!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::map_ref)' + TARGET : '(option::map_ref)' TYPE : 'fun <$T, $U>(&Option, |&$T| -> $U): Option' Method 'none()' INSERT TEXT: 'none()' - TARGET : '(std::option::none)' + TARGET : '(option::none)' TYPE : 'fun (): Option' Method 'or!()' INSERT TEXT: 'or!(${1:o}, ${2:default})' - TARGET : '(std::option::or)' + TARGET : '(option::or)' TYPE : 'fun <$T>(Option, Option): Option' Method 'some()' INSERT TEXT: 'some(${1:e})' - TARGET : '(std::option::some)' + TARGET : '(option::some)' TYPE : 'fun (Element): Option' Method 'swap()' INSERT TEXT: 'swap(${1:t}, ${2:e})' - TARGET : '(std::option::swap)' + TARGET : '(option::swap)' TYPE : 'fun (&mut Option, Element): Element' Method 'swap_or_fill()' INSERT TEXT: 'swap_or_fill(${1:t}, ${2:e})' - TARGET : '(std::option::swap_or_fill)' + TARGET : '(option::swap_or_fill)' TYPE : 'fun (&mut Option, Element): Option' Method 'to_vec()' INSERT TEXT: 'to_vec(${1:t})' - TARGET : '(std::option::to_vec)' + TARGET : '(option::to_vec)' TYPE : 'fun (Option): vector' -- test 12 ------------------- @@ -368,6 +431,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Enum 'SE' Constant 'SOME_CONST' @@ -382,10 +453,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -413,12 +496,13 @@ Method 'targ_type()' -- test 14 ------------------- use line: 27, use_col: 23 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 15 ------------------- use line: 28, use_col: 13 @@ -430,10 +514,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -471,6 +567,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Enum 'SE' Constant 'SOME_CONST' @@ -485,10 +589,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -526,6 +642,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Enum 'SE' Enum 'SomeEnum' @@ -544,7 +668,15 @@ Keyword 'address' -- test 18 ------------------- use line: 33, use_col: 37 Struct 'CompletionStruct' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' @@ -576,6 +708,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Constant 'SOME_CONST' Enum 'SomeEnum' @@ -589,10 +729,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -621,14 +773,23 @@ Method 'targ_type()' -- test 21 ------------------- use line: 55, use_col: 26 Struct 'CompletionStruct' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' -- test 22 ------------------- use line: 55, use_col: 39 -EnumMember 'Variant{}' - INSERT TEXT: 'Variant{${1:field}}' +EnumMember 'Variant' +EnumMember 'Variant{..}' + INSERT TEXT: 'Variant { ${1:field} }' -- test 23 ------------------- use line: 59, use_col: 21 @@ -641,6 +802,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Enum 'SomeEnum' Struct 'SomeStruct' @@ -667,6 +836,14 @@ Module 'Self' Module 'option' Module 'vector' Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'Option' Constant 'SOME_CONST' Enum 'SomeEnum' @@ -680,10 +857,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -719,10 +908,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -748,7 +949,15 @@ Method 'targ_type()' TARGET : '(Completion::colon_colon::targ_type)' TYPE : 'fun (SOME_TYPE)' Struct 'CompletionStruct' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' Constant 'SOME_CONST' @@ -774,10 +983,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains(${1:s})' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon()' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon()' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -803,137 +1024,146 @@ Method 'targ_type()' TARGET : '(Completion::colon_colon::targ_type)' TYPE : 'fun (SOME_TYPE)' Struct 'CompletionStruct' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' Constant 'SOME_CONST' -- test 28 ------------------- use line: 21, use_col: 56 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 29 ------------------- use line: 25, use_col: 16 Method 'and!()' INSERT TEXT: 'and!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::and)' + TARGET : '(option::and)' TYPE : 'fun <$T, $U>(Option, |$T| -> Option): Option' Method 'and_ref!()' INSERT TEXT: 'and_ref!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::and_ref)' + TARGET : '(option::and_ref)' TYPE : 'fun <$T, $U>(&Option, |&$T| -> Option): Option' Method 'borrow()' INSERT TEXT: 'borrow(${1:t})' - TARGET : '(std::option::borrow)' + TARGET : '(option::borrow)' TYPE : 'fun (&Option): &Element' Method 'borrow_mut()' INSERT TEXT: 'borrow_mut(${1:t})' - TARGET : '(std::option::borrow_mut)' + TARGET : '(option::borrow_mut)' TYPE : 'fun (&mut Option): &mut Element' Method 'borrow_with_default()' INSERT TEXT: 'borrow_with_default(${1:t}, ${2:default_ref})' - TARGET : '(std::option::borrow_with_default)' + TARGET : '(option::borrow_with_default)' TYPE : 'fun (&Option, &Element): &Element' Method 'contains()' INSERT TEXT: 'contains(${1:t}, ${2:e_ref})' - TARGET : '(std::option::contains)' + TARGET : '(option::contains)' TYPE : 'fun (&Option, &Element): bool' Method 'destroy!()' INSERT TEXT: 'destroy!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::destroy)' + TARGET : '(option::destroy)' TYPE : 'fun <$T>(Option, |$T| -> ())' Method 'destroy_none()' INSERT TEXT: 'destroy_none(${1:t})' - TARGET : '(std::option::destroy_none)' + TARGET : '(option::destroy_none)' TYPE : 'fun (Option)' Method 'destroy_or!()' INSERT TEXT: 'destroy_or!(${1:o}, ${2:default})' - TARGET : '(std::option::destroy_or)' + TARGET : '(option::destroy_or)' TYPE : 'fun <$T>(Option, $T): $T' Method 'destroy_some()' INSERT TEXT: 'destroy_some(${1:t})' - TARGET : '(std::option::destroy_some)' + TARGET : '(option::destroy_some)' TYPE : 'fun (Option): Element' Method 'destroy_with_default()' INSERT TEXT: 'destroy_with_default(${1:t}, ${2:default})' - TARGET : '(std::option::destroy_with_default)' + TARGET : '(option::destroy_with_default)' TYPE : 'fun (Option, Element): Element' Method 'do!()' INSERT TEXT: 'do!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::do)' + TARGET : '(option::do)' TYPE : 'fun <$T>(Option, |$T| -> ())' Method 'do_mut!()' INSERT TEXT: 'do_mut!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::do_mut)' + TARGET : '(option::do_mut)' TYPE : 'fun <$T>(&mut Option, |&mut $T| -> ())' Method 'do_ref!()' INSERT TEXT: 'do_ref!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::do_ref)' + TARGET : '(option::do_ref)' TYPE : 'fun <$T>(&Option, |&$T| -> ())' Method 'extract()' INSERT TEXT: 'extract(${1:t})' - TARGET : '(std::option::extract)' + TARGET : '(option::extract)' TYPE : 'fun (&mut Option): Element' Method 'fill()' INSERT TEXT: 'fill(${1:t}, ${2:e})' - TARGET : '(std::option::fill)' + TARGET : '(option::fill)' TYPE : 'fun (&mut Option, Element)' Method 'filter!()' INSERT TEXT: 'filter!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::filter)' + TARGET : '(option::filter)' TYPE : 'fun <$T>(Option, |&$T| -> bool): Option' Method 'get_with_default()' INSERT TEXT: 'get_with_default(${1:t}, ${2:default})' - TARGET : '(std::option::get_with_default)' + TARGET : '(option::get_with_default)' TYPE : 'fun (&Option, Element): Element' Method 'is_none()' INSERT TEXT: 'is_none(${1:t})' - TARGET : '(std::option::is_none)' + TARGET : '(option::is_none)' TYPE : 'fun (&Option): bool' Method 'is_some()' INSERT TEXT: 'is_some(${1:t})' - TARGET : '(std::option::is_some)' + TARGET : '(option::is_some)' TYPE : 'fun (&Option): bool' Method 'is_some_and!()' INSERT TEXT: 'is_some_and!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::is_some_and)' + TARGET : '(option::is_some_and)' TYPE : 'fun <$T>(&Option, |&$T| -> bool): bool' Method 'map!()' INSERT TEXT: 'map!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::map)' + TARGET : '(option::map)' TYPE : 'fun <$T, $U>(Option, |$T| -> $U): Option' Method 'map_ref!()' INSERT TEXT: 'map_ref!(${1:o}, |${2}| ${3})' - TARGET : '(std::option::map_ref)' + TARGET : '(option::map_ref)' TYPE : 'fun <$T, $U>(&Option, |&$T| -> $U): Option' Method 'none()' INSERT TEXT: 'none()' - TARGET : '(std::option::none)' + TARGET : '(option::none)' TYPE : 'fun (): Option' Method 'or!()' INSERT TEXT: 'or!(${1:o}, ${2:default})' - TARGET : '(std::option::or)' + TARGET : '(option::or)' TYPE : 'fun <$T>(Option, Option): Option' Method 'some()' INSERT TEXT: 'some(${1:e})' - TARGET : '(std::option::some)' + TARGET : '(option::some)' TYPE : 'fun (Element): Option' Method 'swap()' INSERT TEXT: 'swap(${1:t}, ${2:e})' - TARGET : '(std::option::swap)' + TARGET : '(option::swap)' TYPE : 'fun (&mut Option, Element): Element' Method 'swap_or_fill()' INSERT TEXT: 'swap_or_fill(${1:t}, ${2:e})' - TARGET : '(std::option::swap_or_fill)' + TARGET : '(option::swap_or_fill)' TYPE : 'fun (&mut Option, Element): Option' Method 'to_vec()' INSERT TEXT: 'to_vec(${1:t})' - TARGET : '(std::option::to_vec)' + TARGET : '(option::to_vec)' TYPE : 'fun (Option): vector' -- test 30 ------------------- @@ -949,12 +1179,13 @@ Method 'sha3_256()' -- test 31 ------------------- use line: 27, use_col: 23 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 32 ------------------- use line: 41, use_col: 20 @@ -969,17 +1200,112 @@ Module 'uses' -- test 33 ------------------- use line: 44, use_col: 43 -EnumMember 'SomeNamedVariant{}' - INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}' -EnumMember 'SomePositionalVariant()' +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' EnumMember 'SomeVariant' - INSERT TEXT: 'SomeVariant{}' -- test 34 ------------------- use line: 55, use_col: 38 -EnumMember 'Variant{}' - INSERT TEXT: 'Variant{${1:field}}' +EnumMember 'Variant' +EnumMember 'Variant{..}' + INSERT TEXT: 'Variant { ${1:field} }' + +-- test 35 ------------------- +use line: 78, use_col: 35 +EnumMember 'MultiFieldVariant' +EnumMember 'MultiFieldVariant{..}' + INSERT TEXT: 'MultiFieldVariant { + ${1:name1}, + ${2:name2}, + ${3:name3}, +}' + +-- test 36 ------------------- +use line: 82, use_col: 18 +Unit '0x1' +Unit '0xA' +Unit '0xCAFE' +Unit 'Completion' +Unit 'std' +Module 'Self' +Module 'option' +Module 'vector' +Struct 'CompletionStruct' +Enum 'EnumWithMultiFieldVariant' +Struct 'MultiFieldStruct' +Struct 'MultiFieldStruct{..}' + INSERT TEXT: 'MultiFieldStruct { + ${1:field1}, + ${2:field2}, + ${3:field3}, +}' +Struct 'Option' +Constant 'SOME_CONST' +Enum 'SomeEnum' +Struct 'SomeStruct' +Enum 'TargEnum' +Method 'attr_chain()' + INSERT TEXT: 'attr_chain()' + TARGET : '(Completion::colon_colon::attr_chain)' + TYPE : 'fun ()' +Method 'complete_chains()' + INSERT TEXT: 'complete_chains(${1:s})' + TARGET : '(Completion::colon_colon::complete_chains)' + TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern(${1:e})' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' +Method 'multi_colon_colon()' + INSERT TEXT: 'multi_colon_colon()' + TARGET : '(Completion::colon_colon::multi_colon_colon)' + TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct()' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant()' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' +Method 'one_colon_colon()' + INSERT TEXT: 'one_colon_colon()' + TARGET : '(Completion::colon_colon::one_colon_colon)' + TYPE : 'fun ()' +Method 'sbar()' + INSERT TEXT: 'sbar(${1:_param1}, ${2:_param2})' + TARGET : '(Completion::colon_colon::sbar)' + TYPE : 'fun (u64, SomeStruct)' +Method 'sbaz()' + INSERT TEXT: 'sbaz()' + TARGET : '(Completion::colon_colon::sbaz)' + TYPE : 'fun ()' +Method 'single_ident()' + INSERT TEXT: 'single_ident()' + TARGET : '(Completion::colon_colon::single_ident)' + TYPE : 'fun ()' +Method 'targ_chain()' + INSERT TEXT: 'targ_chain()' + TARGET : '(Completion::colon_colon::targ_chain)' + TYPE : 'fun ()' +Method 'targ_type()' + INSERT TEXT: 'targ_type(${1:p})' + TARGET : '(Completion::colon_colon::targ_type)' + TYPE : 'fun (SOME_TYPE)' + +-- test 37 ------------------- +use line: 87, use_col: 22 +EnumMember 'SomeNamedVariant' +EnumMember 'SomeNamedVariant{..}' + INSERT TEXT: 'SomeNamedVariant { ${1:name1}, ${2:name2} }' +EnumMember 'SomePositionalVariant' +EnumMember 'SomePositionalVariant(..)' + INSERT TEXT: 'SomePositionalVariant(${1}, ${2})' +EnumMember 'SomeVariant' == uses.move ======================================================== -- test 0 ------------------- @@ -1132,10 +1458,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -1161,7 +1499,9 @@ Method 'targ_type()' TARGET : '(Completion::colon_colon::targ_type)' TYPE : 'fun (SOME_TYPE)' Struct 'CompletionStruct' +Struct 'MultiFieldStruct' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' @@ -1175,10 +1515,22 @@ Method 'complete_chains()' INSERT TEXT: 'complete_chains' TARGET : '(Completion::colon_colon::complete_chains)' TYPE : 'fun (SomeStruct)' +Method 'match_pattern()' + INSERT TEXT: 'match_pattern' + TARGET : '(Completion::colon_colon::match_pattern)' + TYPE : 'fun (SomeEnum)' Method 'multi_colon_colon()' INSERT TEXT: 'multi_colon_colon' TARGET : '(Completion::colon_colon::multi_colon_colon)' TYPE : 'fun ()' +Method 'multi_field_struct()' + INSERT TEXT: 'multi_field_struct' + TARGET : '(Completion::colon_colon::multi_field_struct)' + TYPE : 'fun ()' +Method 'multi_field_variant()' + INSERT TEXT: 'multi_field_variant' + TARGET : '(Completion::colon_colon::multi_field_variant)' + TYPE : 'fun ()' Method 'one_colon_colon()' INSERT TEXT: 'one_colon_colon' TARGET : '(Completion::colon_colon::one_colon_colon)' @@ -1204,7 +1556,9 @@ Method 'targ_type()' TARGET : '(Completion::colon_colon::targ_type)' TYPE : 'fun (SOME_TYPE)' Struct 'CompletionStruct' +Struct 'MultiFieldStruct' Struct 'SomeStruct' +Enum 'EnumWithMultiFieldVariant' Enum 'SomeEnum' Enum 'TargEnum' diff --git a/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.ide b/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.ide index 78c526092d1..1ba89f12abc 100644 --- a/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.ide +++ b/external-crates/move/crates/move-analyzer/tests/colon_colon_completion.ide @@ -145,6 +145,18 @@ { "use_line": 55, "use_col": 38 + }, + { + "use_line": 78, + "use_col": 35 + }, + { + "use_line": 82, + "use_col": 18 + }, + { + "use_line": 87, + "use_col": 22 } ], "uses.move": [ diff --git a/external-crates/move/crates/move-analyzer/tests/completion/sources/colon_colon.move b/external-crates/move/crates/move-analyzer/tests/completion/sources/colon_colon.move index ae40128b570..394ccdc7e6d 100644 --- a/external-crates/move/crates/move-analyzer/tests/completion/sources/colon_colon.move +++ b/external-crates/move/crates/move-analyzer/tests/completion/sources/colon_colon.move @@ -63,4 +63,28 @@ module Completion::colon_colon { public fun attr_chain() { abort(SOME_CONST); } + + public enum EnumWithMultiFieldVariant has drop { + MultiFieldVariant { name1: u64, name2: u64, name3: u64}, + } + + public struct MultiFieldStruct has drop { + field1: u64, + field2: u64, + field3: u64, + } + + public fun multi_field_variant() { + EnumWithMultiFieldVariant:: + } + + public fun multi_field_struct() { + MultiField + } + + public fun match_pattern(e: SomeEnum) { + match (e) { + SomeEnum:: + } + } } diff --git a/external-crates/move/crates/move-analyzer/tests/consts.exp b/external-crates/move/crates/move-analyzer/tests/consts.exp index 99b15bf362a..07aa620aad1 100644 --- a/external-crates/move/crates/move-analyzer/tests/consts.exp +++ b/external-crates/move/crates/move-analyzer/tests/consts.exp @@ -135,3 +135,27 @@ TypeDef: no info On Hover: const Symbols::M8::EQUAL: bool = 1 == 1 +-- test 17 ------------------- +use line: 34, use_ndx: 0 +Use: 'ERROR_CONST', start: 10, end: 21 +Def: 'ERROR_CONST', line: 33, def char: 10 +TypeDef: no info +On Hover: +const Symbols::M8::ERROR_CONST: u64 = 42 + +-- test 18 ------------------- +use line: 37, use_ndx: 0 +Use: 'ERROR_CONST', start: 16, end: 27 +Def: 'ERROR_CONST', line: 33, def char: 10 +TypeDef: no info +On Hover: +const Symbols::M8::ERROR_CONST: u64 = 42 + +-- test 19 ------------------- +use line: 37, use_ndx: 1 +Use: 'ERROR_CONST', start: 35, end: 46 +Def: 'ERROR_CONST', line: 33, def char: 10 +TypeDef: no info +On Hover: +const Symbols::M8::ERROR_CONST: u64 = 42 + diff --git a/external-crates/move/crates/move-analyzer/tests/consts.ide b/external-crates/move/crates/move-analyzer/tests/consts.ide index f7b7d9feb70..de79e5274d8 100644 --- a/external-crates/move/crates/move-analyzer/tests/consts.ide +++ b/external-crates/move/crates/move-analyzer/tests/consts.ide @@ -71,6 +71,18 @@ { "use_line": 31, "use_ndx": 2 + }, + { + "use_line": 34, + "use_ndx": 0 + }, + { + "use_line": 37, + "use_ndx": 0 + }, + { + "use_line": 37, + "use_ndx": 1 } ] } diff --git a/external-crates/move/crates/move-analyzer/tests/cursor_tests/cursor_dot_call_tests.exp b/external-crates/move/crates/move-analyzer/tests/cursor_tests/cursor_dot_call_tests.exp index a91697647cd..b692272827d 100644 --- a/external-crates/move/crates/move-analyzer/tests/cursor_tests/cursor_dot_call_tests.exp +++ b/external-crates/move/crates/move-analyzer/tests/cursor_tests/cursor_dot_call_tests.exp @@ -148,7 +148,7 @@ cursor info: - module: Move2024::M2 - definition: function baz - position: exp -- value: DotCall(Name(Single(PathEntry { name: "some_struct", tyargs: None, is_macro: None })), "f3", None, None, [Name(Single(PathEntry { name: "val", tyargs: None, is_macro: None }))]) +- value: DotCall(Name(Single(PathEntry { name: "some_struct", tyargs: None, is_macro: None })), Loc { file_hash: "c26c564206296bc6de3b43456c0cf245c77be098b5cb90d48a37b737c8b0d007", start: 842, end: 843 }, "f3", None, None, [Name(Single(PathEntry { name: "val", tyargs: None, is_macro: None }))]) -- test 20 @ 34:37 ------------ expected: equal sign in a binop @@ -156,5 +156,5 @@ cursor info: - module: Move2024::M2 - definition: function baz - position: exp -- value: BinopExp(DotCall(Name(Single(PathEntry { name: "some_struct", tyargs: None, is_macro: None })), "f3", None, None, [Name(Single(PathEntry { name: "val", tyargs: None, is_macro: None }))]), Eq, DotCall(Name(Single(PathEntry { name: "some_struct", tyargs: None, is_macro: None })), "f4", None, None, [Name(Single(PathEntry { name: "val", tyargs: None, is_macro: None }))])) +- value: BinopExp(DotCall(Name(Single(PathEntry { name: "some_struct", tyargs: None, is_macro: None })), Loc { file_hash: "c26c564206296bc6de3b43456c0cf245c77be098b5cb90d48a37b737c8b0d007", start: 842, end: 843 }, "f3", None, None, [Name(Single(PathEntry { name: "val", tyargs: None, is_macro: None }))]), Eq, DotCall(Name(Single(PathEntry { name: "some_struct", tyargs: None, is_macro: None })), Loc { file_hash: "c26c564206296bc6de3b43456c0cf245c77be098b5cb90d48a37b737c8b0d007", start: 865, end: 866 }, "f4", None, None, [Name(Single(PathEntry { name: "val", tyargs: None, is_macro: None }))])) diff --git a/external-crates/move/crates/move-analyzer/tests/docstring.exp b/external-crates/move/crates/move-analyzer/tests/docstring.exp index d4fc4dd628c..b48d2c995bb 100644 --- a/external-crates/move/crates/move-analyzer/tests/docstring.exp +++ b/external-crates/move/crates/move-analyzer/tests/docstring.exp @@ -1,17 +1,16 @@ == M6.move ======================================================== -- test 0 ------------------- use line: 5, use_ndx: 0 -Use: 'DocumentedStruct', start: 11, end: 27 -Def: 'DocumentedStruct', line: 4, def char: 11 -TypeDef: 'DocumentedStruct', line: 4, char: 11 +Use: 'DocumentedStruct', start: 18, end: 34 +Def: 'DocumentedStruct', line: 4, def char: 18 +TypeDef: 'DocumentedStruct', line: 4, char: 18 On Hover: -struct Symbols::M6::DocumentedStruct has drop, store, key { +public struct Symbols::M6::DocumentedStruct has drop, store { documented_field: u64 } -This is a documented struct -With a multi-line docstring - + This is a documented struct + With a multi-line docstring -- test 1 ------------------- use line: 11, use_ndx: 0 @@ -21,8 +20,7 @@ TypeDef: no info On Hover: const Symbols::M6::DOCUMENTED_CONSTANT: u64 = 42 -Constant containing the answer to the universe - + Constant containing the answer to the universe -- test 2 ------------------- use line: 15, use_ndx: 0 @@ -30,46 +28,45 @@ Use: 'unpack', start: 8, end: 14 Def: 'unpack', line: 14, def char: 8 TypeDef: no info On Hover: -fun Symbols::M6::unpack(s: Symbols::M6::DocumentedStruct): u64 - -A documented function that unpacks a DocumentedStruct +fun Symbols::M6::unpack( + s: Symbols::M6::DocumentedStruct +): u64 + A documented function that unpacks a DocumentedStruct -- test 3 ------------------- use line: 15, use_ndx: 1 Use: 's', start: 15, end: 16 Def: 's', line: 14, def char: 15 -TypeDef: 'DocumentedStruct', line: 4, char: 11 +TypeDef: 'DocumentedStruct', line: 4, char: 18 On Hover: s: Symbols::M6::DocumentedStruct -- test 4 ------------------- use line: 15, use_ndx: 2 Use: 'DocumentedStruct', start: 18, end: 34 -Def: 'DocumentedStruct', line: 4, def char: 11 -TypeDef: 'DocumentedStruct', line: 4, char: 11 +Def: 'DocumentedStruct', line: 4, def char: 18 +TypeDef: 'DocumentedStruct', line: 4, char: 18 On Hover: -struct Symbols::M6::DocumentedStruct has drop, store, key { +public struct Symbols::M6::DocumentedStruct has drop, store { documented_field: u64 } -This is a documented struct -With a multi-line docstring - + This is a documented struct + With a multi-line docstring -- test 5 ------------------- use line: 16, use_ndx: 0 Use: 'DocumentedStruct', start: 12, end: 28 -Def: 'DocumentedStruct', line: 4, def char: 11 -TypeDef: 'DocumentedStruct', line: 4, char: 11 +Def: 'DocumentedStruct', line: 4, def char: 18 +TypeDef: 'DocumentedStruct', line: 4, char: 18 On Hover: -struct Symbols::M6::DocumentedStruct has drop, store, key { +public struct Symbols::M6::DocumentedStruct has drop, store { documented_field: u64 } -This is a documented struct -With a multi-line docstring - + This is a documented struct + With a multi-line docstring -- test 6 ------------------- use line: 16, use_ndx: 1 @@ -80,14 +77,13 @@ On Hover: Symbols::M6::DocumentedStruct documented_field: u64 -A documented field - + A documented field -- test 7 ------------------- use line: 16, use_ndx: 3 Use: 's', start: 59, end: 60 Def: 's', line: 14, def char: 15 -TypeDef: 'DocumentedStruct', line: 4, char: 11 +TypeDef: 'DocumentedStruct', line: 4, char: 18 On Hover: s: Symbols::M6::DocumentedStruct @@ -100,13 +96,12 @@ On Hover: fun Symbols::M6::other_doc_struct(): Symbols::M7::OtherDocStruct -This is a multiline docstring - -This docstring has empty lines. - -It uses the ** format instead of /// + This is a multiline docstring + This docstring has empty lines. + It uses the ** format instead of /// + -- test 9 ------------------- use line: 32, use_ndx: 0 @@ -114,23 +109,23 @@ Use: 'acq', start: 8, end: 11 Def: 'acq', line: 31, def char: 8 TypeDef: no info On Hover: -fun Symbols::M6::acq(uint: u64): u64 - -Asterix based single-line docstring +fun Symbols::M6::acq( + uint: u64 +): u64 + Asterix based single-line docstring -- test 10 ------------------- use line: 27, use_ndx: 2 Use: 'OtherDocStruct', start: 41, end: 55 -Def: 'OtherDocStruct', line: 3, def char: 11 -TypeDef: 'OtherDocStruct', line: 3, char: 11 +Def: 'OtherDocStruct', line: 3, def char: 18 +TypeDef: 'OtherDocStruct', line: 3, char: 18 On Hover: -struct Symbols::M7::OtherDocStruct has drop { +public struct Symbols::M7::OtherDocStruct has drop { some_field: u64 } -Documented struct in another module - + Documented struct in another module -- test 11 ------------------- use line: 28, use_ndx: 1 @@ -138,10 +133,11 @@ Use: 'create_other_struct', start: 21, end: 40 Def: 'create_other_struct', line: 9, def char: 15 TypeDef: no info On Hover: -public fun Symbols::M7::create_other_struct(v: u64): Symbols::M7::OtherDocStruct - -Documented initializer in another module +public fun Symbols::M7::create_other_struct( + v: u64 +): Symbols::M7::OtherDocStruct + Documented initializer in another module -- test 12 ------------------- use line: 28, use_ndx: 2 @@ -151,21 +147,19 @@ TypeDef: no info On Hover: const Symbols::M6::DOCUMENTED_CONSTANT: u64 = 42 -Constant containing the answer to the universe - + Constant containing the answer to the universe -- test 13 ------------------- use line: 39, use_ndx: 1 Use: 'OtherDocStruct', start: 35, end: 49 -Def: 'OtherDocStruct', line: 3, def char: 11 -TypeDef: 'OtherDocStruct', line: 3, char: 11 +Def: 'OtherDocStruct', line: 3, def char: 18 +TypeDef: 'OtherDocStruct', line: 3, char: 18 On Hover: -struct Symbols::M7::OtherDocStruct has drop { +public struct Symbols::M7::OtherDocStruct has drop { some_field: u64 } -Documented struct in another module - + Documented struct in another module -- test 14 ------------------- use line: 44, use_ndx: 1 @@ -183,3 +177,78 @@ TypeDef: no info On Hover: param: T +-- test 16 ------------------- +use line: 56, use_ndx: 0 +Use: 'code_block_doc_slash', start: 8, end: 28 +Def: 'code_block_doc_slash', line: 55, def char: 8 +TypeDef: no info +On Hover: +fun Symbols::M6::code_block_doc_slash() + + A documented function with code block + (should preserve indentation in the code block) + + ```rust + fun foo() { + 42 + } + ``` + +-- test 17 ------------------- +use line: 68, use_ndx: 0 +Use: 'code_block_doc_star', start: 8, end: 27 +Def: 'code_block_doc_star', line: 67, def char: 8 +TypeDef: no info +On Hover: +fun Symbols::M6::code_block_doc_star() + + + A documented function with code block + (should preserve indentation in the code block) + + ```rust + fun foo() { + 42 + } + ``` + + +-- test 18 ------------------- +use line: 80, use_ndx: 0 +Use: 'misformatted_docstring', start: 8, end: 30 +Def: 'misformatted_docstring', line: 79, def char: 8 +TypeDef: no info +On Hover: +fun Symbols::M6::misformatted_docstring() + + + Misformatted docstring to have fewer whitespace in the body than + at the ending marker. + + + Beginning of this string should not disappear. + +Beginning of this string should not disappear either. + + + +-- test 19 ------------------- +use line: 85, use_ndx: 0 +Use: 'attributes_after_docstring', start: 8, end: 34 +Def: 'attributes_after_docstring', line: 84, def char: 8 +TypeDef: no info +On Hover: +fun Symbols::M6::attributes_after_docstring() + + Docstring before attributes + +-- test 20 ------------------- +use line: 89, use_ndx: 0 +Use: 'attributes_before_docstring', start: 8, end: 35 +Def: 'attributes_before_docstring', line: 88, def char: 8 +TypeDef: no info +On Hover: +fun Symbols::M6::attributes_before_docstring() + + Docstring after attributes + diff --git a/external-crates/move/crates/move-analyzer/tests/docstring.ide b/external-crates/move/crates/move-analyzer/tests/docstring.ide index 1aff49d4e0c..ee95a5c428e 100644 --- a/external-crates/move/crates/move-analyzer/tests/docstring.ide +++ b/external-crates/move/crates/move-analyzer/tests/docstring.ide @@ -68,6 +68,26 @@ { "use_line": 44, "use_ndx": 2 + }, + { + "use_line": 56, + "use_ndx": 0 + }, + { + "use_line": 68, + "use_ndx": 0 + }, + { + "use_line": 80, + "use_ndx": 0 + }, + { + "use_line": 85, + "use_ndx": 0 + }, + { + "use_line": 89, + "use_ndx": 0 } ] } diff --git a/external-crates/move/crates/move-analyzer/tests/dot_calls.exp b/external-crates/move/crates/move-analyzer/tests/dot_calls.exp index d7f5f78ba12..ff4b7ad89d1 100644 --- a/external-crates/move/crates/move-analyzer/tests/dot_calls.exp +++ b/external-crates/move/crates/move-analyzer/tests/dot_calls.exp @@ -13,7 +13,9 @@ Use: 'foo', start: 25, end: 28 Def: 'foo', line: 13, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::foo(s: &Move2024::M1::SomeStruct): u64 +public fun Move2024::M1::foo( + s: &Move2024::M1::SomeStruct +): u64 -- test 2 ------------------- use line: 3, use_ndx: 2 @@ -31,7 +33,9 @@ Use: 'f1', start: 43, end: 45 Def: 'foo', line: 13, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::foo(s: &Move2024::M1::SomeStruct): u64 +public fun Move2024::M1::foo( + s: &Move2024::M1::SomeStruct +): u64 -- test 4 ------------------- use line: 4, use_ndx: 0 @@ -47,7 +51,9 @@ Use: 'foo', start: 33, end: 36 Def: 'foo', line: 13, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::foo(s: &Move2024::M1::SomeStruct): u64 +public fun Move2024::M1::foo( + s: &Move2024::M1::SomeStruct +): u64 -- test 6 ------------------- use line: 4, use_ndx: 2 @@ -65,7 +71,9 @@ Use: 'f2', start: 51, end: 53 Def: 'foo', line: 13, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::foo(s: &Move2024::M1::SomeStruct): u64 +public fun Move2024::M1::foo( + s: &Move2024::M1::SomeStruct +): u64 -- test 8 ------------------- use line: 27, use_ndx: 0 @@ -81,7 +89,10 @@ Use: 'bar', start: 22, end: 25 Def: 'bar', line: 17, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::bar(s: &Move2024::M1::SomeStruct, v: u64): u64 +public fun Move2024::M1::bar( + s: &Move2024::M1::SomeStruct, + v: u64 +): u64 -- test 10 ------------------- use line: 27, use_ndx: 2 @@ -107,7 +118,10 @@ Use: 'f3', start: 54, end: 56 Def: 'bar', line: 17, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::bar(s: &Move2024::M1::SomeStruct, v: u64): u64 +public fun Move2024::M1::bar( + s: &Move2024::M1::SomeStruct, + v: u64 +): u64 -- test 13 ------------------- use line: 30, use_ndx: 0 @@ -123,7 +137,10 @@ Use: 'bar', start: 20, end: 23 Def: 'bar', line: 17, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::bar(s: &Move2024::M1::SomeStruct, v: u64): u64 +public fun Move2024::M1::bar( + s: &Move2024::M1::SomeStruct, + v: u64 +): u64 -- test 15 ------------------- use line: 30, use_ndx: 2 @@ -141,7 +158,10 @@ Use: 'f4', start: 43, end: 45 Def: 'bar', line: 17, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::bar(s: &Move2024::M1::SomeStruct, v: u64): u64 +public fun Move2024::M1::bar( + s: &Move2024::M1::SomeStruct, + v: u64 +): u64 -- test 17 ------------------- use line: 34, use_ndx: 0 @@ -157,7 +177,9 @@ Use: 'f1', start: 28, end: 30 Def: 'foo', line: 13, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::foo(s: &Move2024::M1::SomeStruct): u64 +public fun Move2024::M1::foo( + s: &Move2024::M1::SomeStruct +): u64 -- test 19 ------------------- use line: 35, use_ndx: 0 @@ -173,7 +195,10 @@ Use: 'f3', start: 28, end: 30 Def: 'bar', line: 17, def char: 15 TypeDef: no info On Hover: -public fun Move2024::M1::bar(s: &Move2024::M1::SomeStruct, v: u64): u64 +public fun Move2024::M1::bar( + s: &Move2024::M1::SomeStruct, + v: u64 +): u64 -- test 21 ------------------- use line: 35, use_ndx: 2 diff --git a/external-crates/move/crates/move-analyzer/tests/dot_completion.exp b/external-crates/move/crates/move-analyzer/tests/dot_completion.exp index 547bc99ee90..3a43095ec41 100644 --- a/external-crates/move/crates/move-analyzer/tests/dot_completion.exp +++ b/external-crates/move/crates/move-analyzer/tests/dot_completion.exp @@ -54,115 +54,115 @@ Method 'test()' use line: 4, use_col: 10 Method 'all!()' INSERT TEXT: 'all!(|${1}| ${2})' - TARGET : '(std::vector::all)' + TARGET : '(vector::all)' TYPE : 'fun <$T>(&vector<$T>, |&$T| -> bool): bool' Method 'any!()' INSERT TEXT: 'any!(|${1}| ${2})' - TARGET : '(std::vector::any)' + TARGET : '(vector::any)' TYPE : 'fun <$T>(&vector<$T>, |&$T| -> bool): bool' Method 'append()' INSERT TEXT: 'append(${1:other})' - TARGET : '(std::vector::append)' + TARGET : '(vector::append)' TYPE : 'fun (&mut vector, vector)' Method 'borrow()' INSERT TEXT: 'borrow(${1:i})' - TARGET : '(std::vector::borrow)' + TARGET : '(vector::borrow)' TYPE : 'fun (&vector, u64): &Element' Method 'borrow_mut()' INSERT TEXT: 'borrow_mut(${1:i})' - TARGET : '(std::vector::borrow_mut)' + TARGET : '(vector::borrow_mut)' TYPE : 'fun (&mut vector, u64): &mut Element' Method 'contains()' INSERT TEXT: 'contains(${1:e})' - TARGET : '(std::vector::contains)' + TARGET : '(vector::contains)' TYPE : 'fun (&vector, &Element): bool' Method 'count!()' INSERT TEXT: 'count!(|${1}| ${2})' - TARGET : '(std::vector::count)' + TARGET : '(vector::count)' TYPE : 'fun <$T>(&vector<$T>, |&$T| -> bool): u64' Method 'destroy!()' INSERT TEXT: 'destroy!(|${1}| ${2})' - TARGET : '(std::vector::destroy)' + TARGET : '(vector::destroy)' TYPE : 'fun <$T>(vector<$T>, |$T| -> ())' Method 'destroy_empty()' INSERT TEXT: 'destroy_empty()' - TARGET : '(std::vector::destroy_empty)' + TARGET : '(vector::destroy_empty)' TYPE : 'fun (vector)' Method 'do!()' INSERT TEXT: 'do!(|${1}| ${2})' - TARGET : '(std::vector::do)' + TARGET : '(vector::do)' TYPE : 'fun <$T>(vector<$T>, |$T| -> ())' Method 'do_mut!()' INSERT TEXT: 'do_mut!(|${1}| ${2})' - TARGET : '(std::vector::do_mut)' + TARGET : '(vector::do_mut)' TYPE : 'fun <$T>(&mut vector<$T>, |&mut $T| -> ())' Method 'do_ref!()' INSERT TEXT: 'do_ref!(|${1}| ${2})' - TARGET : '(std::vector::do_ref)' + TARGET : '(vector::do_ref)' TYPE : 'fun <$T>(&vector<$T>, |&$T| -> ())' Method 'filter!()' INSERT TEXT: 'filter!(|${1}| ${2})' - TARGET : '(std::vector::filter)' + TARGET : '(vector::filter)' TYPE : 'fun <$T>(vector<$T>, |&$T| -> bool): vector<$T>' Method 'find_index!()' INSERT TEXT: 'find_index!(|${1}| ${2})' - TARGET : '(std::vector::find_index)' + TARGET : '(vector::find_index)' TYPE : 'fun <$T>(&vector<$T>, |&$T| -> bool): Option' Method 'fold!()' INSERT TEXT: 'fold!(${1:init}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::fold)' + TARGET : '(vector::fold)' TYPE : 'fun <$T, $Acc>(vector<$T>, $Acc, |$Acc, $T| -> $Acc): $Acc' Method 'index_of()' INSERT TEXT: 'index_of(${1:e})' - TARGET : '(std::vector::index_of)' + TARGET : '(vector::index_of)' TYPE : 'fun (&vector, &Element): (bool, u64)' Method 'insert()' INSERT TEXT: 'insert(${1:e}, ${2:i})' - TARGET : '(std::vector::insert)' + TARGET : '(vector::insert)' TYPE : 'fun (&mut vector, Element, u64)' Method 'is_empty()' INSERT TEXT: 'is_empty()' - TARGET : '(std::vector::is_empty)' + TARGET : '(vector::is_empty)' TYPE : 'fun (&vector): bool' Method 'length()' INSERT TEXT: 'length()' - TARGET : '(std::vector::length)' + TARGET : '(vector::length)' TYPE : 'fun (&vector): u64' Method 'map!()' INSERT TEXT: 'map!(|${1}| ${2})' - TARGET : '(std::vector::map)' + TARGET : '(vector::map)' TYPE : 'fun <$T, $U>(vector<$T>, |$T| -> $U): vector<$U>' Method 'map_ref!()' INSERT TEXT: 'map_ref!(|${1}| ${2})' - TARGET : '(std::vector::map_ref)' + TARGET : '(vector::map_ref)' TYPE : 'fun <$T, $U>(&vector<$T>, |&$T| -> $U): vector<$U>' Method 'partition!()' INSERT TEXT: 'partition!(|${1}| ${2})' - TARGET : '(std::vector::partition)' + TARGET : '(vector::partition)' TYPE : 'fun <$T>(vector<$T>, |&$T| -> bool): (vector<$T>, vector<$T>)' Method 'pop_back()' INSERT TEXT: 'pop_back()' - TARGET : '(std::vector::pop_back)' + TARGET : '(vector::pop_back)' TYPE : 'fun (&mut vector): Element' Method 'push_back()' INSERT TEXT: 'push_back(${1:e})' - TARGET : '(std::vector::push_back)' + TARGET : '(vector::push_back)' TYPE : 'fun (&mut vector, Element)' Method 'remove()' INSERT TEXT: 'remove(${1:i})' - TARGET : '(std::vector::remove)' + TARGET : '(vector::remove)' TYPE : 'fun (&mut vector, u64): Element' Method 'reverse()' INSERT TEXT: 'reverse()' - TARGET : '(std::vector::reverse)' + TARGET : '(vector::reverse)' TYPE : 'fun (&mut vector)' Method 'swap()' INSERT TEXT: 'swap(${1:i}, ${2:j})' - TARGET : '(std::vector::swap)' + TARGET : '(vector::swap)' TYPE : 'fun (&mut vector, u64, u64)' Method 'swap_remove()' INSERT TEXT: 'swap_remove(${1:i})' - TARGET : '(std::vector::swap_remove)' + TARGET : '(vector::swap_remove)' TYPE : 'fun (&mut vector, u64): Element' Method 'to_ascii_string()' INSERT TEXT: 'to_ascii_string()' @@ -182,26 +182,26 @@ Method 'try_to_string()' TYPE : 'fun (vector): Option' Method 'zip_do!()' INSERT TEXT: 'zip_do!(${1:v2}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::zip_do)' + TARGET : '(vector::zip_do)' TYPE : 'fun <$T1, $T2>(vector<$T1>, vector<$T2>, |$T1, $T2| -> ())' Method 'zip_do_mut!()' INSERT TEXT: 'zip_do_mut!(${1:v2}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::zip_do_mut)' + TARGET : '(vector::zip_do_mut)' TYPE : 'fun <$T1, $T2>(&mut vector<$T1>, &mut vector<$T2>, |&mut $T1, &mut $T2| -> ())' Method 'zip_do_ref!()' INSERT TEXT: 'zip_do_ref!(${1:v2}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::zip_do_ref)' + TARGET : '(vector::zip_do_ref)' TYPE : 'fun <$T1, $T2>(&vector<$T1>, &vector<$T2>, |&$T1, &$T2| -> ())' Method 'zip_do_reverse!()' INSERT TEXT: 'zip_do_reverse!(${1:v2}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::zip_do_reverse)' + TARGET : '(vector::zip_do_reverse)' TYPE : 'fun <$T1, $T2>(vector<$T1>, vector<$T2>, |$T1, $T2| -> ())' Method 'zip_map!()' INSERT TEXT: 'zip_map!(${1:v2}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::zip_map)' + TARGET : '(vector::zip_map)' TYPE : 'fun <$T1, $T2, $U>(vector<$T1>, vector<$T2>, |$T1, $T2| -> $U): vector<$U>' Method 'zip_map_ref!()' INSERT TEXT: 'zip_map_ref!(${1:v2}, |${2}, ${3}| ${4})' - TARGET : '(std::vector::zip_map_ref)' + TARGET : '(vector::zip_map_ref)' TYPE : 'fun <$T1, $T2, $U>(&vector<$T1>, &vector<$T2>, |&$T1, &$T2| -> $U): vector<$U>' diff --git a/external-crates/move/crates/move-analyzer/tests/enums.exp b/external-crates/move/crates/move-analyzer/tests/enums.exp index 6025ff14bd7..3c08331893a 100644 --- a/external-crates/move/crates/move-analyzer/tests/enums.exp +++ b/external-crates/move/crates/move-analyzer/tests/enums.exp @@ -229,8 +229,8 @@ Def: 'AnotherStruct', line: 6, def char: 18 TypeDef: 'AnotherStruct', line: 6, char: 18 On Hover: public struct Enums::struct_match::AnotherStruct has drop { - another_field: Enums::struct_match::SomeStruct, - field: u64 + field: u64, + another_field: Enums::struct_match::SomeStruct } -- test 2 ------------------- @@ -391,15 +391,22 @@ public enum Enums::variant_match::SomeEnum has drop { } -- test 11 ------------------- +use line: 15, use_ndx: 2 +Use: 'PositionalFields', start: 24, end: 40 +Def: 'PositionalFields', line: 7, def char: 8 +TypeDef: no info +On Hover: +Enums::variant_match::SomeEnum::PositionalFields(u64, Enums::variant_match::SomeStruct) + +-- test 12 ------------------- use line: 15, use_ndx: 3 Use: 's', start: 45, end: 46 -Def: 'SomeStruct', line: 7, def char: 30 +Def: 's', line: 12, def char: 29 TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -Enums::variant_match::SomeEnum -1: Enums::variant_match::SomeStruct +s: Enums::variant_match::SomeStruct --- test 12 ------------------- +-- test 13 ------------------- use line: 19, use_ndx: 0 Use: 'e', start: 20, end: 21 Def: 'e', line: 14, def char: 16 @@ -407,7 +414,7 @@ TypeDef: 'SomeEnum', line: 6, char: 16 On Hover: let mut e: Enums::variant_match::SomeEnum --- test 13 ------------------- +-- test 14 ------------------- use line: 20, use_ndx: 0 Use: 'SomeEnum', start: 12, end: 20 Def: 'SomeEnum', line: 6, def char: 16 @@ -419,7 +426,7 @@ public enum Enums::variant_match::SomeEnum has drop { PositionalFields( /* ... */ ) } --- test 14 ------------------- +-- test 15 ------------------- use line: 20, use_ndx: 1 Use: 'PositionalFields', start: 22, end: 38 Def: 'PositionalFields', line: 7, def char: 8 @@ -427,7 +434,7 @@ TypeDef: no info On Hover: Enums::variant_match::SomeEnum::PositionalFields(u64, Enums::variant_match::SomeStruct) --- test 15 ------------------- +-- test 16 ------------------- use line: 20, use_ndx: 2 Use: 'num', start: 39, end: 42 Def: 'u64', line: 7, def char: 25 @@ -436,7 +443,7 @@ On Hover: Enums::variant_match::SomeEnum 0: u64 --- test 16 ------------------- +-- test 17 ------------------- use line: 20, use_ndx: 3 Use: 's', start: 44, end: 45 Def: 'SomeStruct', line: 7, def char: 30 @@ -445,7 +452,7 @@ On Hover: Enums::variant_match::SomeEnum 1: Enums::variant_match::SomeStruct --- test 17 ------------------- +-- test 18 ------------------- use line: 21, use_ndx: 0 Use: 'num', start: 17, end: 20 Def: 'num', line: 19, def char: 39 @@ -453,7 +460,7 @@ TypeDef: no info On Hover: num: &mut u64 --- test 18 ------------------- +-- test 19 ------------------- use line: 21, use_ndx: 1 Use: 's', start: 23, end: 24 Def: 's', line: 19, def char: 44 @@ -461,7 +468,7 @@ TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: s: &mut Enums::variant_match::SomeStruct --- test 19 ------------------- +-- test 20 ------------------- use line: 21, use_ndx: 2 Use: 'some_field', start: 25, end: 35 Def: 'some_field', line: 3, def char: 8 @@ -470,7 +477,7 @@ On Hover: Enums::variant_match::SomeStruct some_field: u64 --- test 20 ------------------- +-- test 21 ------------------- use line: 24, use_ndx: 0 Use: 'SE', start: 12, end: 14 Def: 'SomeEnum', line: 6, def char: 16 @@ -482,7 +489,7 @@ public enum Enums::variant_match::SomeEnum has drop { PositionalFields( /* ... */ ) } --- test 21 ------------------- +-- test 22 ------------------- use line: 24, use_ndx: 1 Use: 'NamedFields', start: 16, end: 27 Def: 'NamedFields', line: 8, def char: 8 @@ -490,7 +497,7 @@ TypeDef: no info On Hover: Enums::variant_match::SomeEnum::NamedFields{num1: u64, num2: u64, s: Enums::variant_match::SomeStruct} --- test 22 ------------------- +-- test 23 ------------------- use line: 24, use_ndx: 2 Use: 'num1', start: 30, end: 34 Def: 'num1', line: 8, def char: 21 @@ -499,7 +506,7 @@ On Hover: Enums::variant_match::SomeEnum num1: u64 --- test 23 ------------------- +-- test 24 ------------------- use line: 24, use_ndx: 3 Use: 'num2', start: 36, end: 40 Def: 'num2', line: 8, def char: 32 @@ -508,7 +515,7 @@ On Hover: Enums::variant_match::SomeEnum num2: u64 --- test 24 ------------------- +-- test 25 ------------------- use line: 24, use_ndx: 4 Use: 's', start: 46, end: 47 Def: 's', line: 8, def char: 43 @@ -517,7 +524,7 @@ On Hover: Enums::variant_match::SomeEnum s: Enums::variant_match::SomeStruct --- test 25 ------------------- +-- test 26 ------------------- use line: 24, use_ndx: 5 Use: 'num1', start: 55, end: 59 Def: 'num1', line: 23, def char: 30 @@ -525,7 +532,7 @@ TypeDef: no info On Hover: num1: &u64 --- test 26 ------------------- +-- test 27 ------------------- use line: 24, use_ndx: 6 Use: 's', start: 62, end: 63 Def: 's', line: 23, def char: 46 @@ -533,7 +540,7 @@ TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: s: &Enums::variant_match::SomeStruct --- test 27 ------------------- +-- test 28 ------------------- use line: 24, use_ndx: 8 Use: 'num1', start: 79, end: 83 Def: 'num1', line: 23, def char: 30 @@ -541,7 +548,7 @@ TypeDef: no info On Hover: num1: &u64 --- test 28 ------------------- +-- test 29 ------------------- use line: 24, use_ndx: 9 Use: 'local', start: 86, end: 91 Def: 'local', line: 16, def char: 12 @@ -549,7 +556,7 @@ TypeDef: no info On Hover: let local: u64 --- test 29 ------------------- +-- test 30 ------------------- use line: 25, use_ndx: 0 Use: 's', start: 16, end: 17 Def: 's', line: 23, def char: 46 @@ -557,7 +564,7 @@ TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: s: &mut Enums::variant_match::SomeStruct --- test 30 ------------------- +-- test 31 ------------------- use line: 25, use_ndx: 2 Use: 'num1', start: 32, end: 36 Def: 'num1', line: 23, def char: 30 @@ -565,7 +572,7 @@ TypeDef: no info On Hover: num1: &mut u64 --- test 31 ------------------- +-- test 32 ------------------- use line: 25, use_ndx: 3 Use: 'num2', start: 40, end: 44 Def: 'num2', line: 23, def char: 36 diff --git a/external-crates/move/crates/move-analyzer/tests/enums.ide b/external-crates/move/crates/move-analyzer/tests/enums.ide index 020a1a48b43..b03e94fb866 100644 --- a/external-crates/move/crates/move-analyzer/tests/enums.ide +++ b/external-crates/move/crates/move-analyzer/tests/enums.ide @@ -49,6 +49,10 @@ "use_line": 15, "use_ndx": 1 }, + { + "use_line": 15, + "use_ndx": 2 + }, { "use_line": 15, "use_ndx": 3 diff --git a/external-crates/move/crates/move-analyzer/tests/ide_testsuite.rs b/external-crates/move/crates/move-analyzer/tests/ide_testsuite.rs index 707d0e65956..536dccde437 100644 --- a/external-crates/move/crates/move-analyzer/tests/ide_testsuite.rs +++ b/external-crates/move/crates/move-analyzer/tests/ide_testsuite.rs @@ -13,11 +13,12 @@ use std::{ use json_comments::StripComments; use lsp_types::{InlayHintKind, InlayHintLabel, InlayHintTooltip, Position}; use move_analyzer::{ - completion::completion_items, + completions::compute_completions_with_symbols, inlay_hints::inlay_hints_internal, symbols::{ - def_info_doc_string, get_symbols, maybe_convert_for_guard, PrecompiledPkgDeps, Symbols, - UseDefMap, + compute_symbols, compute_symbols_parsed_program, compute_symbols_pre_process, + def_info_doc_string, get_compiled_pkg, maybe_convert_for_guard, CompiledPkgInfo, Symbols, + SymbolsComputationData, UseDefMap, }, }; use move_command_line_common::testing::{ @@ -178,9 +179,8 @@ impl CompletionTest { fn test( &self, test_idx: usize, - ide_files_root: VfsPath, - pkg_dependencies: Arc>>, - symbols: &Symbols, + mut compiled_pkg_info: CompiledPkgInfo, + symbols: &mut Symbols, output: &mut dyn std::io::Write, use_file_path: &Path, ) -> anyhow::Result<()> { @@ -190,13 +190,30 @@ impl CompletionTest { line: lsp_use_line, character: lsp_use_col, }; - let items = completion_items( - symbols, - ide_files_root, - pkg_dependencies, - use_file_path, - use_pos, + + // symbols do not change for each test, so we can reuse the same symbols + // but we need to recompute the cursor each time + let cursor_path = use_file_path.to_path_buf(); + let cursor_info = Some((&cursor_path, use_pos)); + let mut symbols_computation_data = SymbolsComputationData::new(); + let mut symbols_computation_data_deps = SymbolsComputationData::new(); + // we only compute cursor context and tag it on the existing symbols to avoid spending time + // recomputing all symbols (saves quite a bit of time when running the test suite) + let mut cursor_context = compute_symbols_pre_process( + &mut symbols_computation_data, + &mut symbols_computation_data_deps, + &mut compiled_pkg_info, + cursor_info, ); + cursor_context = compute_symbols_parsed_program( + &mut symbols_computation_data, + &mut symbols_computation_data_deps, + &compiled_pkg_info, + cursor_context, + ); + symbols.cursor_context = cursor_context; + + let items = compute_completions_with_symbols(symbols, &cursor_path, use_pos); writeln!(output, "-- test {test_idx} -------------------")?; writeln!( output, @@ -226,8 +243,8 @@ impl CursorTest { fn test( &self, test_ndx: usize, - ide_files_root: VfsPath, - pkg_dependencies: Arc>>, + mut compiled_pkg_info: CompiledPkgInfo, + symbols: &mut Symbols, output: &mut dyn std::io::Write, path: &Path, ) -> anyhow::Result<()> { @@ -239,21 +256,32 @@ impl CursorTest { let line = line - 1; // 0th-based let character = character - 1; // 0th-based - let (symbols_opt, _) = get_symbols( - pkg_dependencies, - ide_files_root, - path, - LintLevel::None, - Some((&path.to_path_buf(), Position { line, character })), - )?; - let symbols = symbols_opt.unwrap(); + // symbols do not change for each test, so we can reuse the same symbols + // but we need to recompute the cursor each time + let cursor_path = path.to_path_buf(); + let cursor_info = Some((&cursor_path, Position { line, character })); + let mut symbols_computation_data = SymbolsComputationData::new(); + let mut symbols_computation_data_deps = SymbolsComputationData::new(); + let mut cursor_context = compute_symbols_pre_process( + &mut symbols_computation_data, + &mut symbols_computation_data_deps, + &mut compiled_pkg_info, + cursor_info, + ); + cursor_context = compute_symbols_parsed_program( + &mut symbols_computation_data, + &mut symbols_computation_data_deps, + &compiled_pkg_info, + cursor_context, + ); + symbols.cursor_context = cursor_context.clone(); writeln!( output, "-- test {test_ndx} @ {line}:{character} ------------" )?; writeln!(output, "expected: {description}")?; - writeln!(output, "{}", symbols.cursor_context.unwrap())?; + writeln!(output, "{}", cursor_context.unwrap())?; Ok(()) } } @@ -342,34 +370,36 @@ fn check_expected(expected_path: &Path, result: &str) -> anyhow::Result<()> { fn initial_symbols( project: String, -) -> datatest_stable::Result<( - PathBuf, - VfsPath, - Arc>>, - Symbols, -)> { +) -> datatest_stable::Result<(PathBuf, CompiledPkgInfo, Symbols)> { let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut project_path = base_path.clone(); project_path.push(project); let ide_files_root: VfsPath = MemoryFS::new().into(); let pkg_deps = Arc::new(Mutex::new(BTreeMap::new())); - let (symbols_opt, _) = get_symbols( + + let (compiled_pkg_info_opt, _) = get_compiled_pkg( pkg_deps.clone(), ide_files_root.clone(), project_path.as_path(), LintLevel::None, - None, )?; - let symbols = symbols_opt.ok_or("DID NOT FIND SYMBOLS")?; - Ok((project_path, ide_files_root, pkg_deps, symbols)) + + let compiled_pkg_info = compiled_pkg_info_opt.ok_or("PACKAGE COMPILATION FAILED")?; + let symbols = compute_symbols( + Arc::new(Mutex::new(BTreeMap::new())), + compiled_pkg_info.clone(), + None, + ); + + Ok((project_path, compiled_pkg_info, symbols)) } fn use_def_test_suite( project: String, file_tests: BTreeMap>, ) -> datatest_stable::Result { - let (project_path, _, _, symbols) = initial_symbols(project)?; + let (project_path, _, symbols) = initial_symbols(project)?; let mut output: BufWriter<_> = BufWriter::new(Vec::new()); let writer: &mut dyn io::Write = output.get_mut(); @@ -403,7 +433,7 @@ fn completion_test_suite( project: String, file_tests: BTreeMap>, ) -> datatest_stable::Result { - let (project_path, ide_files_root, pkg_deps, symbols) = initial_symbols(project)?; + let (project_path, compiled_pkg_info, mut symbols) = initial_symbols(project)?; let mut output: BufWriter<_> = BufWriter::new(Vec::new()); let writer: &mut dyn io::Write = output.get_mut(); @@ -420,14 +450,7 @@ fn completion_test_suite( let cpath = dunce::canonicalize(&fpath).unwrap(); for (idx, test) in tests.iter().enumerate() { - test.test( - idx, - ide_files_root.clone(), - pkg_deps.clone(), - &symbols, - writer, - &cpath, - )?; + test.test(idx, compiled_pkg_info.clone(), &mut symbols, writer, &cpath)?; } } @@ -439,7 +462,7 @@ fn cursor_test_suite( project: String, file_tests: BTreeMap>, ) -> datatest_stable::Result { - let (project_path, ide_files_root, pkg_deps, _) = initial_symbols(project)?; + let (project_path, compiled_pkg_info, mut symbols) = initial_symbols(project)?; let mut output: BufWriter<_> = BufWriter::new(Vec::new()); let writer: &mut dyn io::Write = output.get_mut(); @@ -455,13 +478,7 @@ fn cursor_test_suite( fpath.push(format!("sources/{file}")); let cpath = dunce::canonicalize(&fpath).unwrap(); for (idx, test) in tests.iter().enumerate() { - test.test( - idx, - ide_files_root.clone(), - pkg_deps.clone(), - writer, - &cpath, - )?; + test.test(idx, compiled_pkg_info.clone(), &mut symbols, writer, &cpath)?; } } @@ -473,7 +490,7 @@ fn hint_test_suite( project: String, file_tests: BTreeMap>, ) -> datatest_stable::Result { - let (project_path, _, _, symbols) = initial_symbols(project)?; + let (project_path, _, symbols) = initial_symbols(project)?; let mut output: BufWriter<_> = BufWriter::new(Vec::new()); let writer: &mut dyn io::Write = output.get_mut(); diff --git a/external-crates/move/crates/move-analyzer/tests/implicit_uses.exp b/external-crates/move/crates/move-analyzer/tests/implicit_uses.exp index 7c7baf860e9..d324756aee3 100644 --- a/external-crates/move/crates/move-analyzer/tests/implicit_uses.exp +++ b/external-crates/move/crates/move-analyzer/tests/implicit_uses.exp @@ -5,13 +5,12 @@ Use: 'Option', start: 13, end: 19 Def: 'Option', line: 8, def char: 18 TypeDef: 'Option', line: 8, char: 18 On Hover: -public struct std::option::Option has copy, drop, store { +public struct Option has copy, drop, store { vec: vector } -Abstraction of a value that may or may not be present. Implemented with a vector of size -zero or one because Move bytecode does not have ADTs. - + Abstraction of a value that may or may not be present. Implemented with a vector of size + zero or one because Move bytecode does not have ADTs. -- test 1 ------------------- use line: 8, use_ndx: 2 @@ -19,8 +18,7 @@ Use: 'option', start: 26, end: 32 Def: 'option', line: 5, def char: 12 TypeDef: no info On Hover: -module std::option - -This module defines the Option type and its methods to represent and handle an optional value. +module option + This module defines the Option type and its methods to represent and handle an optional value. diff --git a/external-crates/move/crates/move-analyzer/tests/imports.exp b/external-crates/move/crates/move-analyzer/tests/imports.exp index 9fde0cfd229..56c9c662d5f 100644 --- a/external-crates/move/crates/move-analyzer/tests/imports.exp +++ b/external-crates/move/crates/move-analyzer/tests/imports.exp @@ -7,8 +7,7 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment -- test 1 ------------------- use line: 8, use_ndx: 0 @@ -69,20 +68,20 @@ module Symbols::M2 -- test 8 ------------------- use line: 11, use_ndx: 1 Use: 'SomeOtherStruct', start: 22, end: 37 -Def: 'SomeOtherStruct', line: 2, def char: 11 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +Def: 'SomeOtherStruct', line: 2, def char: 18 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: -struct Symbols::M2::SomeOtherStruct has drop { +public struct Symbols::M2::SomeOtherStruct has drop { some_field: u64 } -- test 9 ------------------- use line: 11, use_ndx: 2 Use: 'S', start: 41, end: 42 -Def: 'SomeOtherStruct', line: 2, def char: 11 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +Def: 'SomeOtherStruct', line: 2, def char: 18 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: -struct Symbols::M2::SomeOtherStruct has drop { +public struct Symbols::M2::SomeOtherStruct has drop { some_field: u64 } @@ -105,10 +104,10 @@ module Symbols::M1 -- test 12 ------------------- use line: 38, use_ndx: 1 Use: 'S', start: 27, end: 28 -Def: 'SomeOtherStruct', line: 2, def char: 11 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +Def: 'SomeOtherStruct', line: 2, def char: 18 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: -struct Symbols::M2::SomeOtherStruct has drop { +public struct Symbols::M2::SomeOtherStruct has drop { some_field: u64 } diff --git a/external-crates/move/crates/move-analyzer/tests/macros.exp b/external-crates/move/crates/move-analyzer/tests/macros.exp index 10f0e3341fc..c18896cd20d 100644 --- a/external-crates/move/crates/move-analyzer/tests/macros.exp +++ b/external-crates/move/crates/move-analyzer/tests/macros.exp @@ -38,7 +38,10 @@ Use: 'foo', start: 14, end: 17 Def: 'foo', line: 6, def char: 14 TypeDef: no info On Hover: -macro fun Macros::macros::foo($i: u64, $body: |u64| -> u64): u64 +macro fun Macros::macros::foo( + $i: u64, + $body: |u64| -> u64 +): u64 -- test 1 ------------------- use line: 7, use_ndx: 1 @@ -62,7 +65,10 @@ Use: 'bar', start: 14, end: 17 Def: 'bar', line: 14, def char: 14 TypeDef: no info On Hover: -macro fun Macros::macros::bar($i: Macros::macros::SomeStruct, $body: |Macros::macros::SomeStruct| -> Macros::macros::SomeStruct): Macros::macros::SomeStruct +macro fun Macros::macros::bar( + $i: Macros::macros::SomeStruct, + $body: |Macros::macros::SomeStruct| -> Macros::macros::SomeStruct +): Macros::macros::SomeStruct -- test 4 ------------------- use line: 15, use_ndx: 1 @@ -126,7 +132,10 @@ Use: 'for_each', start: 14, end: 22 Def: 'for_each', line: 18, def char: 14 TypeDef: no info On Hover: -macro fun Macros::macros::for_each<$T>($v: &vector<$T>, $body: |&$T| -> ()) +macro fun Macros::macros::for_each<$T>( + $v: &vector<$T>, + $body: |&$T| -> () +) -- test 11 ------------------- use line: 19, use_ndx: 1 @@ -182,7 +191,10 @@ Use: 'foo', start: 24, end: 27 Def: 'foo', line: 6, def char: 14 TypeDef: no info On Hover: -macro fun Macros::macros::foo($i: u64, $body: |u64| -> u64): u64 +macro fun Macros::macros::foo( + $i: u64, + $body: |u64| -> u64 +): u64 -- test 18 ------------------- use line: 33, use_ndx: 2 @@ -222,7 +234,10 @@ Use: 'foo', start: 68, end: 71 Def: 'foo', line: 6, def char: 14 TypeDef: no info On Hover: -macro fun Macros::macros::foo($i: u64, $body: |u64| -> u64): u64 +macro fun Macros::macros::foo( + $i: u64, + $body: |u64| -> u64 +): u64 -- test 23 ------------------- use line: 38, use_ndx: 8 @@ -270,7 +285,10 @@ Use: 'feach', start: 11, end: 16 Def: 'for_each', line: 18, def char: 14 TypeDef: no info On Hover: -macro fun Macros::macros::for_each<$T>($v: &vector<$T>, $body: |&$T| -> ()) +macro fun Macros::macros::for_each<$T>( + $v: &vector<$T>, + $body: |&$T| -> () +) -- test 29 ------------------- use line: 52, use_ndx: 2 diff --git a/external-crates/move/crates/move-analyzer/tests/mod_access.exp b/external-crates/move/crates/move-analyzer/tests/mod_access.exp index 6296b548ccb..983479d8aee 100644 --- a/external-crates/move/crates/move-analyzer/tests/mod_access.exp +++ b/external-crates/move/crates/move-analyzer/tests/mod_access.exp @@ -7,8 +7,7 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment -- test 1 ------------------- use line: 20, use_ndx: 0 @@ -18,8 +17,7 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment -- test 2 ------------------- use line: 20, use_ndx: 3 @@ -29,8 +27,7 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment -- test 3 ------------------- use line: 23, use_ndx: 2 @@ -40,8 +37,7 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment -- test 4 ------------------- use line: 24, use_ndx: 0 @@ -51,8 +47,7 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment -- test 5 ------------------- use line: 28, use_ndx: 2 @@ -86,6 +81,5 @@ TypeDef: no info On Hover: module Symbols::M9 -A module doc comment - + A module doc comment diff --git a/external-crates/move/crates/move-analyzer/tests/move-2024/sources/structs.move b/external-crates/move/crates/move-analyzer/tests/move-2024/sources/structs.move index 8247c40af8d..ab3809311e1 100644 --- a/external-crates/move/crates/move-analyzer/tests/move-2024/sources/structs.move +++ b/external-crates/move/crates/move-analyzer/tests/move-2024/sources/structs.move @@ -8,4 +8,41 @@ module Move2024::structs { (positional.0, positional.1) } + public struct Named has drop, copy { + some_field: u64, + another_field: SomeStruct, + } + + public fun pack_named(val1: u64, another_field: SomeStruct): Named { + Named { + some_field: val1, + another_field, + } + } + + public fun pack_positional(val1: u64, val2: SomeStruct): Positional { + Positional(val1, val2) + } + + public fun unpack_named(named: Named): (u64, SomeStruct) { + let Named { + some_field: val1, + another_field, + } = named; + (val1, another_field) + } + + public fun unpack_positional(positional: Positional): (u64, SomeStruct) { + let Positional(val1, val2) = positional; + (val1, val2) + } + + public fun borrow_named(named: Named): u64 { + named.some_field + } + + public fun borrow_positional(positional: Positional): u64 { + positional.0 + } + } diff --git a/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/Move.toml b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/Move.toml new file mode 100644 index 00000000000..ece1e0a62fe --- /dev/null +++ b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "DepPkg" +edition = "2024.alpha" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } + +[addresses] +DepPkg = "0x0" diff --git a/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/sources/M1.move b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/sources/M1.move new file mode 100644 index 00000000000..59051e45fe5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/dep-pkg/sources/M1.move @@ -0,0 +1,4 @@ +#[test_only] +module DepPkg::M1 { + public fun foo() {} +} diff --git a/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/Move.toml b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/Move.toml new file mode 100644 index 00000000000..0411f2618e1 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "Pkg" +edition = "2024.alpha" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } +DepPkg = { local = "../dep-pkg" } + +[addresses] +Pkg = "0x0" diff --git a/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/sources/M1.move b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/sources/M1.move new file mode 100644 index 00000000000..2a11cefad8b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/tests/same-pkg-name-error/pkg/sources/M1.move @@ -0,0 +1,15 @@ +#[test_only] +module Pkg::M1 { + public fun foo() {} +} + + +module Pkg::M2 { + + #[test] + public fun bar() { + Pkg::M1::foo(); + DepPkg::M1::foo() + } + +} diff --git a/external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.exp b/external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.exp new file mode 100644 index 00000000000..58cee3e93a4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.exp @@ -0,0 +1 @@ +== M1.move ======================================================== diff --git a/external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.ide b/external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.ide new file mode 100644 index 00000000000..8b1f96392bb --- /dev/null +++ b/external-crates/move/crates/move-analyzer/tests/same_pkg_name_error.ide @@ -0,0 +1,8 @@ +{ + "UseDef": { + "project": "tests/same-pkg-name-error/pkg", + "file_tests": { + "M1.move": [] + } + } +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/tests/structs.exp b/external-crates/move/crates/move-analyzer/tests/structs.exp index 628947df926..14ebc0949f3 100644 --- a/external-crates/move/crates/move-analyzer/tests/structs.exp +++ b/external-crates/move/crates/move-analyzer/tests/structs.exp @@ -63,3 +63,125 @@ On Hover: Move2024::structs::Positional 1: Move2024::structs::SomeStruct +-- test 7 ------------------- +use line: 12, use_ndx: 0 +Use: 'some_field', start: 8, end: 18 +Def: 'some_field', line: 11, def char: 8 +TypeDef: no info +On Hover: +Move2024::structs::Named +some_field: u64 + +-- test 8 ------------------- +use line: 13, use_ndx: 0 +Use: 'another_field', start: 8, end: 21 +Def: 'another_field', line: 12, def char: 8 +TypeDef: 'SomeStruct', line: 2, char: 18 +On Hover: +Move2024::structs::Named +another_field: Move2024::structs::SomeStruct + +-- test 9 ------------------- +use line: 18, use_ndx: 0 +Use: 'some_field', start: 12, end: 22 +Def: 'some_field', line: 11, def char: 8 +TypeDef: no info +On Hover: +Move2024::structs::Named +some_field: u64 + +-- test 10 ------------------- +use line: 18, use_ndx: 1 +Use: 'val1', start: 24, end: 28 +Def: 'val1', line: 15, def char: 26 +TypeDef: no info +On Hover: +val1: u64 + +-- test 11 ------------------- +use line: 19, use_ndx: 0 +Use: 'another_field', start: 12, end: 25 +Def: 'another_field', line: 12, def char: 8 +TypeDef: 'SomeStruct', line: 2, char: 18 +On Hover: +Move2024::structs::Named +another_field: Move2024::structs::SomeStruct + +-- test 12 ------------------- +use line: 24, use_ndx: 1 +Use: 'val1', start: 19, end: 23 +Def: 'val1', line: 22, def char: 31 +TypeDef: no info +On Hover: +val1: u64 + +-- test 13 ------------------- +use line: 24, use_ndx: 2 +Use: 'val2', start: 25, end: 29 +Def: 'val2', line: 22, def char: 42 +TypeDef: 'SomeStruct', line: 2, char: 18 +On Hover: +val2: Move2024::structs::SomeStruct + +-- test 14 ------------------- +use line: 29, use_ndx: 0 +Use: 'some_field', start: 12, end: 22 +Def: 'some_field', line: 11, def char: 8 +TypeDef: no info +On Hover: +Move2024::structs::Named +some_field: u64 + +-- test 15 ------------------- +use line: 29, use_ndx: 1 +Use: 'val1', start: 24, end: 28 +Def: 'val1', line: 28, def char: 24 +TypeDef: no info +On Hover: +val1: u64 + +-- test 16 ------------------- +use line: 30, use_ndx: 0 +Use: 'another_field', start: 12, end: 25 +Def: 'another_field', line: 12, def char: 8 +TypeDef: 'SomeStruct', line: 2, char: 18 +On Hover: +Move2024::structs::Named +another_field: Move2024::structs::SomeStruct + +-- test 17 ------------------- +use line: 36, use_ndx: 1 +Use: 'v', start: 23, end: 24 +Def: 'u64', line: 4, def char: 29 +TypeDef: no info +On Hover: +Move2024::structs::Positional +0: u64 + +-- test 18 ------------------- +use line: 36, use_ndx: 2 +Use: 'v', start: 29, end: 30 +Def: 'SomeStruct', line: 4, def char: 34 +TypeDef: 'SomeStruct', line: 2, char: 18 +On Hover: +Move2024::structs::Positional +1: Move2024::structs::SomeStruct + +-- test 19 ------------------- +use line: 41, use_ndx: 1 +Use: 'INVALID USE IDENT', start: 14, end: 24 +Def: 'some_field', line: 11, def char: 8 +TypeDef: no info +On Hover: +Move2024::structs::Named +some_field: u64 + +-- test 20 ------------------- +use line: 45, use_ndx: 1 +Use: 'INVALID USE IDENT', start: 19, end: 20 +Def: 'u64', line: 4, def char: 29 +TypeDef: no info +On Hover: +Move2024::structs::Positional +0: u64 + diff --git a/external-crates/move/crates/move-analyzer/tests/structs.ide b/external-crates/move/crates/move-analyzer/tests/structs.ide index 8ecf41b6c13..faa0b14e458 100644 --- a/external-crates/move/crates/move-analyzer/tests/structs.ide +++ b/external-crates/move/crates/move-analyzer/tests/structs.ide @@ -32,6 +32,62 @@ { "use_line": 8, "use_ndx": 3 + }, + { + "use_line": 12, + "use_ndx": 0 + }, + { + "use_line": 13, + "use_ndx": 0 + }, + { + "use_line": 18, + "use_ndx": 0 + }, + { + "use_line": 18, + "use_ndx": 1 + }, + { + "use_line": 19, + "use_ndx": 0 + }, + { + "use_line": 24, + "use_ndx": 1 + }, + { + "use_line": 24, + "use_ndx": 2 + }, + { + "use_line": 29, + "use_ndx": 0 + }, + { + "use_line": 29, + "use_ndx": 1 + }, + { + "use_line": 30, + "use_ndx": 0 + }, + { + "use_line": 36, + "use_ndx": 1 + }, + { + "use_line": 36, + "use_ndx": 2 + }, + { + "use_line": 41, + "use_ndx": 1 + }, + { + "use_line": 45, + "use_ndx": 1 } ] } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols.exp b/external-crates/move/crates/move-analyzer/tests/symbols.exp index 7e06c2c2100..23221a424c1 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols.exp +++ b/external-crates/move/crates/move-analyzer/tests/symbols.exp @@ -1,11 +1,11 @@ == M1.move ======================================================== -- test 0 ------------------- use line: 3, use_ndx: 0 -Use: 'SomeStruct', start: 11, end: 21 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Use: 'SomeStruct', start: 18, end: 28 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } @@ -23,33 +23,35 @@ Use: 'unpack', start: 8, end: 14 Def: 'unpack', line: 9, def char: 8 TypeDef: no info On Hover: -fun Symbols::M1::unpack(s: Symbols::M1::SomeStruct): u64 +fun Symbols::M1::unpack( + s: Symbols::M1::SomeStruct +): u64 -- test 3 ------------------- use line: 10, use_ndx: 1 Use: 's', start: 15, end: 16 Def: 's', line: 9, def char: 15 -TypeDef: 'SomeStruct', line: 2, char: 11 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: s: Symbols::M1::SomeStruct -- test 4 ------------------- use line: 10, use_ndx: 2 Use: 'SomeStruct', start: 18, end: 28 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } -- test 5 ------------------- use line: 11, use_ndx: 0 Use: 'SomeStruct', start: 12, end: 22 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } @@ -74,7 +76,7 @@ value: u64 use line: 11, use_ndx: 3 Use: 's', start: 47, end: 48 Def: 's', line: 9, def char: 15 -TypeDef: 'SomeStruct', line: 2, char: 11 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: s: Symbols::M1::SomeStruct @@ -89,20 +91,20 @@ value: u64 -- test 10 ------------------- use line: 20, use_ndx: 1 Use: 'SomeStruct', start: 16, end: 26 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } -- test 11 ------------------- use line: 21, use_ndx: 1 Use: 'SomeStruct', start: 18, end: 28 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } @@ -126,10 +128,10 @@ const Symbols::M1::SOME_CONST: u64 = 42 -- test 14 ------------------- use line: 25, use_ndx: 2 Use: 'SomeOtherStruct', start: 41, end: 56 -Def: 'SomeOtherStruct', line: 2, def char: 11 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +Def: 'SomeOtherStruct', line: 2, def char: 18 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: -struct Symbols::M2::SomeOtherStruct has drop { +public struct Symbols::M2::SomeOtherStruct has drop { some_field: u64 } @@ -139,7 +141,9 @@ Use: 'some_other_struct', start: 21, end: 38 Def: 'some_other_struct', line: 6, def char: 15 TypeDef: no info On Hover: -public fun Symbols::M2::some_other_struct(v: u64): Symbols::M2::SomeOtherStruct +public fun Symbols::M2::some_other_struct( + v: u64 +): Symbols::M2::SomeOtherStruct -- test 16 ------------------- use line: 26, use_ndx: 2 @@ -152,10 +156,10 @@ const Symbols::M1::SOME_CONST: u64 = 42 -- test 17 ------------------- use line: 31, use_ndx: 1 Use: 'SomeOtherStruct', start: 35, end: 50 -Def: 'SomeOtherStruct', line: 2, def char: 11 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +Def: 'SomeOtherStruct', line: 2, def char: 18 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: -struct Symbols::M2::SomeOtherStruct has drop { +public struct Symbols::M2::SomeOtherStruct has drop { some_field: u64 } @@ -165,7 +169,9 @@ Use: 'acq', start: 8, end: 11 Def: 'acq', line: 34, def char: 8 TypeDef: no info On Hover: -fun Symbols::M1::acq(uint: u64): u64 +fun Symbols::M1::acq( + uint: u64 +): u64 -- test 19 ------------------- use line: 41, use_ndx: 2 @@ -194,20 +200,20 @@ fun Symbols::M1::vec(): vector -- test 22 ------------------- use line: 46, use_ndx: 0 Use: 'SomeStruct', start: 15, end: 25 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } -- test 23 ------------------- use line: 46, use_ndx: 1 Use: 'SomeStruct', start: 27, end: 37 -Def: 'SomeStruct', line: 2, def char: 11 -TypeDef: 'SomeStruct', line: 2, char: 11 +Def: 'SomeStruct', line: 2, def char: 18 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: -struct Symbols::M1::SomeStruct has drop, store, key { +public struct Symbols::M1::SomeStruct has drop, store { some_field: u64 } @@ -224,17 +230,17 @@ some_field: u64 use line: 46, use_ndx: 3 Use: 's', start: 57, end: 58 Def: 's', line: 44, def char: 12 -TypeDef: 'SomeStruct', line: 2, char: 11 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: let s: Symbols::M1::SomeStruct -- test 26 ------------------- use line: 57, use_ndx: 1 Use: 'tmp', start: 21, end: 24 -Def: 'tmp', line: 55, def char: 12 +Def: 'tmp', line: 55, def char: 16 TypeDef: no info On Hover: -let tmp: u64 +let mut tmp: u64 -- test 27 ------------------- use line: 58, use_ndx: 0 @@ -258,7 +264,10 @@ Use: 'ret', start: 8, end: 11 Def: 'ret', line: 61, def char: 8 TypeDef: no info On Hover: -fun Symbols::M1::ret(p1: bool, p2: u64): u64 +fun Symbols::M1::ret( + p1: bool, + p2: u64 +): u64 -- test 30 ------------------- use line: 64, use_ndx: 0 @@ -312,7 +321,7 @@ const Symbols::M1::SOME_CONST: u64 = 42 use line: 95, use_ndx: 0 Use: 'outer', start: 8, end: 13 Def: 'outer', line: 93, def char: 12 -TypeDef: 'OuterStruct', line: 87, char: 11 +TypeDef: 'OuterStruct', line: 87, char: 18 On Hover: let outer: Symbols::M1::OuterStruct @@ -320,7 +329,7 @@ let outer: Symbols::M1::OuterStruct use line: 95, use_ndx: 1 Use: 'some_struct', start: 14, end: 25 Def: 'some_struct', line: 88, def char: 8 -TypeDef: 'SomeStruct', line: 2, char: 11 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: Symbols::M1::OuterStruct some_struct: Symbols::M1::SomeStruct @@ -338,7 +347,7 @@ some_field: u64 use line: 103, use_ndx: 0 Use: 'some_struct', start: 10, end: 21 Def: 'some_struct', line: 88, def char: 8 -TypeDef: 'SomeStruct', line: 2, char: 11 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: Symbols::M1::OuterStruct some_struct: Symbols::M1::SomeStruct @@ -347,7 +356,7 @@ some_struct: Symbols::M1::SomeStruct use line: 109, use_ndx: 1 Use: 'outer', start: 17, end: 22 Def: 'outer', line: 107, def char: 12 -TypeDef: 'OuterStruct', line: 87, char: 11 +TypeDef: 'OuterStruct', line: 87, char: 18 On Hover: let outer: Symbols::M1::OuterStruct @@ -355,7 +364,7 @@ let outer: Symbols::M1::OuterStruct use line: 109, use_ndx: 2 Use: 'some_struct', start: 23, end: 34 Def: 'some_struct', line: 88, def char: 8 -TypeDef: 'SomeStruct', line: 2, char: 11 +TypeDef: 'SomeStruct', line: 2, char: 18 On Hover: Symbols::M1::OuterStruct some_struct: Symbols::M1::SomeStruct @@ -389,7 +398,7 @@ const Symbols::M1::SOME_CONST: u64 = 42 use line: 123, use_ndx: 1 Use: 'p', start: 21, end: 22 Def: 'p', line: 122, def char: 21 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: p: Symbols::M2::SomeOtherStruct @@ -397,7 +406,7 @@ p: Symbols::M2::SomeOtherStruct use line: 124, use_ndx: 0 Use: 'INVALID USE IDENT', start: 8, end: 9 Def: 'p', line: 122, def char: 21 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: p: Symbols::M2::SomeOtherStruct @@ -405,7 +414,7 @@ p: Symbols::M2::SomeOtherStruct use line: 128, use_ndx: 0 Use: 'tmp', start: 12, end: 15 Def: 'tmp', line: 127, def char: 12 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: let tmp: Symbols::M2::SomeOtherStruct @@ -413,15 +422,15 @@ let tmp: Symbols::M2::SomeOtherStruct use line: 130, use_ndx: 0 Use: 'INVALID USE IDENT', start: 12, end: 15 Def: 'tmp', line: 127, def char: 12 -TypeDef: 'SomeOtherStruct', line: 2, char: 11 +TypeDef: 'SomeOtherStruct', line: 2, char: 18 On Hover: let tmp: Symbols::M2::SomeOtherStruct == M3.move ======================================================== -- test 0 ------------------- use line: 3, use_ndx: 1 -Use: 'T', start: 23, end: 24 -Def: 'T', line: 2, def char: 23 +Use: 'T', start: 30, end: 31 +Def: 'T', line: 2, def char: 30 TypeDef: no info On Hover: T @@ -429,7 +438,7 @@ T -- test 1 ------------------- use line: 4, use_ndx: 1 Use: 'T', start: 20, end: 21 -Def: 'T', line: 2, def char: 23 +Def: 'T', line: 2, def char: 30 TypeDef: no info On Hover: T @@ -486,7 +495,7 @@ T use line: 12, use_ndx: 0 Use: 'INVALID USE IDENT', start: 8, end: 13 Def: 'param', line: 10, def char: 33 -TypeDef: 'ParamStruct', line: 2, char: 11 +TypeDef: 'ParamStruct', line: 2, char: 18 On Hover: param: Symbols::M3::ParamStruct @@ -501,17 +510,17 @@ T -- test 10 ------------------- use line: 24, use_ndx: 1 Use: 'ParamStruct', start: 20, end: 31 -Def: 'ParamStruct', line: 2, def char: 11 -TypeDef: 'ParamStruct', line: 2, char: 11 +Def: 'ParamStruct', line: 2, def char: 18 +TypeDef: 'ParamStruct', line: 2, char: 18 On Hover: -struct Symbols::M3::ParamStruct { +public struct Symbols::M3::ParamStruct { some_field: T } -- test 11 ------------------- use line: 24, use_ndx: 2 Use: 'T', start: 32, end: 33 -Def: 'T', line: 22, def char: 30 +Def: 'T', line: 22, def char: 37 TypeDef: no info On Hover: T @@ -552,18 +561,18 @@ let tmp: u64 -- test 4 ------------------- use line: 21, use_ndx: 0 Use: 'tmp', start: 15, end: 18 -Def: 'tmp', line: 18, def char: 12 +Def: 'tmp', line: 18, def char: 16 TypeDef: no info On Hover: -let tmp: u64 +let mut tmp: u64 -- test 5 ------------------- use line: 24, use_ndx: 1 Use: 'tmp', start: 26, end: 29 -Def: 'tmp', line: 18, def char: 12 +Def: 'tmp', line: 18, def char: 16 TypeDef: no info On Hover: -let tmp: u64 +let mut tmp: u64 -- test 6 ------------------- use line: 25, use_ndx: 1 @@ -576,10 +585,10 @@ let tmp: u64 -- test 7 ------------------- use line: 27, use_ndx: 0 Use: 'tmp', start: 12, end: 15 -Def: 'tmp', line: 18, def char: 12 +Def: 'tmp', line: 18, def char: 16 TypeDef: no info On Hover: -let tmp: u64 +let mut tmp: u64 -- test 8 ------------------- use line: 41, use_ndx: 1 @@ -592,10 +601,10 @@ let tmp: u64 -- test 9 ------------------- use line: 44, use_ndx: 0 Use: 'tmp', start: 16, end: 19 -Def: 'tmp', line: 34, def char: 12 +Def: 'tmp', line: 34, def char: 16 TypeDef: no info On Hover: -let tmp: u64 +let mut tmp: u64 -- test 10 ------------------- use line: 56, use_ndx: 0 @@ -605,3 +614,91 @@ TypeDef: no info On Hover: const Symbols::M5::SOME_CONST: u64 = 7 +-- test 11 ------------------- +use line: 58, use_ndx: 0 +Use: 'long_param_list', start: 15, end: 30 +Def: 'long_param_list', line: 57, def char: 15 +TypeDef: no info +On Hover: +public fun Symbols::M5::long_param_list( + foo: u64, + bar: u64, + baz: u64, + qux: u64 +) + +-- test 12 ------------------- +use line: 60, use_ndx: 0 +Use: 'short_type_param_list', start: 15, end: 36 +Def: 'short_type_param_list', line: 59, def char: 15 +TypeDef: no info +On Hover: +public fun Symbols::M5::short_type_param_list() + +-- test 13 ------------------- +use line: 62, use_ndx: 0 +Use: 'long_type_param_list', start: 15, end: 35 +Def: 'long_type_param_list', line: 61, def char: 15 +TypeDef: no info +On Hover: +public fun Symbols::M5::long_type_param_list< + TYPE1, + TYPE2, + TYPE3 +>() + +-- test 14 ------------------- +use line: 64, use_ndx: 0 +Use: 'combined_short_type_param_list', start: 15, end: 45 +Def: 'combined_short_type_param_list', line: 63, def char: 15 +TypeDef: no info +On Hover: +public fun Symbols::M5::combined_short_type_param_list( + foo: u64, + bar: u64, + baz: u64, + qux: u64 +) + +-- test 15 ------------------- +use line: 68, use_ndx: 0 +Use: 'combined_long_type_param_list', start: 15, end: 44 +Def: 'combined_long_type_param_list', line: 67, def char: 15 +TypeDef: no info +On Hover: +public fun Symbols::M5::combined_long_type_param_list< + TYPE1, + TYPE2, + TYPE3 +>( + foo: u64, + bar: u64, + baz: u64, + qux: u64 +) + +-- test 16 ------------------- +use line: 75, use_ndx: 2 +Use: 'extract', start: 37, end: 44 +Def: 'extract', line: 81, def char: 15 +TypeDef: no info +On Hover: +public fun option::extract( + t: &mut Option +): Element + + Convert a `some` option to a `none` by removing and returning the value stored inside `t` + Aborts if `t` does not hold a value + +-- test 17 ------------------- +use line: 78, use_ndx: 1 +Use: 'singleton', start: 21, end: 30 +Def: 'singleton', line: 65, def char: 15 +TypeDef: no info +On Hover: +public fun vector::singleton( + e: Element +): vector + + Return an vector of size one containing element `e`. + diff --git a/external-crates/move/crates/move-analyzer/tests/symbols.ide b/external-crates/move/crates/move-analyzer/tests/symbols.ide index bce3e5c8683..7bf47ee1ef1 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols.ide +++ b/external-crates/move/crates/move-analyzer/tests/symbols.ide @@ -295,6 +295,34 @@ { "use_line": 56, "use_ndx": 0 + }, + { + "use_line": 58, + "use_ndx": 0 + }, + { + "use_line": 60, + "use_ndx": 0 + }, + { + "use_line": 62, + "use_ndx": 0 + }, + { + "use_line": 64, + "use_ndx": 0 + }, + { + "use_line": 68, + "use_ndx": 0 + }, + { + "use_line": 75, + "use_ndx": 2 + }, + { + "use_line": 78, + "use_ndx": 1 } ] } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/Move.toml b/external-crates/move/crates/move-analyzer/tests/symbols/Move.toml index 858e952648a..98589032fe0 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/Move.toml +++ b/external-crates/move/crates/move-analyzer/tests/symbols/Move.toml @@ -1,6 +1,6 @@ [package] name = "Symbols" -edition = "legacy" +edition = "2024.alpha" [dependencies] MoveStdlib = { local = "../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M1.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M1.move index b1cd4139af6..8e72efa7839 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M1.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M1.move @@ -1,6 +1,6 @@ module Symbols::M1 { - struct SomeStruct has key, drop, store { + public struct SomeStruct has drop, store { some_field: u64, } @@ -52,8 +52,8 @@ module Symbols::M1 { value } - fun mut(): u64 { - let tmp = 7; + fun mutable(): u64 { + let mut tmp = 7; let r = &mut tmp; *r = SOME_CONST; tmp @@ -85,7 +85,7 @@ module Symbols::M1 { *tmp } - struct OuterStruct has key, drop { + public struct OuterStruct has drop { some_struct: SomeStruct, } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M2.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M2.move index ad95754648c..d674772c265 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M2.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M2.move @@ -1,6 +1,6 @@ module Symbols::M2 { - struct SomeOtherStruct has drop { + public struct SomeOtherStruct has drop { some_field: u64, } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M3.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M3.move index db264354600..85125136a04 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M3.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M3.move @@ -1,6 +1,6 @@ module Symbols::M3 { - struct ParamStruct { + public struct ParamStruct { some_field: T, } @@ -20,7 +20,7 @@ module Symbols::M3 { param } - struct AnotherParamStruct { + public struct AnotherParamStruct { some_field: ParamStruct, } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M4.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M4.move index de30eea4afd..abacd0215ed 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M4.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M4.move @@ -16,10 +16,10 @@ module Symbols::M4 { fun while_loop(): u64 { - let tmp = 7; + let mut tmp = 7; while (tmp > 0) { - let tmp2 = 1; + let mut tmp2 = 1; { let tmp = tmp; tmp2 = tmp - tmp2; @@ -32,10 +32,10 @@ module Symbols::M4 { fun loop_loop(): u64 { - let tmp = 7; + let mut tmp = 7; loop { - let tmp2 = 1; + let mut tmp2 = 1; { let tmp = tmp; tmp2 = tmp - tmp2; @@ -55,4 +55,27 @@ module Symbols::M5 { const SOME_CONST: u64 = 7; + public fun long_param_list(foo: u64, bar: u64, baz: u64, qux: u64) {} + + public fun short_type_param_list() {} + + public fun long_type_param_list() {} + + public fun combined_short_type_param_list( + foo: u64, bar: u64, baz: u64, qux: u64 + ) {} + + public fun combined_long_type_param_list( + foo: u64, bar: u64, baz: u64, qux: u64 + ) {} + + public fun stripped_types(mut opt: std::option::Option): vector { + // hovering over `extract` should strip `std::option` from parameter type + // `std` from the (qualified) function name + let elem: u64 = std::option::extract(&mut opt); + // hovering over `singleton` should strip `std` from the (qualified) + // function name + std::vector::singleton(elem) + } + } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M6.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M6.move index 1b60cf1a897..0dd75702da8 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M6.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M6.move @@ -2,7 +2,7 @@ module Symbols::M6 { /// This is a documented struct /// With a multi-line docstring - struct DocumentedStruct has key, drop, store { + public struct DocumentedStruct has drop, store { /// A documented field documented_field: u64, } @@ -45,4 +45,47 @@ module Symbols::M6 { param } + /// A documented function with code block + /// (should preserve indentation in the code block) + /// + /// ```rust + /// fun foo() { + /// 42 + /// } + /// ``` + fun code_block_doc_slash() {} + + /** + A documented function with code block + (should preserve indentation in the code block) + + ```rust + fun foo() { + 42 + } + ``` + */ + fun code_block_doc_star() {} + + /** + Misformatted docstring to have fewer whitespace in the body than + at the ending marker. + + + Beginning of this string should not disappear. + +Beginning of this string should not disappear either. + + */ + fun misformatted_docstring() {} + + + /// Docstring before attributes + #[test_only] + fun attributes_after_docstring() {} + + #[test_only] + /// Docstring after attributes + fun attributes_before_docstring() {} + } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M7.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M7.move index b4165da1012..2eba2d7eaba 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M7.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M7.move @@ -1,7 +1,7 @@ module Symbols::M7 { /// Documented struct in another module - struct OtherDocStruct has drop { + public struct OtherDocStruct has drop { /// Documented field in another module some_field: u64, } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M8.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M8.move index 49b1aefebf1..b07af0f3626 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M8.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M8.move @@ -29,4 +29,12 @@ module Symbols::M8 { const EQUAL: bool = 1 == 1; const ANOTHER_USE_CONST: bool = Symbols::M8::EQUAL == false; + + #[error] + const ERROR_CONST: u64 = 42; + + public fun clever_assert() { + assert!(ERROR_CONST == 42, ERROR_CONST); + } + } diff --git a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M9.move b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M9.move index 39ee5c5c957..680f22f18e1 100644 --- a/external-crates/move/crates/move-analyzer/tests/symbols/sources/M9.move +++ b/external-crates/move/crates/move-analyzer/tests/symbols/sources/M9.move @@ -12,7 +12,7 @@ module Symbols::M9 { const SOME_CONST: u64 = 42; - struct SomeStruct has drop, store { + public struct SomeStruct has drop, store { some_field: u64, } diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/.eslintrc.json b/external-crates/move/crates/move-analyzer/trace-adapter/.eslintrc.json new file mode 100644 index 00000000000..9156c7ead3d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/naming-convention": [ + "warn", + { + "selector": "import", + "format": [ + "camelCase", + "PascalCase" + ] + } + ], + "@typescript-eslint/semi": "warn", + "curly": "warn", + "eqeqeq": "warn", + "no-throw-literal": "warn", + "semi": "off" + }, + "ignorePatterns": [ + "out", + "dist", + "**/*.d.ts" + ] +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/.mocharc.yaml b/external-crates/move/crates/move-analyzer/trace-adapter/.mocharc.yaml new file mode 100644 index 00000000000..c1cc3443233 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/.mocharc.yaml @@ -0,0 +1,3 @@ +require: "./tests/run_spec.js" +spec: + - "tests/**/*.spec.js" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/.vscodeignore b/external-crates/move/crates/move-analyzer/trace-adapter/.vscodeignore new file mode 100644 index 00000000000..72aa0fe2e73 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/.vscodeignore @@ -0,0 +1,11 @@ +.vscode/** +.vscode-test/** +src/** +.gitignore +.yarnrc +vsc-extension-quickstart.md +**/tsconfig.json +**/.eslintrc.json +**/*.map +**/*.ts +**/.vscode-test.* diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/LICENSE b/external-crates/move/crates/move-analyzer/trace-adapter/LICENSE new file mode 100644 index 00000000000..7eb403e0798 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/LICENSE @@ -0,0 +1,230 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------------------------- + +Portions of the code in this project are derived from the vscode-mock-debug sample +(https://github.com/microsoft/vscode-mock-debug/) under the following license. + +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/README.md b/external-crates/move/crates/move-analyzer/trace-adapter/README.md new file mode 100644 index 00000000000..035ad6c3805 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/README.md @@ -0,0 +1,11 @@ +# Move Trace Adapter + +Implements [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) (DAP) to visualize Move VM traces using a familiar debugging interface. It is a self-contained package in that rather than providing just the adapter that needs to connect to an actual debugger, it implements both the "adapter" part (responsible for communicating with an IDE that can understand DAP) and the "visualizer" part (responsible for analyzing traces and maintaining a runtime to maintain the visualizer/debugger state). + +# Features + +The feature set currently includes (new features upcoming!): + +- forward "step" action: step to next expression and into a regular Move function call +- "step out" action: step out of the current function call into the outer one +- "next" action: step over a function call (instead of steppig into it) diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/package-lock.json b/external-crates/move/crates/move-analyzer/trace-adapter/package-lock.json new file mode 100644 index 00000000000..d5d8cc68621 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/package-lock.json @@ -0,0 +1,2225 @@ +{ + "name": "move-trace-adapter", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "move-trace-adapter", + "version": "0.0.1", + "devDependencies": { + "@types/node": "20.x", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.11.0", + "@vscode/debugadapter": "^1.56.0", + "@vscode/debugadapter-testsupport": "^1.56.0", + "@vscode/debugprotocol": "1.66.0", + "eslint": "^8.57.0", + "line-diff": "^2.1.1", + "mocha": "10.2.0", + "toml": "^3.0.0", + "typescript": "^5.4.5" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/node": { + "version": "20.14.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", + "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vscode/debugadapter": { + "version": "1.66.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter/-/debugadapter-1.66.0.tgz", + "integrity": "sha512-U/m5l6igHtQ8rSMSKW9oWeco9ySPqGYjqW9NECGPGWZ/xnoYicpqUoXhGx3xUNsafrinzWvUWrSUL/Cdgj2V+w==", + "dev": true, + "dependencies": { + "@vscode/debugprotocol": "1.66.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugadapter-testsupport": { + "version": "1.66.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter-testsupport/-/debugadapter-testsupport-1.66.0.tgz", + "integrity": "sha512-MxXBv4wwPDml+0R3aU3d8lbH3fyRktEyIX4xDv5sArUrp1ONpN1f5vakQYfyKlRlySgu0O9NLnA+3Ylh90/RVw==", + "dev": true, + "dependencies": { + "@vscode/debugprotocol": "1.66.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugprotocol": { + "version": "1.66.0", + "resolved": "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.66.0.tgz", + "integrity": "sha512-VGcRBLNL8QwHzwerSWOb60fy1FO7bdseZv6OkTS4opoP3xeyDX58i4/wAwakL2Y4P9NafN4VGrvlXSWIratmWA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levdist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/levdist/-/levdist-1.0.0.tgz", + "integrity": "sha512-YguwC2spb0pqpJM3a5OsBhih/GG2ZHoaSHnmBqhEI7997a36buhqcRTegEjozHxyxByIwLpZHZTVYMThq+Zd3g==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/line-diff": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/line-diff/-/line-diff-2.1.1.tgz", + "integrity": "sha512-vswdynAI5AMPJacOo2o+JJ4caDJbnY2NEqms4MhMW0NJbjh3skP/brpVTAgBxrg55NRZ2Vtw88ef18hnagIpYQ==", + "dev": true, + "dependencies": { + "levdist": "^1.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "dev": true + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/package.json b/external-crates/move/crates/move-analyzer/trace-adapter/package.json new file mode 100644 index 00000000000..f80b31d4e67 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/package.json @@ -0,0 +1,25 @@ +{ + "name": "move-trace-adapter", + "displayName": "move-trace-adapter", + "description": "A Debug Adapter Protocol implementation for visualizing Move VM traces", + "version": "0.0.1", + "main": "./out/server.js", + "scripts": { + "compile": "tsc -p ./", + "lint": "eslint src --ext ts", + "test": "npm run compile && mocha --config ./.mocharc.yaml" + }, + "devDependencies": { + "@types/node": "20.x", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.11.0", + "eslint": "^8.57.0", + "line-diff": "^2.1.1", + "mocha": "10.2.0", + "typescript": "^5.4.5", + "@vscode/debugadapter": "^1.56.0", + "@vscode/debugadapter-testsupport": "^1.56.0", + "@vscode/debugprotocol": "1.66.0", + "toml": "^3.0.0" + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/src/adapter.ts b/external-crates/move/crates/move-analyzer/trace-adapter/src/adapter.ts new file mode 100644 index 00000000000..093b0287207 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/src/adapter.ts @@ -0,0 +1,536 @@ +import { + Breakpoint, + Handles, + Logger, + logger, + LoggingDebugSession, + InitializedEvent, + TerminatedEvent, + StoppedEvent, + Thread, + Scope, + StackFrame, + Source +} from '@vscode/debugadapter'; +import { DebugProtocol } from '@vscode/debugprotocol'; +import * as path from 'path'; +import { + Runtime, + RuntimeEvents, + RuntimeValueType, + IRuntimeVariableScope, + CompoundType, + IRuntimeRefValue, + ExecutionResult +} from './runtime'; + + +const enum LogLevel { + Log = 'log', + Verbose = 'verbose', + None = 'none' +} + +/** + * Customized stack trace response that includes additional data. + */ +interface CustomizedStackTraceResponse extends DebugProtocol.StackTraceResponse { + body: { + stackFrames: StackFrame[]; + totalFrames?: number; + optimized_lines: number[]; + }; +} + +/** + * Converts a log level string to a Logger.LogLevel. + * + * @param level log level as string + * @returns log level as Logger.LogLevel + */ +function convertLoggerLogLevel(level: string): Logger.LogLevel { + switch (level) { + case LogLevel.Log: + return Logger.LogLevel.Log; + case LogLevel.Verbose: + return Logger.LogLevel.Verbose; + default: + return Logger.LogLevel.Stop; + } +} + +/** + * This interface describes the move-debug specific launch attributes + * (which are not part of the Debug Adapter Protocol). + * The schema for these attributes lives in the package.json of the move-debug extension. + * The interface should always match this schema. + */ +interface ILaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { + /** An absolute path to the Move source file whose traces are to be viewed. */ + source: string; + /** Trace selected for viewing. */ + traceInfo: string; + /** Automatically stop target after launch. If not specified, target does not stop. */ + stopOnEntry?: boolean; + /** enable logging the Debug Adapter Protocol */ + logLevel?: string; +} + +export class MoveDebugSession extends LoggingDebugSession { + + /** + * We only even have one thread so we can hardcode its ID. + */ + private static THREAD_ID = 1; + + /** + * DAP-independent runtime maintaining state during + * trace viewing session. + */ + private runtime: Runtime; + + /** + * Handles to create variable scopes and compound variable values. + */ + private variableHandles: Handles; + + public constructor() { + super(); + this.setDebuggerLinesStartAt1(false); + this.setDebuggerColumnsStartAt1(false); + this.runtime = new Runtime(); + this.variableHandles = new Handles(); + + // setup event handlers + + this.runtime.on(RuntimeEvents.stopOnStep, () => { + this.sendEvent(new StoppedEvent('step', MoveDebugSession.THREAD_ID)); + }); + this.runtime.on(RuntimeEvents.stopOnLineBreakpoint, () => { + this.sendEvent(new StoppedEvent('breakpoint', MoveDebugSession.THREAD_ID)); + }); + this.runtime.on(RuntimeEvents.stopOnException, (msg) => { + this.sendEvent(new StoppedEvent('exception', MoveDebugSession.THREAD_ID, msg)); + }); + this.runtime.on(RuntimeEvents.end, () => { + this.sendEvent(new TerminatedEvent()); + }); + + } + + protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void { + + // build and return the capabilities of this debug adapter (enable as needed) + response.body = response.body || {}; + + // the adapter implements the configurationDone request + response.body.supportsConfigurationDoneRequest = false; + + // the adapter supports conditional breakpoints + response.body.supportsConditionalBreakpoints = false; + + // the adapter supports breakpoints that break execution after a specified number of hits + response.body.supportsHitConditionalBreakpoints = false; + + // make VS Code use 'evaluate' when hovering over source + response.body.supportsEvaluateForHovers = false; + + // make VS Code show a 'step back' button + response.body.supportsStepBack = false; + + // make VS Code support data breakpoints + response.body.supportsDataBreakpoints = false; + + // make VS Code support completion in REPL + response.body.supportsCompletionsRequest = false; + response.body.completionTriggerCharacters = []; + + // make VS Code send cancel request + response.body.supportsCancelRequest = false; + + // make VS Code send the breakpointLocations request + response.body.supportsBreakpointLocationsRequest = false; + + // make VS Code provide "Step in Target" functionality + response.body.supportsStepInTargetsRequest = false; + + // the adapter defines two exceptions filters, one with support for conditions. + response.body.supportsExceptionFilterOptions = false; + response.body.exceptionBreakpointFilters = []; + + // make VS Code send exceptionInfo request + response.body.supportsExceptionInfoRequest = false; + + // make VS Code send setVariable request + response.body.supportsSetVariable = false; + + // make VS Code send setExpression request + response.body.supportsSetExpression = false; + + // make VS Code send disassemble request + response.body.supportsDisassembleRequest = false; + response.body.supportsSteppingGranularity = false; + response.body.supportsInstructionBreakpoints = false; + + // make VS Code able to read and write variable memory + response.body.supportsReadMemoryRequest = false; + response.body.supportsWriteMemoryRequest = false; + + response.body.supportSuspendDebuggee = false; + response.body.supportTerminateDebuggee = false; + response.body.supportsFunctionBreakpoints = false; + response.body.supportsDelayedStackTraceLoading = false; + + this.sendResponse(response); + this.sendEvent(new InitializedEvent()); + } + + protected async launchRequest( + response: DebugProtocol.LaunchResponse, + args: ILaunchRequestArguments + ): Promise { + logger.setup(convertLoggerLogLevel(args.logLevel ?? LogLevel.None), false); + logger.log(`Launching trace viewer for file: ${args.source} and trace: ${args.traceInfo}`); + + try { + await this.runtime.start(args.source, args.traceInfo, args.stopOnEntry || false); + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + this.sendResponse(response); + this.sendEvent(new StoppedEvent('entry', MoveDebugSession.THREAD_ID)); + } + + protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { + response.body = { + threads: [ + new Thread(MoveDebugSession.THREAD_ID, 'Main Thread') + ] + }; + this.sendResponse(response); + } + + protected stackTraceRequest( + response: CustomizedStackTraceResponse, + _args: DebugProtocol.StackTraceArguments + ): void { + try { + const runtimeStack = this.runtime.stack(); + const stack_height = runtimeStack.frames.length; + response.body = { + stackFrames: runtimeStack.frames.map(frame => { + const fileName = path.basename(frame.file); + return new StackFrame(frame.id, frame.name, new Source(fileName, frame.file), frame.line); + }).reverse(), + totalFrames: stack_height, + optimized_lines: stack_height > 0 + ? runtimeStack.frames[stack_height - 1].optimizedLines + : [] + }; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + this.sendResponse(response); + } + + /** + * Gets the scopes for a given frame. + * + * @param frameID identifier of the frame scopes are requested for. + * @returns an array of scopes. + * @throws Error with a descriptive error message if scopes cannot be retrieved. + */ + private getScopes(frameID: number): DebugProtocol.Scope[] { + const runtimeStack = this.runtime.stack(); + const frame = runtimeStack.frames.find(frame => frame.id === frameID); + if (!frame) { + throw new Error(`No frame found for id: ${frameID} when getting scopes`); + } + const scopes: DebugProtocol.Scope[] = []; + if (frame.locals.length > 0) { + for (let i = frame.locals.length - 1; i > 0; i--) { + const shadowedScopeReference = this.variableHandles.create({ locals: frame.locals[i] }); + const shadowedScope = new Scope(`shadowed(${i}): ${frame.name}`, shadowedScopeReference, false); + scopes.push(shadowedScope); + } + } + // don't have to check if scope 0 exists as it's created whenever a new frame is created + // and it's never disposed of + const localScopeReference = this.variableHandles.create({ locals: frame.locals[0] }); + const localScope = new Scope(`locals: ${frame.name}`, localScopeReference, false); + scopes.push(localScope); + + return scopes; + } + + protected scopesRequest( + response: DebugProtocol.ScopesResponse, + args: DebugProtocol.ScopesArguments + ): void { + try { + const scopes = this.getScopes(args.frameId); + response.body = { + scopes + }; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + + this.sendResponse(response); + } + + /** + * Converts a runtime reference value to a DAP variable. + * + * @param value reference value. + * @param name name of variable containing the reference value. + * @param type optional type of the variable containing the reference value. + * @returns a DAP variable. + * @throws Error with a descriptive error message if conversion fails. + */ + private convertRefValue( + value: IRuntimeRefValue, + name: string, + type?: string + ): DebugProtocol.Variable { + const frameID = value.loc.frameID; + const localIndex = value.loc.localIndex; + const runtimeStack = this.runtime.stack(); + const frame = runtimeStack.frames.find(frame => frame.id === frameID); + if (!frame) { + throw new Error('No frame found for id ' + + frameID + + ' when converting ref value for local index ' + + localIndex); + } + // a local will be in one of the scopes at a position corresponding to its local index + let local = undefined; + for (const scope of frame.locals) { + local = scope[localIndex]; + if (local) { + break; + } + } + if (!local) { + throw new Error('No local found for index ' + + localIndex + + ' when converting ref value for frame id ' + + frameID); + } + + return this.convertRuntimeValue(local.value, name, type); + } + + /** + * Converts a runtime value to a DAP variable. + * + * @param value variable value + * @param name variable name + * @param type optional variable type + * @returns a DAP variable. + */ + private convertRuntimeValue( + value: RuntimeValueType, + name: string, + type?: string + ): DebugProtocol.Variable { + if (typeof value === 'string') { + return { + name, + type, + value, + variablesReference: 0 + }; + } else if (Array.isArray(value)) { + const compoundValueReference = this.variableHandles.create(value); + return { + name, + type, + value: '(' + value.length + ')[...]', + variablesReference: compoundValueReference + }; + } else if ('fields' in value) { + const compoundValueReference = this.variableHandles.create(value); + // use type if available as it will have information about whether + // it's a reference or not (e.g., `&mut 0x42::mod::SomeStruct`), + // as opposed to the type that come with the value + // (e.g., `0x42::mod::SomeStruct`) + const actualType = type ? type : value.type; + const accessChainParts = actualType.split('::'); + const datatypeName = accessChainParts[accessChainParts.length - 1]; + return { + name, + type: value.variantName + ? actualType + '::' + value.variantName + : actualType, + value: (value.variantName + ? datatypeName + '::' + value.variantName + : datatypeName + ) + '{...}', + variablesReference: compoundValueReference + }; + } else { + return this.convertRefValue(value, name, type); + } + } + + /** + * Converts runtime variables to DAP variables. + * + * @param runtimeScope runtime variables scope, + * @returns an array of DAP variables. + */ + private convertRuntimeVariables(runtimeScope: IRuntimeVariableScope): DebugProtocol.Variable[] { + const variables: DebugProtocol.Variable[] = []; + const runtimeVariables = runtimeScope.locals; + runtimeVariables.forEach(v => { + if (v) { + variables.push(this.convertRuntimeValue(v.value, v.name, v.type)); + } + }); + return variables; + } + + protected variablesRequest( + response: DebugProtocol.VariablesResponse, + args: DebugProtocol.VariablesArguments + ): void { + try { + const variableHandle = this.variableHandles.get(args.variablesReference); + let variables: DebugProtocol.Variable[] = []; + if (variableHandle) { + if ('locals' in variableHandle) { + // we are dealing with a scope + variables = this.convertRuntimeVariables(variableHandle); + } else { + // we are dealing with a compound value + if (Array.isArray(variableHandle)) { + for (let i = 0; i < variableHandle.length; i++) { + const v = variableHandle[i]; + variables.push(this.convertRuntimeValue(v, String(i))); + } + } else { + variableHandle.fields.forEach(([fname, fvalue]) => { + variables.push(this.convertRuntimeValue(fvalue, fname)); + }); + } + } + } + if (variables.length > 0) { + response.body = { + variables + }; + } + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + this.sendResponse(response); + } + + + protected nextRequest( + response: DebugProtocol.NextResponse, + _args: DebugProtocol.NextArguments + ): void { + let terminate = false; + try { + const executionResult = this.runtime.step(/* next */ true, /* stopAtCloseFrame */ false); + terminate = executionResult === ExecutionResult.TraceEnd; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + if (terminate) { + this.sendEvent(new TerminatedEvent()); + } + this.sendResponse(response); + } + + protected stepInRequest( + response: DebugProtocol.StepInResponse, + _args: DebugProtocol.StepInArguments + ): void { + let terminate = false; + try { + const executionResult = this.runtime.step(/* next */ false, /* stopAtCloseFrame */ false); + terminate = executionResult === ExecutionResult.TraceEnd; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + if (terminate) { + this.sendEvent(new TerminatedEvent()); + } + this.sendResponse(response); + } + + protected stepOutRequest( + response: DebugProtocol.StepOutResponse, + _args: DebugProtocol.StepOutArguments + ): void { + let terminate = false; + try { + const executionResult = this.runtime.stepOut(/* next */ false); + terminate = executionResult === ExecutionResult.TraceEnd; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + if (terminate) { + this.sendEvent(new TerminatedEvent()); + } + this.sendResponse(response); + } + + protected continueRequest( + response: DebugProtocol.ContinueResponse, + _args: DebugProtocol.ContinueArguments + ): void { + let terminate = false; + try { + const executionResult = this.runtime.continue(); + terminate = executionResult === ExecutionResult.TraceEnd; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + if (terminate) { + this.sendEvent(new TerminatedEvent()); + } + this.sendResponse(response); + } + + protected setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): void { + try { + const finalBreakpoints = []; + if (args.breakpoints && args.source.path) { + const breakpointLines = args.breakpoints.map(bp => bp.line); + const validatedBreakpoints = this.runtime.setLineBreakpoints(args.source.path, breakpointLines); + for (let i = 0; i < breakpointLines.length; i++) { + finalBreakpoints.push(new Breakpoint(validatedBreakpoints[i], breakpointLines[i])); + } + } + response.body = { + breakpoints: finalBreakpoints + }; + } catch (err) { + response.success = false; + response.message = err instanceof Error ? err.message : String(err); + } + this.sendResponse(response); + } + + + protected disconnectRequest( + response: DebugProtocol.DisconnectResponse, + _args: DebugProtocol.DisconnectArguments + ): void { + // Cleanup and terminate the debug session + this.sendEvent(new TerminatedEvent()); + this.sendResponse(response); + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/src/runtime.ts b/external-crates/move/crates/move-analyzer/trace-adapter/src/runtime.ts new file mode 100644 index 00000000000..3a88c518ee5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/src/runtime.ts @@ -0,0 +1,1003 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { EventEmitter } from 'events'; +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import * as path from 'path'; +import toml from 'toml'; +import { IFileInfo, ISourceMap, readAllSourceMaps } from './source_map_utils'; +import { + TraceEffectKind, + TraceEvent, + TraceEventKind, + TraceInstructionKind, + readTrace, +} from './trace_utils'; + +/** + * Describes the runtime variable scope (e.g., local variables + * or shadowed variables). + */ +export interface IRuntimeVariableScope { + locals: (IRuntimeVariable | undefined)[]; +} + +/** + * A compound type: + * - a vector (converted to an array of values) + * - a struct/enum (converted to an array of string/field value pairs) + */ +export type CompoundType = RuntimeValueType[] | IRuntimeCompoundValue; + +/** + * A runtime value can have any of the following types: + * - boolean, number, string (converted to string) + * - compound type (vector, struct, enum) + */ +export type RuntimeValueType = string | CompoundType | IRuntimeRefValue; + +/** + * Location of a local variable in the runtime. + */ +export interface IRuntimeVariableLoc { + frameID: number; + localIndex: number; +} + +/** + * Value of a reference in the runtime. + */ +export interface IRuntimeRefValue { + mutable: boolean; + loc: IRuntimeVariableLoc +} + +/** + * Information about a runtime compound value (struct/enum). + */ +export interface IRuntimeCompoundValue { + fields: [string, RuntimeValueType][]; + type: string; + variantName?: string; + variantTag?: number; +} + +/** + * Describes a runtime local variable. + */ +interface IRuntimeVariable { + name: string; + value: RuntimeValueType; + type: string; +} + +/** + * Describes a stack frame in the runtime and its current state + * during trace viewing session. + */ +interface IRuntimeStackFrame { + /** + * Frame identifier. + */ + id: number; + /** + * Name of the function in this frame. + */ + name: string; + /** + * Path to the file containing currently executing instruction. + */ + file: string; + /** + * File hash of the file containing currently executing instruction. + */ + fileHash: string; + /** + * Current line in the file corresponding to currently viewed instruction. + */ + line: number; // 1-based + /** + * Local variable types by variable frame index. + */ + localsTypes: string[]; + /** + * Local variable names by variable frame index. + */ + localsNames: string[]; + /** + * Local variables per scope (local scope at 0 and then following block scopes), + * indexed by variable frame index. + */ + locals: (IRuntimeVariable | undefined)[][]; + /** + * Line of the last call instruction that was processed in this frame. + * It's needed to make sure that step/next into/over call works correctly. + */ + lastCallInstructionLine: number | undefined; + /** + * Lines that are not present in the source map. + */ + optimizedLines: number[] +} + +/** + * Describes the runtime stack during trace viewing session + * (oldest frame is at the bottom of the stack at index 0). + */ +export interface IRuntimeStack { + frames: IRuntimeStackFrame[]; +} + +/** + * Events emitted by the runtime during trace viewing session. + */ +export enum RuntimeEvents { + /** + * Stop after step/next action is performed. + */ + stopOnStep = 'stopOnStep', + + /** + * Stop after a line breakpoint is hit. + */ + stopOnLineBreakpoint = 'stopOnLineBreakpoint', + + /** + * Stop after exception has been encountered. + */ + stopOnException = 'stopOnException', + + /** + * Finish trace viewing session. + */ + end = 'end', +} +/** + * Describes result of the execution. + */ +export enum ExecutionResult { + Ok, + TraceEnd, + Exception, +} + +/** + * The runtime for viewing traces. + */ +export class Runtime extends EventEmitter { + + /** + * Trace being viewed. + */ + private trace = { + events: [] as TraceEvent[], + localLifetimeEnds: new Map(), + tracedLines: new Map>() + }; + + /** + * Index of the current trace event being processed. + */ + private eventIndex = 0; + + /** + * Current frame stack. + */ + private frameStack = { frames: [] as IRuntimeStackFrame[] }; + + /** + * Map of file hashes to file info. + */ + private filesMap = new Map(); + + /** + * Map of line breakpoints, keyed on a file path. + */ + private lineBreakpoints = new Map>(); + + /** + * Start a trace viewing session and set up the initial state of the runtime. + * + * @param source path to the Move source file whose traces are to be viewed. + * @param traceInfo trace selected for viewing. + * @throws Error with a descriptive error message if starting runtime has failed. + * + */ + public async start(source: string, traceInfo: string, stopOnEntry: boolean): Promise { + const pkgRoot = await findPkgRoot(source); + if (!pkgRoot) { + throw new Error(`Cannot find package root for file: ${source}`); + } + const manifest_path = path.join(pkgRoot, 'Move.toml'); + + // find package name from manifest file which corresponds `build` directory's subdirectory + // name containing this package's build files + const pkg_name = getPkgNameFromManifest(manifest_path); + if (!pkg_name) { + throw Error(`Cannot find package name in manifest file: ${manifest_path}`); + } + + // create file maps for all files in the `build` directory, including both package source + // files and source files for dependencies + this.hashToFileMap(path.join(pkgRoot, 'build', pkg_name, 'sources')); + // update with files from the actual "sources" directory rather than from the "build" directory + this.hashToFileMap(path.join(pkgRoot, 'sources')); + + // create source maps for all modules in the `build` directory + const sourceMapsModMap = readAllSourceMaps(path.join(pkgRoot, 'build', pkg_name, 'source_maps'), this.filesMap); + + // reconstruct trace file path from trace info + const traceFilePath = path.join(pkgRoot, 'traces', traceInfo.replace(/:/g, '_') + '.json'); + + // create a mapping from file hash to its corresponding source map + const sourceMapsHashMap = new Map; + for (const [_, sourceMap] of sourceMapsModMap) { + sourceMapsHashMap.set(sourceMap.fileHash, sourceMap); + } + + this.trace = readTrace(traceFilePath, sourceMapsModMap, sourceMapsHashMap, this.filesMap); + + // start trace viewing session with the first trace event + this.eventIndex = 0; + + // setup frame stack with the first frame + const currentEvent = this.trace.events[this.eventIndex]; + if (currentEvent.type !== TraceEventKind.OpenFrame) { + throw new Error(`First event in trace is not an OpenFrame event`); + } + const newFrame = + this.newStackFrame( + currentEvent.id, + currentEvent.name, + currentEvent.fileHash, + currentEvent.localsTypes, + currentEvent.localsNames, + currentEvent.optimizedLines + ); + this.frameStack = { + frames: [newFrame] + }; + this.step(/* next */ false, /* stopAtCloseFrame */ false); + } + + /** + * Handles "get current stack" adapter action. + * + * @returns current frame stack. + */ + public stack(): IRuntimeStack { + return this.frameStack; + } + + /** + * Handles step/next adapter action. + * + * @param next determines if it's `next` (or otherwise `step`) action. + * @param stopAtCloseFrame determines if the action should stop at `CloseFrame` event + * (rather then proceed to the following instruction). + * @returns ExecutionResult.Ok if the step action was successful, ExecutionResult.TraceEnd if we + * reached the end of the trace, and ExecutionResult.Exception if an exception was encountered. + * @throws Error with a descriptive error message if the step event cannot be handled. + */ + public step(next: boolean, stopAtCloseFrame: boolean): ExecutionResult { + this.eventIndex++; + if (this.eventIndex >= this.trace.events.length) { + this.sendEvent(RuntimeEvents.stopOnStep); + return ExecutionResult.TraceEnd; + } + let currentEvent = this.trace.events[this.eventIndex]; + if (currentEvent.type === TraceEventKind.Instruction) { + const stackHeight = this.frameStack.frames.length; + if (stackHeight <= 0) { + throw new Error('No frame on the stack when processing Instruction event on line: ' + + currentEvent.loc.line + + ' in column: ' + + currentEvent.loc.column); + } + const currentFrame = this.frameStack.frames[stackHeight - 1]; + // remember last call instruction line before it (potentially) changes + // in the `instruction` call below + const lastCallInstructionLine = currentFrame.lastCallInstructionLine; + let [sameLine, currentLine] = this.instruction(currentFrame, currentEvent); + // do not attempt to skip events on the same line if the previous event + // was a switch to/from an inlined frame - we want execution to stop before + // the first instruction of the inlined frame is processed + const prevEvent = this.trace.events[this.eventIndex - 1]; + sameLine = sameLine && + !(prevEvent.type === TraceEventKind.ReplaceInlinedFrame + || prevEvent.type === TraceEventKind.OpenFrame && prevEvent.id < 0 + || prevEvent.type === TraceEventKind.CloseFrame && prevEvent.id < 0); + if (sameLine) { + if (!next && (currentEvent.kind === TraceInstructionKind.CALL + || currentEvent.kind === TraceInstructionKind.CALL_GENERIC) + && lastCallInstructionLine === currentLine) { + // We are about to step into another call on the same line + // but we should wait for user action to do so rather than + // having debugger step into it automatically. If we don't + // the user will observe a weird effect. For example, + // consider the following code: + // ``` + // foo(); + // assert(bar() == baz()); + // ``` + // In the code above, after executing `foo()`, the user + // will move to the next line and will expect to only + // step into `bar` rather than having debugger to step + // immediately into `baz` as well. At the same time, + // if the user intended to step over functions using `next`, + // we should skip over all calls on the same line (both `bar` + // and `baz` in the example above). + // + // The following explains a bit more formally what needs + // to happen both on on `next` and `step` actions when + // call and non-call instructions are interleaved: + // + // When `step` is called: + // + // When there is only one call on the same line, we want to + // stop on the first instruction of this line, then after + // user `step` action enter the call, and then after + // exiting the call go to the instruction on the next line: + // 6: instruction + // 7: instruction // stop here + // 7: call // enter call here + // 7: instruction + // 8: instruction // stop here + // + // When there is more than one call on the same line, we + // want to stop on the first instruction of this line, + // then after user `step` action enter the call, then + // after exiting the call stop on the next call instruction + // and wait for another `step` action from the user: + // 6: instruction + // 7: instruction // stop here + // 7: call // enter call here + // 7: instruction + // 7: call // stop and then enter call here + // 7: instruction + // 8: instruction // stop here + // + // When `next` is called, things have to happen differently, + // particularly when there are multiple calls on the same line: + // 6: instruction + // 7: instruction // stop here + // 7: call + // 7: instruction + // 7: call + // 7: instruction + // 8: instruction // stop here + // + // To support this, we need to keep track of the line number when + // the last call instruction in a give frame happened, and + // also we need to make `stepOut` aware of whether it is executed + // as part of `next` (which is how `next` is implemented) or not. + this.sendEvent(RuntimeEvents.stopOnStep); + return ExecutionResult.Ok; + } else { + return this.step(next, stopAtCloseFrame); + } + } + this.sendEvent(RuntimeEvents.stopOnStep); + return ExecutionResult.Ok; + } else if (currentEvent.type === TraceEventKind.ReplaceInlinedFrame) { + let currentFrame = this.frameStack.frames.pop(); + if (!currentFrame) { + throw new Error('No frame to pop when processing `ReplaceInlinedFrame` event'); + } + currentFrame.fileHash = currentEvent.fileHash; + currentFrame.optimizedLines = currentEvent.optimizedLines; + const currentFile = this.filesMap.get(currentFrame.fileHash); + if (!currentFile) { + throw new Error('Cannot find file with hash ' + + currentFrame.fileHash + + ' when processing `ReplaceInlinedFrame` event'); + } + currentFrame.file = currentFile.path; + this.frameStack.frames.push(currentFrame); + return this.step(next, stopAtCloseFrame); + } else if (currentEvent.type === TraceEventKind.OpenFrame) { + // if function is native then the next event will be CloseFrame + if (currentEvent.isNative) { + // see if native function aborted + if (this.trace.events.length > this.eventIndex + 1) { + const nextEvent = this.trace.events[this.eventIndex + 1]; + if (nextEvent.type === TraceEventKind.Effect && + nextEvent.effect.type === TraceEffectKind.ExecutionError) { + this.sendEvent(RuntimeEvents.stopOnException, nextEvent.effect.msg); + return ExecutionResult.Exception; + } + } + // if native function executed successfully, then the next event + // should be CloseFrame + if (this.trace.events.length <= this.eventIndex + 1 || + this.trace.events[this.eventIndex + 1].type !== TraceEventKind.CloseFrame) { + throw new Error('Expected an CloseFrame event after native OpenFrame event'); + } + // skip over CloseFrame as there is no frame to pop + this.eventIndex++; + return this.step(next, stopAtCloseFrame); + } + + // create a new frame and push it onto the stack + const newFrame = + this.newStackFrame( + currentEvent.id, + currentEvent.name, + currentEvent.fileHash, + currentEvent.localsTypes, + currentEvent.localsNames, + currentEvent.optimizedLines + ); + // set values of parameters in the new frame + this.frameStack.frames.push(newFrame); + for (let i = 0; i < currentEvent.paramValues.length; i++) { + localWrite(newFrame, i, currentEvent.paramValues[i]); + } + + if (next) { + // step out of the frame right away + return this.stepOut(next); + } else { + return this.step(next, stopAtCloseFrame); + } + } else if (currentEvent.type === TraceEventKind.CloseFrame) { + if (stopAtCloseFrame) { + // don't do anything as the caller needs to inspect + // the event before proceeding + return ExecutionResult.Ok; + } else { + // pop the top frame from the stack + if (this.frameStack.frames.length <= 0) { + throw new Error('No frame to pop at CloseFrame event with ID: ' + + currentEvent.id); + } + this.frameStack.frames.pop(); + return this.step(next, stopAtCloseFrame); + } + } else if (currentEvent.type === TraceEventKind.Effect) { + const effect = currentEvent.effect; + if (effect.type === TraceEffectKind.ExecutionError) { + this.sendEvent(RuntimeEvents.stopOnException, effect.msg); + return ExecutionResult.Exception; + } + if (effect.type === TraceEffectKind.Write) { + const traceLocation = effect.loc; + const traceValue = effect.value; + const frame = this.frameStack.frames.find( + frame => frame.id === traceLocation.frameID + ); + if (!frame) { + throw new Error('Cannot find frame with ID: ' + + traceLocation.frameID + + ' when processing Write effect for local variable at index: ' + + traceLocation.localIndex); + } + localWrite(frame, traceLocation.localIndex, traceValue); + } + return this.step(next, stopAtCloseFrame); + } else { + // ignore other events + return this.step(next, stopAtCloseFrame); + } + } + + /** + * Handles "step out" adapter action. + * + * @param next determines if it's part of `next` (or otherwise `step`) action. + * @returns ExecutionResult.Ok if the step action was successful, ExecutionResult.TraceEnd if we + * reached the end of the trace, and ExecutionResult.Exception if an exception was encountered. + * @throws Error with a descriptive error message if the step out event cannot be handled. + */ + public stepOut(next: boolean): ExecutionResult { + const stackHeight = this.frameStack.frames.length; + if (stackHeight <= 1) { + // do nothing as there is no frame to step out to + this.sendEvent(RuntimeEvents.stopOnStep); + return ExecutionResult.Ok; + } + // newest frame is at the top of the stack + const currentFrame = this.frameStack.frames[stackHeight - 1]; + let currentEvent = this.trace.events[this.eventIndex]; + // skip all events until the corresponding CloseFrame event, + // pop the top frame from the stack, and proceed to the next event + while (true) { + // when calling `step` in the loop below, we need to avoid + // skipping over calls next-style otherwise we can miss seeing + // the actual close frame event that we are looking for + // and have the loop execute too far + const executionResult = this.step(/* next */ false, /* stopAtCloseFrame */ true); + if (executionResult === ExecutionResult.Exception) { + return executionResult; + } + if (executionResult === ExecutionResult.TraceEnd) { + throw new Error('Cannot find corresponding CloseFrame event for function: ' + + currentFrame.name); + } + currentEvent = this.trace.events[this.eventIndex]; + if (currentEvent.type === TraceEventKind.CloseFrame) { + const currentFrameID = currentFrame.id; + // `step` call finished at the CloseFrame event + // but did not process it so we need pop the frame here + this.frameStack.frames.pop(); + if (currentEvent.id === currentFrameID) { + break; + } + } + } + return this.step(next, /* stopAtCloseFrame */ false); + } + + /** + * Handles "continue" adapter action. + * @returns ExecutionResult.Ok if the step action was successful, ExecutionResult.TraceEnd if we + * reached the end of the trace, and ExecutionResult.Exception if an exception was encountered. + * @throws Error with a descriptive error message if the continue event cannot be handled. + */ + public continue(): ExecutionResult { + while (true) { + const executionResult = this.step(/* next */ false, /* stopAtCloseFrame */ false); + if (executionResult === ExecutionResult.TraceEnd || + executionResult === ExecutionResult.Exception) { + return executionResult; + } + let currentEvent = this.trace.events[this.eventIndex]; + if (currentEvent.type === TraceEventKind.Instruction) { + const stackHeight = this.frameStack.frames.length; + if (stackHeight <= 0) { + throw new Error('No frame on the stack when processing Instruction event on line: ' + + currentEvent.loc.line + + ' in column: ' + + currentEvent.loc.column); + } + const currentFrame = this.frameStack.frames[stackHeight - 1]; + const breakpoints = this.lineBreakpoints.get(currentFrame.file); + if (!breakpoints) { + continue; + } + if (breakpoints.has(currentEvent.loc.line)) { + this.sendEvent(RuntimeEvents.stopOnLineBreakpoint); + return ExecutionResult.Ok; + } + } + } + } + + /** + * Sets line breakpoints for a file (resetting any existing ones). + * + * @param path file path. + * @param lines breakpoints lines. + * @returns array of booleans indicating if a breakpoint was set on a line. + * @throws Error with a descriptive error message if breakpoints cannot be set. + */ + public setLineBreakpoints(path: string, lines: number[]): boolean[] { + const breakpoints = new Set(); + const tracedLines = this.trace.tracedLines.get(path); + // Set all breakpoints to invalid and validate the correct ones in the loop, + // otherwise let them all be invalid if there are no traced lines. + // Valid breakpoints are those that are on lines that have at least + // one instruction in the trace on them. + const validated = lines.map(() => false); + if (tracedLines) { + for (let i = 0; i < lines.length; i++) { + if (tracedLines.has(lines[i])) { + validated[i] = true; + breakpoints.add(lines[i]); + } + } + } + this.lineBreakpoints.set(path, breakpoints); + return validated; + } + + /** + * Handles `Instruction` trace event which represents instruction in the current stack frame. + * + * @param instructionEvent `Instruction` trace event. + * @returns `true` if the instruction is on the same line as the one in the current frame, + * `false` otherwise (so that instructions on the same line can be skipped). + * @throws Error with a descriptive error message if instruction event cannot be handled. + */ + private instruction( + currentFrame: IRuntimeStackFrame, + instructionEvent: Extract + ): [boolean, number] { + // if current instruction ends lifetime of a local variable, mark this in the + // local variable array + const frameLocalLifetimeEnds = this.trace.localLifetimeEnds.get(currentFrame.id); + if (frameLocalLifetimeEnds) { + const localsLength = currentFrame.locals.length; + for (let i = 0; i < localsLength; i++) { + for (let j = 0; j < currentFrame.locals[i].length; j++) { + if (frameLocalLifetimeEnds[j] === instructionEvent.pc) { + currentFrame.locals[i][j] = undefined; + } + } + } + // trim shadowed scopes that have no live variables in them + for (let i = localsLength - 1; i > 0; i--) { + const liveVar = currentFrame.locals[i].find(runtimeVar => { + return runtimeVar !== undefined; + }); + if (!liveVar) { + currentFrame.locals.pop(); + } + } + } + const loc = instructionEvent.loc; + if (instructionEvent.kind === TraceInstructionKind.CALL || + instructionEvent.kind === TraceInstructionKind.CALL_GENERIC) { + currentFrame.lastCallInstructionLine = loc.line; + } + + if (loc.line === currentFrame.line) { + // so that instructions on the same line can be bypassed + return [true, loc.line]; + } else { + currentFrame.line = loc.line; + return [false, loc.line]; + } + } + + + /** + * Creates a new runtime stack frame based on info from the `OpenFrame` trace event. + * + * @param frameID frame identifier from the trace event. + * @param funName function name. + * @param modInfo information about module containing the function. + * @param localsTypes types of local variables in the frame. + * @param localsNames names of local variables in the frame. + * @param optimizedLines lines that are not present in the source map. + * @returns new frame. + * @throws Error with a descriptive error message if frame cannot be constructed. + */ + private newStackFrame( + frameID: number, + funName: string, + fileHash: string, + localsTypes: string[], + localsNames: string[], + optimizedLines: number[] + ): IRuntimeStackFrame { + const currentFile = this.filesMap.get(fileHash); + + if (!currentFile) { + throw new Error(`Cannot find file with hash: ${fileHash}`); + } + + let locals = []; + // create first scope for local variables + locals[0] = []; + const stackFrame: IRuntimeStackFrame = { + id: frameID, + name: funName, + file: currentFile.path, + fileHash, + line: 0, // line will be updated when next event (Instruction) is processed + localsTypes, + localsNames, + locals, + lastCallInstructionLine: undefined, + optimizedLines + }; + + if (this.trace.events.length <= this.eventIndex + 1 || + (this.trace.events[this.eventIndex + 1].type !== TraceEventKind.Instruction && + this.trace.events[this.eventIndex + 1].type !== TraceEventKind.OpenFrame) + ) { + throw new Error('Expected an Instruction or OpenFrame event after OpenFrame event'); + } + return stackFrame; + } + + /** + * Emits an event to the adapter. + * + * @param event string representing the event. + * @param args optional arguments to be passed with the event. + */ + private sendEvent(event: string, ...args: any[]): void { + setTimeout(() => { + this.emit(event, ...args); + }, 0); + } + + /** + * Creates a map from a file hash to file information for all Move source files in a directory. + * + * @param directory path to the directory containing Move source files. + * @param filesMap map to update with file information. + */ + private hashToFileMap(directory: string): void { + const processDirectory = (dir: string) => { + const files = fs.readdirSync(dir); + for (const f of files) { + const filePath = path.join(dir, f); + const stats = fs.statSync(filePath); + if (stats.isDirectory()) { + processDirectory(filePath); + } else if (path.extname(f) === '.move') { + const content = fs.readFileSync(filePath, 'utf8'); + const numFileHash = computeFileHash(content); + const lines = content.split('\n'); + const fileInfo = { path: filePath, content, lines }; + const fileHash = Buffer.from(numFileHash).toString('base64'); + this.filesMap.set(fileHash, fileInfo); + } + } + }; + + processDirectory(directory); + } + + // + // Utility functions for testing and debugging. + // + + /** + * Whitespace used for indentation in the string representation of the runtime. + */ + private singleTab = ' '; + + /** + * Returns a string representing the current state of the runtime. + * + * @returns string representation of the runtime. + */ + public toString(): string { + let res = 'current frame stack:\n'; + for (const frame of this.frameStack.frames) { + const fileName = path.basename(frame.file); + res += this.singleTab + + 'function: ' + + frame.name + + ' (' + + fileName + + ':' + + frame.line + + ')\n'; + for (let i = 0; i < frame.locals.length; i++) { + res += this.singleTab + this.singleTab + 'scope ' + i + ' :\n'; + for (let j = 0; j < frame.locals[i].length; j++) { + const local = frame.locals[i][j]; + if (local) { + res += this.varToString(this.singleTab + + this.singleTab + + this.singleTab, local) + '\n'; + } + } + } + } + if (this.lineBreakpoints && this.lineBreakpoints.size > 0) { + res += 'line breakpoints\n'; + for (const [file, breakpoints] of this.lineBreakpoints) { + res += this.singleTab + path.basename(file) + '\n'; + for (const line of breakpoints) { + res += this.singleTab + this.singleTab + line + '\n'; + } + } + } + return res; + } + /** + * Returns a string representation of a runtime variable. + * + * @param variable runtime variable. + * @returns string representation of the variable. + */ + private varToString(tabs: string, variable: IRuntimeVariable): string { + return this.valueToString(tabs, variable.value, variable.name, variable.type); + } + + /** + * Returns a string representation of a runtime compound value. + * + * @param compoundValue runtime compound value. + * @returns string representation of the compound value. + */ + private compoundValueToString(tabs: string, compoundValue: IRuntimeCompoundValue): string { + const type = compoundValue.variantName + ? compoundValue.type + '::' + compoundValue.variantName + : compoundValue.type; + let res = '(' + type + ') {\n'; + for (const [name, value] of compoundValue.fields) { + res += this.valueToString(tabs + this.singleTab, value, name); + } + res += tabs + '}\n'; + return res; + } + + /** + * Returns a string representation of a runtime reference value. + * + * @param refValue runtime reference value. + * @param name name of the variable containing reference value. + * @param type optional type of the variable containing reference value. + * @returns string representation of the reference value. + */ + private refValueToString( + tabs: string, + refValue: IRuntimeRefValue, + name: string, + type?: string + ): string { + let res = ''; + const frame = this.frameStack.frames.find(frame => frame.id === refValue.loc.frameID); + let local = undefined; + if (!frame) { + return res; + } + for (const scope of frame.locals) { + local = scope[refValue.loc.localIndex]; + if (local) { + break; + } + } + if (!local) { + return res; + } + return this.valueToString(tabs, local.value, name, type); + } + + /** + * Returns a string representation of a runtime value. + * + * @param value runtime value. + * @param name name of the variable containing the value. + * @param type optional type of the variable containing the value. + * @returns string representation of the value. + */ + private valueToString( + tabs: string, + value: RuntimeValueType, + name: string, + type?: string + ): string { + let res = ''; + if (typeof value === 'string') { + res += tabs + name + ' : ' + value + '\n'; + if (type) { + res += tabs + 'type: ' + type + '\n'; + } + } else if (Array.isArray(value)) { + res += tabs + name + ' : [\n'; + for (let i = 0; i < value.length; i++) { + res += this.valueToString(tabs + this.singleTab, value[i], String(i)); + } + res += tabs + ']\n'; + if (type) { + res += tabs + 'type: ' + type + '\n'; + } + return res; + } else if ('fields' in value) { + res += tabs + name + ' : ' + this.compoundValueToString(tabs, value); + if (type) { + res += tabs + 'type: ' + type + '\n'; + } + } else { + res += this.refValueToString(tabs, value, name, type); + } + return res; + } +} + +/** + * Handles a write to a local variable in a stack frame. + * + * @param frame stack frame frame. + * @param localIndex variable index in the frame. + * @param runtimeValue variable value. + */ +function localWrite( + frame: IRuntimeStackFrame, + localIndex: number, + value: RuntimeValueType +): void { + const type = frame.localsTypes[localIndex]; + if (!type) { + throw new Error('Cannot find type for local variable at index: ' + + localIndex + + ' in function: ' + + frame.name); + } + const name = frame.localsNames[localIndex]; + if (!name) { + throw new Error('Cannot find local variable at index: ' + + localIndex + + ' in function: ' + + frame.name); + } + + if (name.includes('%')) { + // don't show "artificial" variables generated by the compiler + // for enum and macro execution as they would be quite confusing + // for the user without knowing compilation internals + return; + } + + + const scopesCount = frame.locals.length; + if (scopesCount <= 0) { + throw new Error("There should be at least one variable scope in function" + + frame.name); + } + // If a variable has the same name but a different index (it is shadowed) + // it has to be put in a different scope (e.g., locals[1], locals[2], etc.). + // Find scope already containing variable name, if any, starting from + // the outermost one + let existingVarScope = -1; + for (let i = scopesCount - 1; i >= 0; i--) { + const existingVarIndex = frame.locals[i].findIndex(runtimeVar => { + return runtimeVar && runtimeVar.name === name; + }); + if (existingVarIndex !== -1 && existingVarIndex !== localIndex) { + existingVarScope = i; + break; + } + } + if (existingVarScope >= 0) { + const shadowedScope = frame.locals[existingVarScope + 1]; + if (!shadowedScope) { + frame.locals.push([]); + } + frame.locals[existingVarScope + 1][localIndex] = { name, value, type }; + } else { + // put variable in the "main" locals scope + frame.locals[0][localIndex] = { name, value, type }; + } +} + +/** + * Finds the root directory of the package containing the active file. + * + * @param active_file_path path to a file active in the editor. + * @returns root directory of the package containing the active file. + */ +async function findPkgRoot(active_file_path: string): Promise { + const containsManifest = (dir: string): boolean => { + const filesInDir = fs.readdirSync(dir); + return filesInDir.includes('Move.toml'); + }; + + const activeFileDir = path.dirname(active_file_path); + let currentDir = activeFileDir; + while (currentDir !== path.parse(currentDir).root) { + if (containsManifest(currentDir)) { + return currentDir; + } + currentDir = path.resolve(currentDir, '..'); + } + + if (containsManifest(currentDir)) { + return currentDir; + } + + return undefined; +} + +/** + * Find the package name in the manifest file. + * + * @param pkgRoot root directory of the package. + * @returns package name. + */ +function getPkgNameFromManifest(pkgRoot: string): string | undefined { + const manifest = fs.readFileSync(pkgRoot, 'utf8'); + const parsedManifest = toml.parse(manifest); + const packageName = parsedManifest.package.name; + return packageName; +} + +/** + * Computes the SHA-256 hash of a file's contents. + * + * @param fileContents contents of the file. + */ +function computeFileHash(fileContents: string): Uint8Array { + const hash = crypto.createHash('sha256').update(fileContents).digest(); + return new Uint8Array(hash); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/src/server.ts b/external-crates/move/crates/move-analyzer/trace-adapter/src/server.ts new file mode 100644 index 00000000000..e2d3a069796 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/src/server.ts @@ -0,0 +1,5 @@ +import { DebugSession } from '@vscode/debugadapter'; +import { MoveDebugSession } from './adapter'; + +// Run the MoveDebugSession debug adapter using stdio +DebugSession.run(MoveDebugSession); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/src/source_map_utils.ts b/external-crates/move/crates/move-analyzer/trace-adapter/src/source_map_utils.ts new file mode 100644 index 00000000000..bb3fee11bdc --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/src/source_map_utils.ts @@ -0,0 +1,370 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import * as fs from 'fs'; +import * as path from 'path'; +import { ModuleInfo } from './utils'; + +// Data types corresponding to source map file JSON schema. + +interface JSONSrcDefinitionLocation { + file_hash: number[]; + start: number; + end: number; +} + +interface JSONSrcStructSourceMapEntry { + definition_location: JSONSrcDefinitionLocation; + type_parameters: [string, JSONSrcDefinitionLocation][]; + fields: JSONSrcDefinitionLocation[]; +} + +interface JSONSrcEnumSourceMapEntry { + definition_location: JSONSrcDefinitionLocation; + type_parameters: [string, JSONSrcDefinitionLocation][]; + variants: [[string, JSONSrcDefinitionLocation], JSONSrcDefinitionLocation[]][]; +} + +interface JSONSrcFunctionMapEntry { + location: JSONSrcDefinitionLocation; + definition_location: JSONSrcDefinitionLocation; + type_parameters: [string, JSONSrcDefinitionLocation][]; + parameters: [string, JSONSrcDefinitionLocation][]; + locals: [string, JSONSrcDefinitionLocation][]; + nops: Record; + code_map: Record; + is_native: boolean; +} + +interface JSONSrcRootObject { + definition_location: JSONSrcDefinitionLocation; + module_name: string[]; + struct_map: Record; + enum_map: Record; + function_map: Record; + constant_map: Record; +} + +// Runtime data types. + +/** + * Describes a location in terms of line/column. + */ +export interface ILoc { + line: number; + column: number; +} + +/** + * Describes a location in the source file. + */ +export interface IFileLoc { + fileHash: string; + loc: ILoc; +} + +/** + * Describes a function in the source map. + */ +export interface ISourceMapFunction { + /** + * Locations indexed with PC values. + */ + pcLocs: IFileLoc[], + /** + * Names of local variables by their index in the frame + * (parameters first, then actual locals). + */ + localsNames: string[], + /** + * Location of function definition start. + */ + startLoc: ILoc, + /** + * Location of function definition start. + */ + endLoc: ILoc +} + +/** + * Information about a Move source file. + */ +export interface IFileInfo { + // File path. + path: string; + // File content. + content: string; + // File content split into lines (for efficient line/column calculations). + lines: string[]; +} + +/** + * Source map for a Move module. + */ +export interface ISourceMap { + filePath: string + fileHash: string + modInfo: ModuleInfo, + functions: Map, + /** + * Lines that are not present in the source map. + */ + optimizedLines: number[] +} + +export function readAllSourceMaps( + directory: string, + filesMap: Map +): Map { + const sourceMapsMap = new Map(); + const allSourceMapLinesMap = new Map>; + + const processDirectory = (dir: string) => { + const files = fs.readdirSync(dir); + for (const f of files) { + const filePath = path.join(dir, f); + const stats = fs.statSync(filePath); + if (stats.isDirectory()) { + processDirectory(filePath); + } else if (path.extname(f) === '.json') { + const sourceMap = readSourceMap(filePath, filesMap, allSourceMapLinesMap); + sourceMapsMap.set(JSON.stringify(sourceMap.modInfo), sourceMap); + } + } + }; + + processDirectory(directory); + + for (const sourceMap of sourceMapsMap.values()) { + const fileHash = sourceMap.fileHash; + const sourceMapLines = allSourceMapLinesMap.get(fileHash); + const fileInfo = filesMap.get(fileHash); + if (sourceMapLines && fileInfo) { + for (let i = 0; i < fileInfo.lines.length; i++) { + if (!sourceMapLines.has(i + 1)) { // allSourceMapLines is 1-based + sourceMap.optimizedLines.push(i); // result must be 0-based + } + } + } + } + + + return sourceMapsMap; +} + +/** + * Reads a Move VM source map from a JSON file. + * + * @param sourceMapPath path to the source map JSON file. + * @param filesMap map from file hash to file information. + * @param sourceMapLinesMap map from file hash to set of lines present + * in all source maps for a given file (a given source map may contain + * source lines for different files due to inlining). + * @returns source map. + * @throws Error if with a descriptive error message if the source map cannot be read. + */ +function readSourceMap( + sourceMapPath: string, + filesMap: Map, + sourceMapLinesMap: Map> +): ISourceMap { + const sourceMapJSON: JSONSrcRootObject = JSON.parse(fs.readFileSync(sourceMapPath, 'utf8')); + + const fileHash = Buffer.from(sourceMapJSON.definition_location.file_hash).toString('base64'); + const modInfo: ModuleInfo = { + addr: sourceMapJSON.module_name[0], + name: sourceMapJSON.module_name[1] + }; + const functions = new Map(); + const fileInfo = filesMap.get(fileHash); + if (!fileInfo) { + throw new Error('Could not find file with hash: ' + + fileHash + + ' when processing source map at: ' + + sourceMapPath); + } + const sourceMapLines = sourceMapLinesMap.get(fileHash) ?? new Set; + prePopulateSourceMapLines(sourceMapJSON, fileInfo, sourceMapLines); + sourceMapLinesMap.set(fileHash, sourceMapLines); + const functionMap = sourceMapJSON.function_map; + for (const funEntry of Object.values(functionMap)) { + let nameStart = funEntry.definition_location.start; + let nameEnd = funEntry.definition_location.end; + const funName = fileInfo.content.slice(nameStart, nameEnd); + const pcLocs: IFileLoc[] = []; + let prevPC = 0; + // we need to initialize `prevFileLoc` to make the compiler happy but it's never + // going to be used as the first PC in the frame is always 0 so the inner + // loop never gets executed during first iteration of the outer loop + let prevLoc: IFileLoc = { + fileHash: "", + loc: { line: -1, column: -1 } + }; + // create a list of locations for each PC, even those not explicitly listed + // in the source map + for (const [pc, defLocation] of Object.entries(funEntry.code_map)) { + const currentPC = parseInt(pc); + const defLocFileHash = Buffer.from(defLocation.file_hash).toString('base64'); + const fileInfo = filesMap.get(defLocFileHash); + if (!fileInfo) { + throw new Error('Could not find file with hash: ' + + fileHash + + ' when processing source map at: ' + + sourceMapPath); + } + const currentStartLoc = byteOffsetToLineColumn(fileInfo, defLocation.start); + const currentFileStartLoc: IFileLoc = { + fileHash: defLocFileHash, + loc: currentStartLoc + }; + const sourceMapLines = sourceMapLinesMap.get(defLocFileHash) ?? new Set; + sourceMapLines.add(currentStartLoc.line); + // add the end line to the set as well even if we don't need it for pcLocs + const currentEndLoc = byteOffsetToLineColumn(fileInfo, defLocation.end); + sourceMapLines.add(currentEndLoc.line); + sourceMapLinesMap.set(defLocFileHash, sourceMapLines); + for (let i = prevPC + 1; i < currentPC; i++) { + pcLocs.push(prevLoc); + } + pcLocs.push(currentFileStartLoc); + prevPC = currentPC; + prevLoc = currentFileStartLoc; + } + + const localsNames: string[] = []; + for (const param of funEntry.parameters) { + const paramName = param[0].split("#")[0]; + if (!paramName) { + localsNames.push(param[0]); + } else { + localsNames.push(paramName); + } + } + + for (const local of funEntry.locals) { + const localsName = local[0].split("#")[0]; + if (!localsName) { + localsNames.push(local[0]); + } else { + localsNames.push(localsName); + } + } + // compute start and end of function definition + const startLoc = byteOffsetToLineColumn(fileInfo, funEntry.location.start); + const endLoc = byteOffsetToLineColumn(fileInfo, funEntry.location.end); + functions.set(funName, { pcLocs, localsNames, startLoc, endLoc }); + } + return { filePath: fileInfo.path, fileHash, modInfo, functions, optimizedLines: [] }; +} + +/** + * Pre-populates the set of source file lines that are present in the source map + * with lines corresponding to the definitions of module, structs, enums, and functions + * (excluding location of instructions in the function body which are handled elsewhere). + * Constants do not have location information in the source map and must be handled separately. + * + * @param sourceMapJSON + * @param fileInfo + * @param sourceMapLines + */ +function prePopulateSourceMapLines( + sourceMapJSON: JSONSrcRootObject, + fileInfo: IFileInfo, + sourceMapLines: Set +): void { + addLinesForLocation(sourceMapJSON.definition_location, fileInfo, sourceMapLines); + const structMap = sourceMapJSON.struct_map; + for (const structEntry of Object.values(structMap)) { + addLinesForLocation(structEntry.definition_location, fileInfo, sourceMapLines); + for (const typeParam of structEntry.type_parameters) { + addLinesForLocation(typeParam[1], fileInfo, sourceMapLines); + } + for (const fieldDef of structEntry.fields) { + addLinesForLocation(fieldDef, fileInfo, sourceMapLines); + } + } + + const enumMap = sourceMapJSON.enum_map; + for (const enumEntry of Object.values(enumMap)) { + addLinesForLocation(enumEntry.definition_location, fileInfo, sourceMapLines); + for (const typeParam of enumEntry.type_parameters) { + addLinesForLocation(typeParam[1], fileInfo, sourceMapLines); + } + for (const variant of enumEntry.variants) { + addLinesForLocation(variant[0][1], fileInfo, sourceMapLines); + for (const fieldDef of variant[1]) { + addLinesForLocation(fieldDef, fileInfo, sourceMapLines); + } + } + } + + const functionMap = sourceMapJSON.function_map; + for (const funEntry of Object.values(functionMap)) { + addLinesForLocation(funEntry.definition_location, fileInfo, sourceMapLines); + for (const typeParam of funEntry.type_parameters) { + addLinesForLocation(typeParam[1], fileInfo, sourceMapLines); + } + for (const param of funEntry.parameters) { + addLinesForLocation(param[1], fileInfo, sourceMapLines); + } + for (const local of funEntry.locals) { + addLinesForLocation(local[1], fileInfo, sourceMapLines); + } + } +} + +/** + * Adds source file lines for the given location to the set. + * + * @param loc location in the source file. + * @param fileInfo source file information. + * @param sourceMapLines set of source file lines. + */ +function addLinesForLocation( + loc: JSONSrcDefinitionLocation, + fileInfo: IFileInfo, + sourceMapLines: Set +): void { + const startLine = byteOffsetToLineColumn(fileInfo, loc.start).line; + sourceMapLines.add(startLine); + const endLine = byteOffsetToLineColumn(fileInfo, loc.end).line; + sourceMapLines.add(endLine); +} + + +/** + * Computes source file location (line/colum) from the byte offset + * (assumes that lines and columns are 1-based). + * + * @param fileInfo source file information. + * @param offset byte offset in the source file. + * @returns Source file location (line/column). + */ +function byteOffsetToLineColumn( + fileInfo: IFileInfo, + offset: number, +): ILoc { + if (offset < 0) { + return { line: 1, column: 1 }; + } + const lines = fileInfo.lines; + if (offset >= fileInfo.content.length) { + return { line: lines.length, column: lines[lines.length - 1].length + 1 /* 1-based */ }; + } + let accumulatedLength = 0; + + for (let lineNumber = 0; lineNumber < lines.length; lineNumber++) { + const lineLength = lines[lineNumber].length + 1; // +1 for the newline character + + if (accumulatedLength + lineLength > offset) { + return { + line: lineNumber + 1, // 1-based + column: offset - accumulatedLength + 1 // 1-based + }; + } + + accumulatedLength += lineLength; + } + return { line: lines.length, column: lines[lines.length - 1].length + 1 /* 1-based */ }; +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/src/trace_utils.ts b/external-crates/move/crates/move-analyzer/trace-adapter/src/trace_utils.ts new file mode 100644 index 00000000000..ecac4ab4c2f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/src/trace_utils.ts @@ -0,0 +1,942 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import * as fs from 'fs'; +import { FRAME_LIFETIME, ModuleInfo } from './utils'; +import { + IRuntimeCompoundValue, + RuntimeValueType, + IRuntimeVariableLoc, + IRuntimeRefValue +} from './runtime'; +import { ISourceMap, IFileLoc, IFileInfo, ILoc, ISourceMapFunction } from './source_map_utils'; + + +// Data types corresponding to trace file JSON schema. + +interface JSONTraceModule { + address: string; + name: string; +} + +interface JSONStructTypeDescription { + address: string; + module: string; + name: string; + type_args: string[]; +} + +interface JSONStructType { + struct: JSONStructTypeDescription; +} + +interface JSONVectorType { + vector: JSONBaseType; +} + +type JSONBaseType = string | JSONStructType | JSONVectorType; + +enum JSONTraceRefType { + Mut = 'Mut', + Imm = 'Imm' +} + +interface JSONTraceType { + type_: JSONBaseType; + ref_type?: JSONTraceRefType +} + +type JSONTraceRuntimeValueType = boolean | number | string | JSONTraceRuntimeValueType[] | JSONTraceCompound; + +interface JSONTraceFields { + [key: string]: JSONTraceRuntimeValueType; +} + +interface JSONTraceCompound { + fields: JSONTraceFields; + type: string; + variant_name?: string; + variant_tag?: number; +} + +interface JSONTraceRefValueContent { + location: JSONTraceLocation; + snapshot: JSONTraceRuntimeValueType; +} + +interface JSONTraceMutRefValue { + MutRef: JSONTraceRefValueContent; +} + +interface JSONTraceImmRefValue { + ImmRef: JSONTraceRefValueContent; +} + +interface JSONTraceRuntimeValueContent { + value: JSONTraceRuntimeValueType; +} + +interface JSONTraceRuntimeValue { + RuntimeValue: JSONTraceRuntimeValueContent; +} + +export type JSONTraceRefValue = JSONTraceMutRefValue | JSONTraceImmRefValue; + +export type JSONTraceValue = JSONTraceRuntimeValue | JSONTraceRefValue; + +interface JSONTraceFrame { + binary_member_index: number; + frame_id: number; + function_name: string; + is_native: boolean; + locals_types: JSONTraceType[]; + module: JSONTraceModule; + parameters: JSONTraceValue[]; + return_types: JSONTraceType[]; + type_instantiation: string[]; +} + +interface JSONTraceOpenFrame { + frame: JSONTraceFrame; + gas_left: number; +} + +interface JSONTraceInstruction { + gas_left: number; + instruction: string; + pc: number; + type_parameters: any[]; +} + +interface JSONTraceLocalLocation { + Local: [number, number]; +} + +interface JSONTraceIndexedLocation { + Indexed: [JSONTraceLocalLocation, number]; +} + +type JSONTraceLocation = JSONTraceLocalLocation | JSONTraceIndexedLocation; + +interface JSONTraceWriteEffect { + location: JSONTraceLocation; + root_value_after_write: JSONTraceRuntimeValue; +} + +interface JSONTraceReadEffect { + location: JSONTraceLocation; + moved: boolean; + root_value_read: JSONTraceRuntimeValue; +} + +interface JSONTracePushEffect { + RuntimeValue?: JSONTraceRuntimeValueContent; + MutRef?: { + location: JSONTraceLocation; + snapshot: any[]; + }; +} + +interface JSONTracePopEffect { + RuntimeValue?: JSONTraceRuntimeValueContent; + MutRef?: { + location: JSONTraceLocation; + snapshot: any[]; + }; +} + +interface JSONTraceEffect { + Push?: JSONTracePushEffect; + Pop?: JSONTracePopEffect; + Write?: JSONTraceWriteEffect; + Read?: JSONTraceReadEffect; + ExecutionError?: string; + +} + +interface JSONTraceCloseFrame { + frame_id: number; + gas_left: number; + return_: JSONTraceRuntimeValueContent[]; +} + +interface JSONTraceEvent { + OpenFrame?: JSONTraceOpenFrame; + Instruction?: JSONTraceInstruction; + Effect?: JSONTraceEffect; + CloseFrame?: JSONTraceCloseFrame; +} + +interface JSONTraceRootObject { + events: JSONTraceEvent[]; + version: number; +} + +// Runtime data types. + +/** + * Kind of instruction in the trace. Enum member names correspond to instruction names. + * (other than UNKNOWN which is used for instructions whose kind does not matter). + */ +export enum TraceInstructionKind { + /** + * Call instruction. + */ + CALL, + /** + * Generic call instruction. + */ + CALL_GENERIC, + // for now we don't care about other kinds of instructions + UNKNOWN +} + +/** + * Kind of a trace event. + */ +export enum TraceEventKind { + /** + * Artificial event to replace the content of the current inlined frame + * with the content of another frame. This is to make sure that there is + * only one inlined frame on the stack at any given time as inlined frames + * are not being pushed and popped symmetrically and need to be handled + * differently than regular frames. + */ + ReplaceInlinedFrame, + OpenFrame, + CloseFrame, + Instruction, + Effect +} + +/** + * Trace event types containing relevant data. + */ +export type TraceEvent = + | { + type: TraceEventKind.ReplaceInlinedFrame + fileHash: string + optimizedLines: number[] + } + | { + type: TraceEventKind.OpenFrame, + id: number, + name: string, + fileHash: string + isNative: boolean, + localsTypes: string[], + localsNames: string[], + paramValues: RuntimeValueType[] + optimizedLines: number[] + } + | { type: TraceEventKind.CloseFrame, id: number } + | { type: TraceEventKind.Instruction, pc: number, loc: ILoc, kind: TraceInstructionKind } + | { type: TraceEventKind.Effect, effect: EventEffect }; + +/** + * Kind of an effect of an instruction. + */ +export enum TraceEffectKind { + Write = 'Write', + ExecutionError = 'ExecutionError' + // TODO: other effect types +} + +/** + * Effect of an instruction. + */ +export type EventEffect = + | { type: TraceEffectKind.Write, loc: IRuntimeVariableLoc, value: RuntimeValueType } + | { type: TraceEffectKind.ExecutionError, msg: string }; + +/** + * Execution trace consisting of a sequence of trace events. + */ +interface ITrace { + events: TraceEvent[]; + /** + * Maps frame ID to an array of local variable lifetime ends + * indexed by the local variable index in the trace + * (variable lifetime end is PC of an instruction following + * the last variable access). + */ + localLifetimeEnds: Map; + + /** + * Maps file path to the lines of code present in the trace instructions + * in functions defined in the file. + */ + tracedLines: Map>; +} + +/** + * Information about the frame being currently processed used during trace generation. + */ +interface ITraceGenFrameInfo { + /** + * Frame ID. + */ + ID: number; + /** + * PC locations traced in the frame + */ + pcLocs: IFileLoc[]; + /** + * Path to a file containing function represented by the frame. + */ + filePath: string; + /** + * Hash of a file containing function represented by the frame. + */ + fileHash: string; + /** + * Code ines in a given file that have been optimized away. + */ + optimizedLines: number[]; + /** + * Name of the function represented by the frame. + */ + funName: string; + /** + * Source map information for a given function. + */ + funEntry: ISourceMapFunction; +} + +/** + * An ID of a virtual frame representing a macro defined in the same file + * where it is inlined. + */ +const INLINED_FRAME_ID_SAME_FILE = -1; +/** + * An ID of a virtual frame representing a macro defined in a different file + * than file where it is inlined. + */ +const INLINED_FRAME_ID_DIFFERENT_FILE = -2; + +/** + * Reads a Move VM execution trace from a JSON file. + * + * @param traceFilePath path to the trace JSON file. + * @param sourceMapsModMap a map from stringified module info to a source map. + * @param sourceMapsHashMap a map from file hash to a source map. + * @returns execution trace. + * @throws Error with a descriptive error message if reading trace has failed. + */ +export function readTrace( + traceFilePath: string, + sourceMapsModMap: Map, + sourceMapsHashMap: Map, + filesMap: Map +): ITrace { + const traceJSON: JSONTraceRootObject = JSON.parse(fs.readFileSync(traceFilePath, 'utf8')); + if (traceJSON.events.length === 0) { + throw new Error('Trace contains no events'); + } + const events: TraceEvent[] = []; + // We compute the end of lifetime for a local variable as follows. + // When a given local variable is read or written in an effect, we set the end of its lifetime + // to FRAME_LIFETIME. When a new instruction is executed, we set the end of its lifetime + // to be the PC of this instruction. The caveat here is that we must use + // the largest PC of all encountered instructions for this to avoid incorrectly + // setting the end of lifetime to a smaller PC in case of a loop. + // + // For example, consider the following code: + // ``` + // while (x < foo()) { + // x = x + 1; + // } + // ``` + // In this case (simplifying a bit), `x` should be live throughout + // (unrolled in the trace) iterations of the loop. However, the last + // instruction executed after `x` is accessed for the last time + // will be `foo` whose PC is lower than PCs of instructions in/beyond + // the loop + const localLifetimeEnds = new Map(); + const localLifetimeEndsMax = new Map(); + const tracedLines = new Map>(); + // stack of frame infos OpenFrame and popped on CloseFrame + const frameInfoStack: ITraceGenFrameInfo[] = []; + for (const event of traceJSON.events) { + if (event.OpenFrame) { + const localsTypes = []; + const frame = event.OpenFrame.frame; + for (const type of frame.locals_types) { + localsTypes.push(JSONTraceTypeToString(type.type_, type.ref_type)); + } + // process parameters - store their values in trace and set their + // initial lifetimes + const paramValues = []; + const lifetimeEnds = localLifetimeEnds.get(frame.frame_id) || []; + for (let i = 0; i < frame.parameters.length; i++) { + const value = frame.parameters[i]; + if (value) { + const runtimeValue: RuntimeValueType = 'RuntimeValue' in value + ? traceRuntimeValueFromJSON(value.RuntimeValue.value) + : traceRefValueFromJSON(value); + + paramValues.push(runtimeValue); + lifetimeEnds[i] = FRAME_LIFETIME; + } + } + localLifetimeEnds.set(frame.frame_id, lifetimeEnds); + const modInfo = { + addr: frame.module.address, + name: frame.module.name + }; + const sourceMap = sourceMapsModMap.get(JSON.stringify(modInfo)); + if (!sourceMap) { + throw new Error('Source map for module ' + + modInfo.name + + ' in package ' + + modInfo.addr + + ' not found'); + } + const funEntry = sourceMap.functions.get(frame.function_name); + if (!funEntry) { + throw new Error('Cannot find function entry in source map for function ' + + frame.function_name + + ' when processing OpenFrame event'); + } + events.push({ + type: TraceEventKind.OpenFrame, + id: frame.frame_id, + name: frame.function_name, + fileHash: sourceMap.fileHash, + isNative: frame.is_native, + localsTypes, + localsNames: funEntry.localsNames, + paramValues, + optimizedLines: sourceMap.optimizedLines + }); + const currentFile = filesMap.get(sourceMap.fileHash); + + if (!currentFile) { + throw new Error(`Cannot find file with hash: ${sourceMap.fileHash}`); + } + frameInfoStack.push({ + ID: frame.frame_id, + pcLocs: funEntry.pcLocs, + filePath: currentFile.path, + fileHash: sourceMap.fileHash, + optimizedLines: sourceMap.optimizedLines, + funName: frame.function_name, + funEntry + }); + } else if (event.CloseFrame) { + events.push({ + type: TraceEventKind.CloseFrame, + id: event.CloseFrame.frame_id + }); + frameInfoStack.pop(); + } else if (event.Instruction) { + const name = event.Instruction.instruction; + let frameInfo = frameInfoStack[frameInfoStack.length - 1]; + const fid = frameInfo.ID; + const pcLocs = frameInfo.pcLocs; + // if map does not contain an entry for a PC that can be found in the trace file, + // it means that the position of the last PC in the source map should be used + let instLoc = event.Instruction.pc >= pcLocs.length + ? pcLocs[pcLocs.length - 1] + : pcLocs[event.Instruction.pc]; + + if (!instLoc) { + throw new Error('Cannot find location for PC: ' + + event.Instruction.pc + + ' in frame: ' + + fid); + } + + const differentFileVirtualFramePop = processInstructionIfMacro( + sourceMapsHashMap, + events, + frameInfoStack, + event.Instruction.pc, + instLoc + ); + + if (differentFileVirtualFramePop) { + // if we pop a virtual frame for a macro defined in a different file, + // we may still land in a macro defined in the same file, in which case + // we need to push another virtual frame for this instruction right away + processInstructionIfMacro( + sourceMapsHashMap, + events, + frameInfoStack, + event.Instruction.pc, + instLoc + ); + } + + + // re-read frame info as it may have changed as a result of processing + // and inlined call + frameInfo = frameInfoStack[frameInfoStack.length - 1]; + const filePath = frameInfo.filePath; + const lines = tracedLines.get(filePath) || new Set(); + // floc is still good as the pc_locs used for its computation + // do not change as a result of processing inlined frames + lines.add(instLoc.loc.line); + tracedLines.set(filePath, lines); + events.push({ + type: TraceEventKind.Instruction, + pc: event.Instruction.pc, + loc: instLoc.loc, + kind: name in TraceInstructionKind + ? TraceInstructionKind[name as keyof typeof TraceInstructionKind] + : TraceInstructionKind.UNKNOWN + }); + + // Set end of lifetime for all locals to the max instruction PC ever seen + // for a given local (if they are live after this instructions, they will + // be reset to FRAME_LIFETIME when processing subsequent effects). + // All instructions in a given function, regardless of whether they are + // in the inlined portion of the code or not, reset variable lifetimes. + const nonInlinedFrameID = frameInfo.ID !== INLINED_FRAME_ID_SAME_FILE && + frameInfo.ID !== INLINED_FRAME_ID_DIFFERENT_FILE + ? frameInfo.ID + : frameInfoStack[frameInfoStack.length - 2].ID; + const lifetimeEnds = localLifetimeEnds.get(nonInlinedFrameID) || []; + const lifetimeEndsMax = localLifetimeEndsMax.get(nonInlinedFrameID) || []; + for (let i = 0; i < lifetimeEnds.length; i++) { + if (lifetimeEnds[i] === undefined || lifetimeEnds[i] === FRAME_LIFETIME) { + // only set new end of lifetime if it has not been set before + // or if variable is live + const pc = event.Instruction.pc; + if (lifetimeEndsMax[i] === undefined || lifetimeEndsMax[i] < pc) { + lifetimeEnds[i] = pc; + lifetimeEndsMax[i] = pc; + } + } + } + localLifetimeEnds.set(nonInlinedFrameID, lifetimeEnds); + localLifetimeEndsMax.set(nonInlinedFrameID, lifetimeEndsMax); + } else if (event.Effect) { + const effect = event.Effect; + if (effect.Write || effect.Read) { + // if a local is read or written, set its end of lifetime + // to infinite (end of frame) + const location = effect.Write ? effect.Write.location : effect.Read!.location; + const loc = processJSONLocalLocation(location, localLifetimeEnds); + if (effect.Write) { + if (!loc) { + throw new Error('Unsupported location type in Write effect'); + } + // process a write only if the location is supported + const value = 'RuntimeValue' in effect.Write.root_value_after_write + ? traceRuntimeValueFromJSON(effect.Write.root_value_after_write.RuntimeValue.value) + : traceRefValueFromJSON(effect.Write.root_value_after_write); + events.push({ + type: TraceEventKind.Effect, + effect: { + type: TraceEffectKind.Write, + loc, + value + } + }); + } + } + if (effect.ExecutionError) { + events.push({ + type: TraceEventKind.Effect, + effect: { + type: TraceEffectKind.ExecutionError, + msg: effect.ExecutionError + } + }); + } + } + } + return { events, localLifetimeEnds, tracedLines }; +} + +/** + * Additional processing of an instruction if it's detected that it belongs + * to an inlined macro. If this is the case, then virtual frames may be pushed + * to the stack or popped from it. + * + * @param sourceMapsHashMap a map from file hash to a source map. + * @param events trace events. + * @param frameInfoStack stack of frame infos used during trace generation. + * @param instPC PC of the instruction. + * @param instLoc location of the instruction. + * @returns `true` if this instruction caused a pop of a virtual frame for + * an inlined macro defined in a different file, `false` otherwise. + */ +function processInstructionIfMacro( + sourceMapsHashMap: Map, + events: TraceEvent[], + frameInfoStack: ITraceGenFrameInfo[], + instPC: number, + instLoc: IFileLoc +): boolean { + let frameInfo = frameInfoStack[frameInfoStack.length - 1]; + const fid = frameInfo.ID; + if (instLoc.fileHash !== frameInfo.fileHash) { + // This indicates that we are going to an instruction in the same function + // but in a different file, which can happen due to macro inlining. + // One could think of "outlining" the inlined code to create separate + // frames for each inlined macro but unfortunately this will not quite work. + // The reason is that we cannot rely on these the inlined frame pushes and pops + // being symmetric. Consider the following example: + //``` + // macro fun baz() { + // ... + // } + // macro fun bar() { + // baz!(); + // ... + // } + // fun foo() { + // bar!(); + // } + //``` + // In the example above, according to the trace, there will be only + // one inlined frame push as the first instruction of function `foo` + // will be an instruction in macro `baz` instead of an instruction + // in macro `bar`. Yet, when the control flow exits `baz`, it will go + // to `bar`, and then to `foo`. + // + // The high level idea of how to handle this situation is to always + // keep only a single inlined frame on the stack: + // - the first time we see different file hashes, we push an inlined + // frame on the stack + // - if an inlined frame is already on the stack, and the next file + // hash transition happens, then we do ond of the following: + // - if the next file hash is the same as the file hash of the frame + // before the current one, we pop the current inlined frame + // - otherwise, we replace the current inlined frame with the new one + // + // The exception to this single-inlined-frame rule is when we are already + // in an inlined frame for a macro defined in the same file, and go to + // a macro in a different file. In this case, we will have two inlined + // frames on the stack. + if (frameInfoStack.length > 1 && + frameInfoStack[frameInfoStack.length - 2].fileHash === instLoc.fileHash + ) { + frameInfoStack.pop(); + events.push({ + type: TraceEventKind.CloseFrame, + id: fid + }); + return true; + } else { + const sourceMap = sourceMapsHashMap.get(instLoc.fileHash); + if (!sourceMap) { + throw new Error('Cannot find source map for file with hash: ' + + instLoc.fileHash + + ' when frame switching within frame ' + + fid + + ' at PC ' + + instPC); + } + if (frameInfo.ID === INLINED_FRAME_ID_DIFFERENT_FILE) { + events.push({ + type: TraceEventKind.ReplaceInlinedFrame, + fileHash: instLoc.fileHash, + optimizedLines: sourceMap.optimizedLines + }); + // pop the current inlined frame so that it can + // be replaced on the frame info stack below + frameInfoStack.pop(); + } else { + events.push({ + type: TraceEventKind.OpenFrame, + id: INLINED_FRAME_ID_DIFFERENT_FILE, + name: '__inlined__', + fileHash: instLoc.fileHash, + isNative: false, + localsTypes: [], + localsNames: [], + paramValues: [], + optimizedLines: sourceMap.optimizedLines + }); + } + frameInfoStack.push({ + ID: INLINED_FRAME_ID_DIFFERENT_FILE, + // same pcLocs as before since we are in the same function + pcLocs: frameInfo.pcLocs, + filePath: sourceMap.filePath, + fileHash: sourceMap.fileHash, + optimizedLines: sourceMap.optimizedLines, + // same function name and source map as before since we are in the same function + funName: frameInfo.funName, + funEntry: frameInfo.funEntry + }); + } + } else if (frameInfo.ID !== INLINED_FRAME_ID_DIFFERENT_FILE) { + // We are in the same file here, though perhaps this instruction + // belongs to an inlined macro. If we are already in an inlined + // frame for a macro defined in a different file, we don't do + // anything do avoid pushing a new inlined frame for a macro. + // + // Otherwise, below we check if instruction belongs to an inlined macro + // when this macro is defined in the same file to provide similar + // behavior as when the macro is defined in a different file + // (push/pop virtual inlined frames). The implementation here is + // a bit different, though, as we don't have explicit boundaries + // for when the code transitions from/to inlined code. Instead, + // we need to inspect each instruction and act as follows: + // - if the instruction is outside of the function (belongs to inlined macro): + // - if we are not in an inlined frame, we need to push one + // - if we are in an inlined frame, we don't need to do anything + // - if the instruction is in the function: + // - if we are in an inlined frame, we need to pop it + // - if we are not in an inlined frame, we don't need to do anything + if (instLoc.loc.line < frameInfo.funEntry.startLoc.line || + instLoc.loc.line > frameInfo.funEntry.endLoc.line || + (instLoc.loc.line === frameInfo.funEntry.startLoc.line && + instLoc.loc.column < frameInfo.funEntry.startLoc.column) || + (instLoc.loc.line === frameInfo.funEntry.endLoc.line && + instLoc.loc.column > frameInfo.funEntry.endLoc.column)) { + // the instruction is outside of the function + // (belongs to inlined macro) + if (frameInfo.ID !== INLINED_FRAME_ID_SAME_FILE) { + // if we are not in an inlined frame, we need to push one + events.push({ + type: TraceEventKind.OpenFrame, + id: INLINED_FRAME_ID_SAME_FILE, + name: '__inlined__', + fileHash: instLoc.fileHash, + isNative: false, + localsTypes: [], + localsNames: [], + paramValues: [], + optimizedLines: frameInfo.optimizedLines + }); + // we get a lot of data for the new frame info from the current on + // since we are still in the same function + frameInfoStack.push({ + ID: INLINED_FRAME_ID_SAME_FILE, + pcLocs: frameInfo.pcLocs, + filePath: frameInfo.filePath, + fileHash: instLoc.fileHash, + optimizedLines: frameInfo.optimizedLines, + funName: frameInfo.funName, + funEntry: frameInfo.funEntry + }); + } // else we are already in an inlined frame, so we don't need to do anything + } else { + // the instruction is in the function + if (frameInfo.ID === INLINED_FRAME_ID_SAME_FILE) { + // If we are in an inlined frame, we need to pop it. + // This the place where we need different inlined frame id + // for macros defined in the same or different file than + // the file where they are inlined. Since this check is executed + // for each instruction that is within the function, we could + // accidentally (and incorrectly) at this point pop virtual inlined + // frame for a macro defined in a different file, if we did could not + // distinguish between the two cases. + events.push({ + type: TraceEventKind.CloseFrame, + id: INLINED_FRAME_ID_SAME_FILE + }); + frameInfoStack.pop(); + } // else we are not in an inlined frame, so we don't need to do anything + } + } + return false; +} + + + + +/** + * Converts a JSON trace type to a string representation. + */ +function JSONTraceTypeToString(baseType: JSONBaseType, refType?: JSONTraceRefType): string { + const refPrefix = refType === JSONTraceRefType.Mut + ? '&mut ' + : (refType === JSONTraceRefType.Imm + ? '&' + : ''); + if (typeof baseType === 'string') { + return refPrefix + baseType; + } else if ('vector' in baseType) { + return refPrefix + `vector<${JSONTraceTypeToString(baseType.vector)}>`; + } else { + return refPrefix + + JSONTraceAddressToHexString(baseType.struct.address) + + "::" + + baseType.struct.module + + "::" + + baseType.struct.name; + } +} + +/** + * Attempts to convert an address found in the trace (which is a string + * representing a 32-byte number) to a shorter and more readable hex string. + * Returns original string address if conversion fails. + */ +function JSONTraceAddressToHexString(address: string): string { + try { + const number = BigInt(address); + const hexAddress = number.toString(16); + return `0x${hexAddress}`; + } catch (error) { + // Return the original string if it's not a valid number + return address; + } +} + +/** + * Processes a location of a local variable in a JSON trace: sets the end of its lifetime + * when requested and returns its location + * @param traceLocation location in the trace. + * @param localLifetimeEnds map of local variable lifetimes (defined if local variable + * lifetime should happen). + * @returns variable location. + */ +function processJSONLocalLocation( + traceLocation: JSONTraceLocation, + localLifetimeEnds?: Map, +): IRuntimeVariableLoc | undefined { + if ('Local' in traceLocation) { + const frameID = traceLocation.Local[0]; + const localIndex = traceLocation.Local[1]; + if (localLifetimeEnds) { + const lifetimeEnds = localLifetimeEnds.get(frameID) || []; + lifetimeEnds[localIndex] = FRAME_LIFETIME; + localLifetimeEnds.set(frameID, lifetimeEnds); + } + return { frameID, localIndex }; + } else if ('Indexed' in traceLocation) { + return processJSONLocalLocation(traceLocation.Indexed[0], localLifetimeEnds); + } else { + // Currently, there is nothing that needs to be done for 'Global' locations, + // neither with respect to lifetime nor with respect to location itself. + // This is because `Global` locations currently only represent read-only + // reference values returned from native functions. If there ever was + // a native function that would return a mutable reference, we should + // consider how to handle value changes via such reference, but it's unlikely + // that such a function would ever be added to either Move stdlib or + // the Iota framework. + return undefined; + } +} + +/** + * Converts a JSON trace reference value to a runtime value. + * + * @param value JSON trace reference value. + * @returns runtime value. + * @throws Error with a descriptive error message if conversion has failed. + */ +function traceRefValueFromJSON(value: JSONTraceRefValue): RuntimeValueType { + if ('MutRef' in value) { + const loc = processJSONLocalLocation(value.MutRef.location); + if (!loc) { + throw new Error('Unsupported location type in MutRef'); + } + const ret: IRuntimeRefValue = { mutable: true, loc }; + return ret; + } else { + const loc = processJSONLocalLocation(value.ImmRef.location); + if (!loc) { + throw new Error('Unsupported location type in ImmRef'); + } + const ret: IRuntimeRefValue = { mutable: false, loc }; + return ret; + } +} + +/** + * Converts a JSON trace runtime value to a runtime trace value. + * + * @param value JSON trace runtime value. + * @returns runtime trace value. + */ +function traceRuntimeValueFromJSON(value: JSONTraceRuntimeValueType): RuntimeValueType { + if (typeof value === 'boolean' + || typeof value === 'number' + || typeof value === 'string') { + return String(value); + } else if (Array.isArray(value)) { + return value.map(item => traceRuntimeValueFromJSON(item)); + } else { + const fields: [string, RuntimeValueType][] = + Object.entries(value.fields).map(([key, value]) => [key, traceRuntimeValueFromJSON(value)]); + const compoundValue: IRuntimeCompoundValue = { + fields, + type: value.type, + variantName: value.variant_name, + variantTag: value.variant_tag + }; + return compoundValue; + } +} + +// +// Utility functions for testing and debugging. +// + +/** + * Converts trace events to an array of strings + * representing these events. + * + * @param trace trace. + * @returns array of strings representing trace events. + */ +export function traceEventsToString(trace: ITrace): string[] { + return trace.events.map(event => eventToString(event)); +} + +/** + * Converts a trace event to a string representation. + * + * @param event trace event. + * @returns string representation of the event. + */ +function eventToString(event: TraceEvent): string { + switch (event.type) { + case TraceEventKind.ReplaceInlinedFrame: + return 'ReplaceInlinedFrame'; + case TraceEventKind.OpenFrame: + return `OpenFrame ${event.id} for ${event.name}`; + case TraceEventKind.CloseFrame: + return `CloseFrame ${event.id}`; + case TraceEventKind.Instruction: + return 'Instruction ' + + instructionKindToString(event.kind) + + ' at PC ' + + event.pc + + ', line ' + + event.loc.line; + case TraceEventKind.Effect: + return `Effect ${effectToString(event.effect)}`; + } +} + +/** + * Converts a trace instruction kind to a string representation. + * + * @param kind instruction kind. + * @returns string representation of the instruction kind. + */ +function instructionKindToString(kind: TraceInstructionKind): string { + switch (kind) { + case TraceInstructionKind.CALL: + return 'CALL'; + case TraceInstructionKind.CALL_GENERIC: + return 'CALL_GENERIC'; + case TraceInstructionKind.UNKNOWN: + return 'UNKNOWN'; + } +} + +/** + * Converts an effect of an instruction to a string representation. + * + * @param effect effect. + * @returns string representation of the effect. + */ +function effectToString(effect: EventEffect): string { + switch (effect.type) { + case TraceEffectKind.Write: + return `Write at idx ${effect.loc.localIndex} in frame ${effect.loc.frameID}`; + case TraceEffectKind.ExecutionError: + return `ExecutionError ${effect.msg}`; + } +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/src/utils.ts b/external-crates/move/crates/move-analyzer/trace-adapter/src/utils.ts new file mode 100644 index 00000000000..9a45b057163 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/src/utils.ts @@ -0,0 +1,18 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/** + * Describes a Move module. + */ +export interface ModuleInfo { + addr: string; + name: string; +} + +/** + * If end of lifetime for a local has this value, + * it means that it lives until the end of the current + * frame. + */ +export const FRAME_LIFETIME = -1; \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/.gitignore b/external-crates/move/crates/move-analyzer/trace-adapter/tests/.gitignore new file mode 100644 index 00000000000..4946de71472 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/.gitignore @@ -0,0 +1,6 @@ +**/dependency/* +**/dependencies/* +*.mvsm +*.yaml +*~ +!**/build/ diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/Move.toml new file mode 100644 index 00000000000..0fcf2d84eb2 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "abort_assert" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +abort_assert = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..d315ddb8ef31fd24b7f3ca2232a9f51d20d9e094 GIT binary patch literal 268 zcmbtPOA5j;5S>Y;(KZz^bH+QHjQ>D>3?>ywnAcdLI1OeSDhnw-5i!_fE0HBBlGqJ` P29V`wl#*vO92tB8*m)z0 literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/source_maps/m.json new file mode 100644 index 00000000000..61b40ef6dcf --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":90,"end":91},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":94,"end":171},"definition_location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":98,"end":101},"type_parameters":[],"parameters":[["p#0#0",{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":102,"end":103}]],"returns":[{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":111,"end":114}],"locals":[["val#1#0",{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":125,"end":128}]],"nops":{},"code_map":{"0":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":131,"end":132},"1":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":135,"end":136},"2":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":133,"end":134},"3":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":125,"end":128},"4":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":150,"end":153},"5":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":157,"end":159},"6":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":154,"end":156},"7":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":142,"end":160},"11":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":166,"end":169}},"is_native":false},"1":{"location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":181,"end":208},"definition_location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":185,"end":189},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":202,"end":204},"1":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":198,"end":205},"3":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":205,"end":206}},"is_native":false},"2":{"location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":69,"end":208},"definition_location":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":69,"end":208},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[168,122,162,74,20,113,41,145,92,12,34,91,147,70,136,52,6,15,129,19,242,234,217,255,35,9,215,162,135,4,101,199],"start":69,"end":208}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/sources/m.move new file mode 100644 index 00000000000..089f012c009 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/build/abort_assert/sources/m.move @@ -0,0 +1,13 @@ +// Test abort on an assertion when stepping (but not stepping over). +module abort_assert::m; + +fun foo(p: u64): u64 { + let val = p + p; + assert!(val != 84); + val +} + +#[test] +fun test() { + foo(42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/sources/m.move new file mode 100644 index 00000000000..089f012c009 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/sources/m.move @@ -0,0 +1,13 @@ +// Test abort on an assertion when stepping (but not stepping over). +module abort_assert::m; + +fun foo(p: u64): u64 { + let val = p + p; + assert!(val != 84); + val +} + +#[test] +fun test() { + foo(42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/test.exp new file mode 100644 index 00000000000..2e30fe5759d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/test.exp @@ -0,0 +1 @@ +Exception \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/trace.spec.js new file mode 100644 index 00000000000..ded5216c20d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/trace.spec.js @@ -0,0 +1,11 @@ +const { ExecutionResult } = require('../../out/runtime'); + +let action = (runtime) => { + let res = ''; + // keep stepping to get abort state + runtime.step(false); + runtime.step(false); + res += ExecutionResult[runtime.step(false)]; + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/traces/abort_assert__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/traces/abort_assert__m__test.json new file mode 100644 index 00000000000..534ad48f673 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_assert/traces/abort_assert__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999997,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999997}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999978,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999960,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999957,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999956,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Write":{"location":{"Local":[4,1]},"root_value_after_write":{"RuntimeValue":{"value":84}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999938,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,1]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999935,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999932,"instruction":"NEQ"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999931,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999928,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":9223372066919546879}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999927,"instruction":"ABORT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":9223372066919546879}}}},{"Effect":{"ExecutionError":"ABORTED"}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/Move.toml new file mode 100644 index 00000000000..603692dc444 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "abort_math" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +abort_math = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..da602d41e52a8f1ce502c74b8eccc5bca7ff8a17 GIT binary patch literal 245 zcmbtPTMEK35S&f6@zH)*C@3NxKu_SGo+OB*B_Afz#Pf*f^AaYZcmd~QXLlBcnfLBf zD*%eXlDlf7X8X%rpPLt*Ac#Tf2}y~nG!hAr1TCBGZ8X5!X=1$z?6FMyw8#(1Jwiz`0^UD@ouB4#plQ literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/source_maps/m.json new file mode 100644 index 00000000000..e087c0d10dd --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":109,"end":110},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":113,"end":167},"definition_location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":117,"end":120},"type_parameters":[],"parameters":[["p#0#0",{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":121,"end":122}]],"returns":[{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":130,"end":133}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":150,"end":151},"1":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":154,"end":156},"2":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":152,"end":153},"3":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":162,"end":165}},"is_native":false},"1":{"location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":177,"end":204},"definition_location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":181,"end":185},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":198,"end":200},"1":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":194,"end":201},"3":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":201,"end":202}},"is_native":false},"2":{"location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":90,"end":204},"definition_location":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":90,"end":204},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[163,53,45,204,110,55,138,72,189,14,193,128,247,102,17,29,112,74,91,248,154,96,248,127,5,183,134,78,27,23,112,39],"start":90,"end":204}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/sources/m.move new file mode 100644 index 00000000000..bfd33b18ea5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/build/abort_math/sources/m.move @@ -0,0 +1,13 @@ +// Test abort on an invalid math operation when continuing +// the the end of the program. +module abort_math::m; + +fun foo(p: u64): u64 { + let val = p - 43; + val +} + +#[test] +fun test() { + foo(42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/sources/m.move new file mode 100644 index 00000000000..bfd33b18ea5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/sources/m.move @@ -0,0 +1,13 @@ +// Test abort on an invalid math operation when continuing +// the the end of the program. +module abort_math::m; + +fun foo(p: u64): u64 { + let val = p - 43; + val +} + +#[test] +fun test() { + foo(42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/test.exp new file mode 100644 index 00000000000..2e30fe5759d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/test.exp @@ -0,0 +1 @@ +Exception \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/trace.spec.js new file mode 100644 index 00000000000..f3628331f8b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/trace.spec.js @@ -0,0 +1,9 @@ +const { ExecutionResult } = require('../../out/runtime'); + +let action = (runtime) => { + let res = ''; + // continue to the end of the program to get abort state + res += ExecutionResult[runtime.continue()]; + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/traces/abort_math__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/traces/abort_math__m__test.json new file mode 100644 index 00000000000..bd2166d4f8e --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_math/traces/abort_math__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999997,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999997}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999978,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999975,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":43}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999972,"instruction":"SUB"}},{"Effect":{"Pop":{"RuntimeValue":{"value":43}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/Move.toml new file mode 100644 index 00000000000..f98aed1c891 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "abort_native" +edition = "2024.beta" + +[dependencies] +Iota = { git = "https://github.com/iotaledger/iota.git", subdir = "crates/iota-framework/packages/iota-framework", rev = "framework/mainnet" } + +[addresses] +abort_native = "0x0" +Iota = "0x2" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..8ccb7be904d939374d8c34ff68c648f6fbf7ddc5 GIT binary patch literal 368 zcmbtQJ5B^K4D~0UNoESBp+IQ2L~KV#Pr)(5vYT0r#3m>SNZf%-&~q~`foFv%X?T(? z`}x_@^T*{^Zvem|blk1g73u4hy^q}|J`C@42MR4Z0w6#DLsE5;5S<6ownJc68k8YV zOss`u^n@A-9iW$xez4p9zQkHDb|r3G40S%FSZbJZ2`$z(rvpzp`>Et(czhEIkFE;) z6kASek+_#Mx0Cqnw+hdBt~r_4xNEtHjsHOW{Ry!Sz}{nz=L7dJ>VbOhiIzpOH=A29 Uo1Y7#d`JcgNG;zzVPquu2GtKPcmMzZ literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/Iota/address.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/Iota/address.json new file mode 100644 index 00000000000..d52e8c046a5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/Iota/address.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":117,"end":124},"module_name":["0000000000000000000000000000000000000000000000000000000000000002","address"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":802,"end":846},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":820,"end":827},"type_parameters":[],"parameters":[["a#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":828,"end":829}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":841,"end":845}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":983,"end":1029},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1001,"end":1010},"type_parameters":[],"parameters":[["n#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1011,"end":1012}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1021,"end":1028}],"locals":[],"nops":{},"code_map":{},"is_native":true},"2":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1140,"end":1197},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1158,"end":1168},"type_parameters":[],"parameters":[["bytes#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1169,"end":1174}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1189,"end":1196}],"locals":[],"nops":{},"code_map":{},"is_native":true},"3":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1239,"end":1308},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1250,"end":1258},"type_parameters":[],"parameters":[["a#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1259,"end":1260}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1272,"end":1282}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1303,"end":1305},"1":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1289,"end":1306}},"is_native":false},"4":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1356,"end":1460},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1367,"end":1382},"type_parameters":[],"parameters":[["a#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1383,"end":1384}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1396,"end":1409}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1437,"end":1438},"1":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1428,"end":1439},"2":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1416,"end":1440},"3":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1416,"end":1458}},"is_native":false},"5":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1502,"end":1589},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1513,"end":1522},"type_parameters":[],"parameters":[["a#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1523,"end":1524}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1536,"end":1550}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1573,"end":1574},"1":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1557,"end":1575},"2":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":1557,"end":1587}},"is_native":false},"6":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2019,"end":2393},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2030,"end":2046},"type_parameters":[],"parameters":[["bytes#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2047,"end":2052}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2068,"end":2075}],"locals":[["hex_bytes#1#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2145,"end":2154}],["hi#1#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2219,"end":2221}],["i#1#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2179,"end":2180}],["lo#1#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2262,"end":2264}]],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2090,"end":2095},"1":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2090,"end":2104},"2":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2108,"end":2110},"3":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2105,"end":2107},"4":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2082,"end":2131},"8":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2112,"end":2130},"9":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2082,"end":2131},"10":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2157,"end":2165},"11":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2141,"end":2154},"12":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2183,"end":2184},"13":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2175,"end":2180},"14":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2197,"end":2198},"15":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2201,"end":2203},"16":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2199,"end":2200},"17":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2190,"end":2364},"18":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2239,"end":2244},"19":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2245,"end":2246},"20":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2239,"end":2247},"22":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2224,"end":2248},"23":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2219,"end":2221},"24":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2282,"end":2287},"25":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2288,"end":2289},"26":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2290,"end":2291},"27":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2289,"end":2290},"28":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2282,"end":2292},"30":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2267,"end":2293},"31":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2262,"end":2264},"32":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2303,"end":2312},"33":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2324,"end":2326},"34":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2330,"end":2331},"35":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2327,"end":2329},"36":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2335,"end":2337},"37":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2333,"end":2334},"38":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2303,"end":2338},"39":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2352,"end":2353},"40":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2356,"end":2357},"41":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2354,"end":2355},"42":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2348,"end":2349},"43":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2190,"end":2364},"44":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2370,"end":2391},"46":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2381,"end":2390},"47":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2370,"end":2391}},"is_native":false},"7":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2395,"end":2599},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2399,"end":2413},"type_parameters":[],"parameters":[["c#0#0",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2414,"end":2415}]],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2422,"end":2424}],"locals":[["%#1",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2435,"end":2453}],["%#2",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2482,"end":2500}],["%#3",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2529,"end":2548}],["%#5",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2478,"end":2597}],["%#6",{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2431,"end":2597}]],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2435,"end":2436},"1":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2440,"end":2442},"2":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2437,"end":2439},"3":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2435,"end":2453},"4":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2446,"end":2447},"5":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2451,"end":2453},"6":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2448,"end":2450},"7":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2435,"end":2453},"12":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2431,"end":2597},"13":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2455,"end":2456},"14":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2459,"end":2461},"15":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2457,"end":2458},"16":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2431,"end":2597},"18":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2482,"end":2483},"19":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2487,"end":2489},"20":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2484,"end":2486},"21":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2482,"end":2500},"22":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2493,"end":2494},"23":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2498,"end":2500},"24":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2495,"end":2497},"25":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2482,"end":2500},"30":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2478,"end":2597},"31":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2502,"end":2503},"32":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2506,"end":2508},"33":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2504,"end":2505},"34":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2478,"end":2597},"36":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2529,"end":2530},"37":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2534,"end":2536},"38":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2531,"end":2533},"39":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2529,"end":2548},"40":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2540,"end":2541},"41":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2545,"end":2548},"42":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2542,"end":2544},"43":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2529,"end":2548},"48":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2525,"end":2597},"50":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2579,"end":2597},"51":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2573,"end":2597},"52":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2550,"end":2551},"53":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2554,"end":2556},"54":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2552,"end":2553},"55":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2478,"end":2597},"57":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2431,"end":2597}},"is_native":false},"8":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2638,"end":2677},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2649,"end":2655},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2659,"end":2662}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2669,"end":2675}},"is_native":false},"9":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2708,"end":2742},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2719,"end":2722},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2726,"end":2730}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":2737,"end":2740}},"is_native":false},"10":{"location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":105,"end":2742},"definition_location":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":105,"end":2742},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[121,232,100,12,1,50,55,8,252,100,0,207,134,199,220,27,227,9,197,116,194,4,73,229,246,118,92,127,20,158,39,14],"start":105,"end":2742}},"is_native":false}},"constant_map":{"EAddressParseError":2,"LENGTH":0,"MAX":1}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/MoveStdlib/vector.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/MoveStdlib/vector.json new file mode 100644 index 00000000000..c3f7f3e6979 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/dependencies/MoveStdlib/vector.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":261,"end":267},"module_name":["0000000000000000000000000000000000000000000000000000000000000001","vector"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1124,"end":1176},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1142,"end":1147},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1148,"end":1155}]],"parameters":[],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1160,"end":1175}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1239,"end":1299},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1257,"end":1263},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1264,"end":1271}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1273,"end":1274}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1295,"end":1298}],"locals":[],"nops":{},"code_map":{},"is_native":true},"2":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1453,"end":1526},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1471,"end":1477},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1478,"end":1485}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1487,"end":1488}],["i#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1508,"end":1509}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1517,"end":1525}],"locals":[],"nops":{},"code_map":{},"is_native":true},"3":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1602,"end":1676},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1620,"end":1629},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1630,"end":1637}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1639,"end":1640}],["e#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1664,"end":1665}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"4":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1826,"end":1911},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1844,"end":1854},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1855,"end":1862}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1864,"end":1865}],["i#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1889,"end":1890}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":1898,"end":1910}],"locals":[],"nops":{},"code_map":{},"is_native":true},"5":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2012,"end":2082},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2030,"end":2038},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2039,"end":2046}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2048,"end":2049}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2074,"end":2081}],"locals":[],"nops":{},"code_map":{},"is_native":true},"6":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2168,"end":2229},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2186,"end":2199},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2200,"end":2207}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2209,"end":2210}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"7":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2371,"end":2444},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2389,"end":2393},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2394,"end":2401}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2403,"end":2404}],["i#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2428,"end":2429}],["j#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2436,"end":2437}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"8":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2503,"end":2616},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2514,"end":2523},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2524,"end":2531}]],"parameters":[["e#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2533,"end":2534}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2546,"end":2561}],"locals":[["v#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2576,"end":2577}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2580,"end":2587},"1":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2572,"end":2577},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2593,"end":2594},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2605,"end":2606},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2593,"end":2607},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2613,"end":2614}},"is_native":false},"9":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2685,"end":3022},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2696,"end":2703},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2704,"end":2711}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2713,"end":2714}]],"returns":[],"locals":[["back_index#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2837,"end":2847}],["front_index#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2808,"end":2819}],["len#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2748,"end":2751}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2754,"end":2755},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2754,"end":2764},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2748,"end":2751},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2774,"end":2777},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2781,"end":2782},"6":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2778,"end":2780},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2770,"end":2793},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2784,"end":2793},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2822,"end":2823},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2804,"end":2819},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2850,"end":2853},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2856,"end":2857},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2854,"end":2855},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2833,"end":2847},"17":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2870,"end":2881},"18":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2884,"end":2894},"19":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2882,"end":2883},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2863,"end":3020},"21":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2906,"end":2907},"22":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2913,"end":2924},"23":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2926,"end":2936},"24":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2906,"end":2937},"25":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2961,"end":2972},"26":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2975,"end":2976},"27":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2973,"end":2974},"28":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2947,"end":2958},"29":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2999,"end":3009},"30":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3012,"end":3013},"31":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3010,"end":3011},"32":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2986,"end":2996},"33":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":2863,"end":3020}},"is_native":false},"10":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3100,"end":3296},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3111,"end":3117},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3118,"end":3125}]],"parameters":[["lhs#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3127,"end":3130}],["other#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3158,"end":3163}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3188,"end":3193},"1":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3188,"end":3203},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3217,"end":3222},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3217,"end":3233},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3216,"end":3217},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3209,"end":3266},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3235,"end":3238},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3249,"end":3254},"9":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3249,"end":3265},"10":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3235,"end":3266},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3209,"end":3266},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3272,"end":3293},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3272,"end":3277},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3272,"end":3293},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3293,"end":3294}},"is_native":false},"11":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3373,"end":3452},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3384,"end":3392},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3393,"end":3400}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3402,"end":3403}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3424,"end":3428}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3435,"end":3436},"1":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3435,"end":3445},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3449,"end":3450},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3446,"end":3448},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3435,"end":3450}},"is_native":false},"12":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3529,"end":3741},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3540,"end":3548},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3549,"end":3556}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3558,"end":3559}],["e#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3579,"end":3580}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3593,"end":3597}],"locals":[["i#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3612,"end":3613}],["len#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3627,"end":3630}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3616,"end":3617},"1":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3608,"end":3613},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3633,"end":3634},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3633,"end":3643},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3627,"end":3630},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3656,"end":3657},"6":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3660,"end":3663},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3658,"end":3659},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3649,"end":3728},"10":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3680,"end":3681},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3682,"end":3683},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3679,"end":3684},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3688,"end":3689},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3685,"end":3687},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3675,"end":3702},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3691,"end":3702},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3698,"end":3702},"21":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3691,"end":3702},"22":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3716,"end":3717},"23":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3720,"end":3721},"24":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3718,"end":3719},"25":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3712,"end":3713},"26":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3649,"end":3728},"27":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3734,"end":3739}},"is_native":false},"13":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3845,"end":4074},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3856,"end":3864},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3865,"end":3872}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3874,"end":3875}],["e#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3895,"end":3896}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3910,"end":3914},{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3916,"end":3919}],"locals":[["i#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3935,"end":3936}],["len#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3950,"end":3953}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3939,"end":3940},"1":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3931,"end":3936},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3956,"end":3957},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3956,"end":3966},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3950,"end":3953},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3979,"end":3980},"6":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3983,"end":3986},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3981,"end":3982},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3972,"end":4056},"10":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4003,"end":4004},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4005,"end":4006},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4002,"end":4007},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4011,"end":4012},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4008,"end":4010},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3998,"end":4030},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4014,"end":4030},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4022,"end":4026},"21":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4028,"end":4029},"22":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4014,"end":4030},"23":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4044,"end":4045},"24":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4048,"end":4049},"25":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4046,"end":4047},"26":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4040,"end":4041},"27":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":3972,"end":4056},"28":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4062,"end":4072},"32":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4063,"end":4068},"33":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4070,"end":4071},"34":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4062,"end":4072}},"is_native":false},"14":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4261,"end":4549},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4272,"end":4278},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4279,"end":4286}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4288,"end":4289}],["i#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4317,"end":4318}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4326,"end":4333}],"locals":[["%#1",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4489,"end":4490}],["%#2",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4482,"end":4483}],["len#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4348,"end":4351}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4354,"end":4355},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4354,"end":4364},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4344,"end":4351},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4404,"end":4405},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4409,"end":4412},"6":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4406,"end":4408},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4400,"end":4440},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4414,"end":4440},"10":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4420,"end":4440},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4414,"end":4440},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4453,"end":4456},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4459,"end":4460},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4457,"end":4458},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4447,"end":4450},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4473,"end":4474},"17":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4477,"end":4480},"18":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4475,"end":4476},"19":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4466,"end":4529},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4482,"end":4483},"22":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4489,"end":4490},"24":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4506,"end":4507},"25":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4510,"end":4511},"26":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4508,"end":4509},"27":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4502,"end":4503},"28":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4482,"end":4483},"29":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4489,"end":4490},"30":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4521,"end":4522},"31":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4482,"end":4529},"32":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4466,"end":4529},"33":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4535,"end":4536},"34":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4535,"end":4547}},"is_native":false},"15":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4859,"end":5123},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4870,"end":4876},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4877,"end":4884}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4886,"end":4887}],["e#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4911,"end":4912}],["i#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4927,"end":4928}]],"returns":[],"locals":[["len#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4945,"end":4948}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4951,"end":4952},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4951,"end":4961},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4945,"end":4948},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4994,"end":4995},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4998,"end":5001},"6":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4996,"end":4997},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":4990,"end":5029},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5003,"end":5029},"10":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5009,"end":5029},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5003,"end":5029},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5036,"end":5037},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5048,"end":5049},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5036,"end":5050},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5063,"end":5064},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5067,"end":5070},"17":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5065,"end":5066},"18":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5056,"end":5121},"19":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5082,"end":5083},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5089,"end":5090},"21":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5092,"end":5095},"22":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5082,"end":5096},"23":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5110,"end":5111},"24":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5114,"end":5115},"25":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5112,"end":5113},"26":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5106,"end":5107},"27":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5056,"end":5121}},"is_native":false},"16":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5329,"end":5533},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5340,"end":5351},"type_parameters":[["Element",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5352,"end":5359}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5361,"end":5362}],["i#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5386,"end":5387}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5395,"end":5402}],"locals":[["last_idx#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5463,"end":5471}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5418,"end":5419},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5418,"end":5430},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5417,"end":5418},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5409,"end":5453},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5432,"end":5452},"9":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5409,"end":5453},"10":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5474,"end":5475},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5474,"end":5484},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5487,"end":5488},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5485,"end":5486},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5463,"end":5471},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5494,"end":5495},"17":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5501,"end":5502},"18":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5504,"end":5512},"19":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5494,"end":5513},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5519,"end":5520},"21":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":5519,"end":5531}},"is_native":false},"17":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9433,"end":9551},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9444,"end":9451},"type_parameters":[["T",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9452,"end":9453}]],"parameters":[["v#0#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9455,"end":9456}]],"returns":[{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9478,"end":9487}],"locals":[["r#1#0",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9502,"end":9503}],["u#1#2",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9527,"end":9528}],["v#1#1",{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6324,"end":6325}]],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9506,"end":9514},"1":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9498,"end":9503},"2":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9520,"end":9521},"3":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6320,"end":6325},"4":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6336,"end":6337},"5":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6336,"end":6347},"6":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6361,"end":6362},"7":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6361,"end":6373},"8":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6360,"end":6361},"9":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6353,"end":6391},"11":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6378,"end":6379},"12":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6378,"end":6390},"13":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9527,"end":9528},"14":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9530,"end":9531},"15":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9539,"end":9540},"16":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9530,"end":9541},"18":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6397,"end":6398},"19":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":6397,"end":6414},"20":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":9548,"end":9549}},"is_native":false},"18":{"location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":249,"end":12967},"definition_location":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":249,"end":12967},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[175,73,72,11,111,41,34,114,136,84,224,14,175,157,133,212,23,85,163,43,96,82,188,181,140,168,72,17,252,116,121,48],"start":249,"end":12967}},"is_native":false}},"constant_map":{"EINDEX_OUT_OF_BOUNDS":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/m.json new file mode 100644 index 00000000000..35c782bde4a --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":168,"end":169},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":172,"end":303},"definition_location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":176,"end":179},"type_parameters":[],"parameters":[["v#0#0",{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":180,"end":181}],["p#0#0",{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":195,"end":196}]],"returns":[{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":205,"end":208},{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":210,"end":217}],"locals":[["addr#1#0",{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":250,"end":254}],["val#1#0",{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":229,"end":232}]],"nops":{},"code_map":{"0":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":235,"end":236},"1":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":239,"end":240},"2":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":237,"end":238},"3":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":229,"end":232},"4":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":282,"end":283},"5":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":257,"end":284},"6":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":250,"end":254},"7":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":291,"end":294},"8":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":296,"end":300},"9":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":290,"end":301}},"is_native":false},"1":{"location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":313,"end":363},"definition_location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":317,"end":321},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":352,"end":354},"1":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":334,"end":355},"2":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":357,"end":359},"3":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":330,"end":360},"6":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":360,"end":361}},"is_native":false},"2":{"location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":147,"end":363},"definition_location":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":147,"end":363},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[57,183,107,225,240,52,116,228,84,241,116,170,33,69,63,92,184,20,95,216,175,56,87,163,157,86,119,65,26,67,22,113],"start":147,"end":363}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/Iota/address.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/Iota/address.move new file mode 100644 index 00000000000..cd0e93d668c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/Iota/address.move @@ -0,0 +1,87 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(address)] +module iota::address; + +use std::ascii; +use std::bcs; +use std::string; +use iota::hex; + +/// Allows calling `.to_id()` on an address to get its `ID`. +public use fun iota::object::id_from_address as address.to_id; + +/// The length of an address, in bytes +const LENGTH: u64 = 32; + +// The largest integer that can be represented with 32 bytes: 2^(8*32) - 1 +const MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + +#[allow(unused_const)] +/// Error from `from_bytes` when it is supplied too many or too few bytes. +const EAddressParseError: u64 = 0; + +/// Convert `a` into a u256 by interpreting `a` as the bytes of a big-endian integer +/// (e.g., `to_u256(0x1) == 1`) +public native fun to_u256(a: address): u256; + +/// Convert `n` into an address by encoding it as a big-endian integer (e.g., `from_u256(1) = @0x1`) +/// Aborts if `n` > `MAX_ADDRESS` +public native fun from_u256(n: u256): address; + +/// Convert `bytes` into an address. +/// Aborts with `EAddressParseError` if the length of `bytes` is not 32 +public native fun from_bytes(bytes: vector): address; + +/// Convert `a` into BCS-encoded bytes. +public fun to_bytes(a: address): vector { + bcs::to_bytes(&a) +} + +/// Convert `a` to a hex-encoded ASCII string +public fun to_ascii_string(a: address): ascii::String { + hex::encode(to_bytes(a)).to_ascii_string() +} + +/// Convert `a` to a hex-encoded string +public fun to_string(a: address): string::String { + to_ascii_string(a).to_string() +} + +/// Converts an ASCII string to an address, taking the numerical value for each character. The +/// string must be Base16 encoded, and thus exactly 64 characters long. +/// For example, the string "00000000000000000000000000000000000000000000000000000000DEADB33F" +/// will be converted to the address @0xDEADB33F. +/// Aborts with `EAddressParseError` if the length of `s` is not 64, +/// or if an invalid character is encountered. +public fun from_ascii_bytes(bytes: &vector): address { + assert!(bytes.length() == 64, EAddressParseError); + let mut hex_bytes = vector[]; + let mut i = 0; + while (i < 64) { + let hi = hex_char_value(bytes[i]); + let lo = hex_char_value(bytes[i+1]); + hex_bytes.push_back((hi << 4) | lo); + i = i + 2; + }; + from_bytes(hex_bytes) +} + +fun hex_char_value(c: u8): u8 { + if (c >= 48 && c <= 57) c - 48 // 0-9 + else if (c >= 65 && c <= 70) c - 55 // A-F + else if (c >= 97 && c <= 102) c - 87 // a-f + else abort EAddressParseError +} + +/// Length of a Iota address in bytes +public fun length(): u64 { + LENGTH +} + +/// Largest possible address +public fun max(): u256 { + MAX +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/MoveStdlib/vector.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/MoveStdlib/vector.move new file mode 100644 index 00000000000..64d7bdacba4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/dependencies/MoveStdlib/vector.move @@ -0,0 +1,375 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(vector)] +/// A variable-sized container that can hold any type. Indexing is 0-based, and +/// vectors are growable. This module has many native functions. +module std::vector; + +/// Allows calling `.to_string()` on a vector of `u8` to get a utf8 `String`. +public use fun std::string::utf8 as vector.to_string; + +/// Allows calling `.try_to_string()` on a vector of `u8` to get a utf8 `String`. +/// This will return `None` if the vector is not valid utf8. +public use fun std::string::try_utf8 as vector.try_to_string; + +/// Allows calling `.to_ascii_string()` on a vector of `u8` to get an `ascii::String`. +public use fun std::ascii::string as vector.to_ascii_string; + +/// Allows calling `.try_to_ascii_string()` on a vector of `u8` to get an +/// `ascii::String`. This will return `None` if the vector is not valid ascii. +public use fun std::ascii::try_string as vector.try_to_ascii_string; + +/// The index into the vector is out of bounds +const EINDEX_OUT_OF_BOUNDS: u64 = 0x20000; + +#[bytecode_instruction] +/// Create an empty vector. +public native fun empty(): vector; + +#[bytecode_instruction] +/// Return the length of the vector. +public native fun length(v: &vector): u64; + +#[syntax(index)] +#[bytecode_instruction] +/// Acquire an immutable reference to the `i`th element of the vector `v`. +/// Aborts if `i` is out of bounds. +public native fun borrow(v: &vector, i: u64): ∈ + +#[bytecode_instruction] +/// Add element `e` to the end of the vector `v`. +public native fun push_back(v: &mut vector, e: Element); + +#[syntax(index)] +#[bytecode_instruction] +/// Return a mutable reference to the `i`th element in the vector `v`. +/// Aborts if `i` is out of bounds. +public native fun borrow_mut(v: &mut vector, i: u64): &mut Element; + +#[bytecode_instruction] +/// Pop an element from the end of vector `v`. +/// Aborts if `v` is empty. +public native fun pop_back(v: &mut vector): Element; + +#[bytecode_instruction] +/// Destroy the vector `v`. +/// Aborts if `v` is not empty. +public native fun destroy_empty(v: vector); + +#[bytecode_instruction] +/// Swaps the elements at the `i`th and `j`th indices in the vector `v`. +/// Aborts if `i` or `j` is out of bounds. +public native fun swap(v: &mut vector, i: u64, j: u64); + +/// Return an vector of size one containing element `e`. +public fun singleton(e: Element): vector { + let mut v = empty(); + v.push_back(e); + v +} + +/// Reverses the order of the elements in the vector `v` in place. +public fun reverse(v: &mut vector) { + let len = v.length(); + if (len == 0) return (); + + let mut front_index = 0; + let mut back_index = len - 1; + while (front_index < back_index) { + v.swap(front_index, back_index); + front_index = front_index + 1; + back_index = back_index - 1; + } +} + +/// Pushes all of the elements of the `other` vector into the `lhs` vector. +public fun append(lhs: &mut vector, mut other: vector) { + other.reverse(); + while (!other.is_empty()) lhs.push_back(other.pop_back()); + other.destroy_empty(); +} + +/// Return `true` if the vector `v` has no elements and `false` otherwise. +public fun is_empty(v: &vector): bool { + v.length() == 0 +} + +/// Return true if `e` is in the vector `v`. +/// Otherwise, returns false. +public fun contains(v: &vector, e: &Element): bool { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return true; + i = i + 1; + }; + false +} + +/// Return `(true, i)` if `e` is in the vector `v` at index `i`. +/// Otherwise, returns `(false, 0)`. +public fun index_of(v: &vector, e: &Element): (bool, u64) { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return (true, i); + i = i + 1; + }; + (false, 0) +} + +/// Remove the `i`th element of the vector `v`, shifting all subsequent elements. +/// This is O(n) and preserves ordering of elements in the vector. +/// Aborts if `i` is out of bounds. +public fun remove(v: &mut vector, mut i: u64): Element { + let mut len = v.length(); + // i out of bounds; abort + if (i >= len) abort EINDEX_OUT_OF_BOUNDS; + + len = len - 1; + while (i < len) v.swap(i, { + i = i + 1; + i + }); + v.pop_back() +} + +/// Insert `e` at position `i` in the vector `v`. +/// If `i` is in bounds, this shifts the old `v[i]` and all subsequent elements to the right. +/// If `i == v.length()`, this adds `e` to the end of the vector. +/// This is O(n) and preserves ordering of elements in the vector. +/// Aborts if `i > v.length()` +public fun insert(v: &mut vector, e: Element, mut i: u64) { + let len = v.length(); + // i too big abort + if (i > len) abort EINDEX_OUT_OF_BOUNDS; + + v.push_back(e); + while (i < len) { + v.swap(i, len); + i = i + 1 + } +} + +/// Swap the `i`th element of the vector `v` with the last element and then pop the vector. +/// This is O(1), but does not preserve ordering of elements in the vector. +/// Aborts if `i` is out of bounds. +public fun swap_remove(v: &mut vector, i: u64): Element { + assert!(!v.is_empty(), EINDEX_OUT_OF_BOUNDS); + let last_idx = v.length() - 1; + v.swap(i, last_idx); + v.pop_back() +} + +// === Macros === + +/// Create a vector of length `n` by calling the function `f` on each index. +public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> { + let mut v = vector[]; + let n = $n; + n.do!(|i| v.push_back($f(i))); + v +} + +/// Destroy the vector `v` by calling `f` on each element and then destroying the vector. +/// Does not preserve the order of elements in the vector (starts from the end of the vector). +public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); +} + +/// Destroy the vector `v` by calling `f` on each element and then destroying the vector. +/// Preserves the order of elements in the vector. +public macro fun do<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); +} + +/// Perform an action `f` on each element of the vector `v`. The vector is not modified. +public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) { + let v = $v; + v.length().do!(|i| $f(&v[i])) +} + +/// Perform an action `f` on each element of the vector `v`. +/// The function `f` takes a mutable reference to the element. +public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) { + let v = $v; + v.length().do!(|i| $f(&mut v[i])) +} + +/// Map the vector `v` to a new vector by applying the function `f` to each element. +/// Preserves the order of elements in the vector, first is called first. +public macro fun map<$T, $U>($v: vector<$T>, $f: |$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do!(|e| r.push_back($f(e))); + r +} + +/// Map the vector `v` to a new vector by applying the function `f` to each element. +/// Preserves the order of elements in the vector, first is called first. +public macro fun map_ref<$T, $U>($v: &vector<$T>, $f: |&$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do_ref!(|e| r.push_back($f(e))); + r +} + +/// Filter the vector `v` by applying the function `f` to each element. +/// Return a new vector containing only the elements for which `f` returns `true`. +public macro fun filter<$T: drop>($v: vector<$T>, $f: |&$T| -> bool): vector<$T> { + let v = $v; + let mut r = vector[]; + v.do!(|e| if ($f(&e)) r.push_back(e)); + r +} + +/// Split the vector `v` into two vectors by applying the function `f` to each element. +/// Return a tuple containing two vectors: the first containing the elements for which `f` returns `true`, +/// and the second containing the elements for which `f` returns `false`. +public macro fun partition<$T>($v: vector<$T>, $f: |&$T| -> bool): (vector<$T>, vector<$T>) { + let v = $v; + let mut r1 = vector[]; + let mut r2 = vector[]; + v.do!(|e| if ($f(&e)) r1.push_back(e) else r2.push_back(e)); + (r1, r2) +} + +/// Finds the index of first element in the vector `v` that satisfies the predicate `f`. +/// Returns `some(index)` if such an element is found, otherwise `none()`. +public macro fun find_index<$T>($v: &vector<$T>, $f: |&$T| -> bool): Option { + let v = $v; + 'find_index: { + v.length().do!(|i| if ($f(&v[i])) return 'find_index option::some(i)); + option::none() + } +} + +/// Count how many elements in the vector `v` satisfy the predicate `f`. +public macro fun count<$T>($v: &vector<$T>, $f: |&$T| -> bool): u64 { + let v = $v; + let mut count = 0; + v.do_ref!(|e| if ($f(e)) count = count + 1); + count +} + +/// Reduce the vector `v` to a single value by applying the function `f` to each element. +/// Similar to `fold_left` in Rust and `reduce` in Python and JavaScript. +public macro fun fold<$T, $Acc>($v: vector<$T>, $init: $Acc, $f: |$Acc, $T| -> $Acc): $Acc { + let v = $v; + let mut acc = $init; + v.do!(|e| acc = $f(acc, e)); + acc +} + +/// Concatenate the vectors of `v` into a single vector, keeping the order of the elements. +public fun flatten(v: vector>): vector { + let mut r = vector[]; + v.do!(|u| r.append(u)); + r +} + +/// Whether any element in the vector `v` satisfies the predicate `f`. +/// If the vector is empty, returns `false`. +public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'any: { + v.do_ref!(|e| if ($f(e)) return 'any true); + false + } +} + +/// Whether all elements in the vector `v` satisfy the predicate `f`. +/// If the vector is empty, returns `true`. +public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'all: { + v.do_ref!(|e| if (!$f(e)) return 'all false); + true + } +} + +/// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. +/// Aborts if the vectors are not of the same length. +/// The order of elements in the vectors is preserved. +public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + v2.reverse(); + let len = v1.length(); + assert!(len == v2.length()); + v1.do!(|el1| $f(el1, v2.pop_back())); +} + +/// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. +/// Aborts if the vectors are not of the same length. +/// Starts from the end of the vectors. +public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + v1.destroy!(|el1| $f(el1, v2.pop_back())); +} + +/// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of +/// elements. The vectors are not modified. +/// Aborts if the vectors are not of the same length. +/// The order of elements in the vectors is preserved. +public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&v1[i], &v2[i])); +} + +/// Iterate through `v1` and `v2` and apply the function `f` to mutable references of each pair +/// of elements. The vectors may be modified. +/// Aborts if the vectors are not of the same length. +/// The order of elements in the vectors is preserved. +public macro fun zip_do_mut<$T1, $T2>( + $v1: &mut vector<$T1>, + $v2: &mut vector<$T2>, + $f: |&mut $T1, &mut $T2|, +) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&mut v1[i], &mut v2[i])); +} + +/// Destroys two vectors `v1` and `v2` by applying the function `f` to each pair of elements. +/// The returned values are collected into a new vector. +/// Aborts if the vectors are not of the same length. +/// The order of elements in the vectors is preserved. +public macro fun zip_map<$T1, $T2, $U>( + $v1: vector<$T1>, + $v2: vector<$T2>, + $f: |$T1, $T2| -> $U, +): vector<$U> { + let mut r = vector[]; + zip_do!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r +} + +/// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of +/// elements. The returned values are collected into a new vector. +/// Aborts if the vectors are not of the same length. +/// The order of elements in the vectors is preserved. +public macro fun zip_map_ref<$T1, $T2, $U>( + $v1: &vector<$T1>, + $v2: &vector<$T2>, + $f: |&$T1, &$T2| -> $U, +): vector<$U> { + let mut r = vector[]; + zip_do_ref!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/m.move new file mode 100644 index 00000000000..f2ea7744224 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/build/abort_native/sources/m.move @@ -0,0 +1,15 @@ +// Test abort on an a native function when stepping out +// of a function containing the native call (before this +// call is stepped into or over). +module abort_native::m; + +fun foo(v: vector, p: u64): (u64, address) { + let val = p + p; + let addr = iota::address::from_bytes(v); + (val, addr) +} + +#[test] +fun test() { + foo(vector::singleton(42), 42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/sources/m.move new file mode 100644 index 00000000000..f2ea7744224 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/sources/m.move @@ -0,0 +1,15 @@ +// Test abort on an a native function when stepping out +// of a function containing the native call (before this +// call is stepped into or over). +module abort_native::m; + +fun foo(v: vector, p: u64): (u64, address) { + let val = p + p; + let addr = iota::address::from_bytes(v); + (val, addr) +} + +#[test] +fun test() { + foo(vector::singleton(42), 42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/test.exp new file mode 100644 index 00000000000..2e30fe5759d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/test.exp @@ -0,0 +1 @@ +Exception \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/trace.spec.js new file mode 100644 index 00000000000..fe54e007ca4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/trace.spec.js @@ -0,0 +1,17 @@ +const { run } = require('node:test'); +const { ExecutionResult } = require('../../out/runtime'); + +let action = (runtime) => { + let res = ''; + // step into function creating a vector + runtime.step(false); + // step out of a function creating a vector + runtime.stepOut(); + // step into function containing native call + runtime.step(false); + // step out of a function containing native call + // before this call is executed + res += ExecutionResult[runtime.stepOut()]; + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/traces/abort_native__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/traces/abort_native__m__test.json new file mode 100644 index 00000000000..9883665f200 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native/traces/abort_native__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_U8"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999997,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":["u8"],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":{"vector":"u8"},"ref_type":null}],"locals_types":[{"type_":"u8","ref_type":null},{"type_":{"vector":"u8"},"ref_type":null}],"is_native":false},"gas_left":999999997}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999986,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999985,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[4,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999975,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[4,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999957,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999956,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[4,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[4,1]},"root_value_after_write":{"RuntimeValue":{"value":[42]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999953,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,1]},"root_value_read":{"RuntimeValue":{"value":[42]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[42]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999952,"instruction":"RET"}},{"CloseFrame":{"frame_id":4,"return_":[{"RuntimeValue":{"value":[42]}}],"gas_left":999999952}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999949,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999949,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":28,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[42]}},{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null},{"type_":"address","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u64","ref_type":null},{"type_":"address","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999949}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999930,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999912,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999909,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999908,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Write":{"location":{"Local":[28,3]},"root_value_after_write":{"RuntimeValue":{"value":84}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999905,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,0]},"root_value_read":{"RuntimeValue":{"value":[42]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[42]}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999905,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":46,"function_name":"from_bytes","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"address"},"binary_member_index":2,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[42]}}],"return_types":[{"type_":"address","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null}],"is_native":true},"gas_left":999999905}},{"Effect":{"ExecutionError":"ABORTED"}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/Move.toml new file mode 100644 index 00000000000..2dafdff7df0 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "abort_native_bytecode" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +abort_native_bytecode = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..b8cf16cab0debbc666664fbb6501633f9e6a73a0 GIT binary patch literal 251 zcmbtPK?=e!5S-nl)oKw7J&1VmA0Db72`XvH!9iP1TF w$gG-|HL>{Hxl>PPg0t!HKS-YeTy2mO6kMq1?6MrnFq<8Sa}t*GS|^C{1DEt3cmMzZ literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/dependencies/MoveStdlib/vector.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/dependencies/MoveStdlib/vector.json new file mode 100644 index 00000000000..9d5a13fdd3b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/dependencies/MoveStdlib/vector.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":261,"end":267},"module_name":["0000000000000000000000000000000000000000000000000000000000000001","vector"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1184,"end":1236},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1202,"end":1207},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1208,"end":1215}]],"parameters":[],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1220,"end":1235}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1311,"end":1371},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1329,"end":1335},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1336,"end":1343}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1345,"end":1346}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1367,"end":1370}],"locals":[],"nops":{},"code_map":{},"is_native":true},"2":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1545,"end":1618},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1563,"end":1569},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1570,"end":1577}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1579,"end":1580}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1600,"end":1601}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1609,"end":1617}],"locals":[],"nops":{},"code_map":{},"is_native":true},"3":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1706,"end":1780},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1724,"end":1733},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1734,"end":1741}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1743,"end":1744}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1768,"end":1769}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"4":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1950,"end":2035},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1968,"end":1978},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1979,"end":1986}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1988,"end":1989}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2013,"end":2014}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2022,"end":2034}],"locals":[],"nops":{},"code_map":{},"is_native":true},"5":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2152,"end":2222},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2170,"end":2178},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2179,"end":2186}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2188,"end":2189}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2214,"end":2221}],"locals":[],"nops":{},"code_map":{},"is_native":true},"6":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2324,"end":2385},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2342,"end":2355},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2356,"end":2363}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2365,"end":2366}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"7":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2543,"end":2616},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2561,"end":2565},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2566,"end":2573}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2575,"end":2576}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2600,"end":2601}],["j#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2608,"end":2609}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"8":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2683,"end":2812},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2694,"end":2703},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2704,"end":2711}]],"parameters":[["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2713,"end":2714}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2726,"end":2741}],"locals":[["v#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2760,"end":2761}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2764,"end":2771},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2756,"end":2761},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2782},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2793,"end":2794},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2795},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2805,"end":2806}},"is_native":false},"9":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2889,"end":3266},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2900,"end":2907},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2908,"end":2915}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2917,"end":2918}]],"returns":[],"locals":[["back_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3057,"end":3067}],["front_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3024,"end":3035}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2963},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2972},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2986,"end":2989},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2993,"end":2994},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2990,"end":2992},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2982,"end":3005},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2996,"end":3005},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3038,"end":3039},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3020,"end":3035},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3070,"end":3073},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3076,"end":3077},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3074,"end":3075},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3053,"end":3067},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3094,"end":3105},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3108,"end":3118},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3106,"end":3107},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3135},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3141,"end":3152},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3154,"end":3164},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3165},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3193,"end":3204},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3207,"end":3208},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3205,"end":3206},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3179,"end":3190},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3235,"end":3245},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3248,"end":3249},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3246,"end":3247},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3222,"end":3232},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260}},"is_native":false},"10":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3352,"end":3564},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3363,"end":3369},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3370,"end":3377}]],"parameters":[["lhs#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3379,"end":3382}],["other#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3410,"end":3415}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3449},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3459},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3482},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3493},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3476,"end":3477},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3498},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3514},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3525},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3526},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3541},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3557,"end":3558}},"is_native":false},"11":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3649,"end":3736},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3660,"end":3668},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3669,"end":3676}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3678,"end":3679}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3700,"end":3704}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3716},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3725},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3729,"end":3730},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3726,"end":3728},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3730}},"is_native":false},"12":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3825,"end":4069},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3836,"end":3844},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3845,"end":3852}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3854,"end":3855}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3875,"end":3876}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3889,"end":3893}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3912,"end":3913}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3916,"end":3917},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3908,"end":3913},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3938},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3947},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3964,"end":3965},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3968,"end":3971},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3966,"end":3967},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3992,"end":3993},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3994,"end":3995},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3991,"end":3996},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4000,"end":4001},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3997,"end":3999},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3987,"end":4014},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4010,"end":4014},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4032,"end":4033},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4036,"end":4037},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4034,"end":4035},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4028,"end":4029},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4058,"end":4063}},"is_native":false},"13":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4185,"end":4446},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4196,"end":4204},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4205,"end":4212}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4214,"end":4215}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4235,"end":4236}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4250,"end":4254},{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4256,"end":4259}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4279,"end":4280}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4283,"end":4284},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4275,"end":4280},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4305},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4314},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4331,"end":4332},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4335,"end":4338},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4333,"end":4334},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4359,"end":4360},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4361,"end":4362},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4358,"end":4363},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4367,"end":4368},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4364,"end":4366},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4354,"end":4386},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4378,"end":4382},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4384,"end":4385},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4404,"end":4405},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4408,"end":4409},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4406,"end":4407},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4400,"end":4401},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4431,"end":4436},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4438,"end":4439},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440}},"is_native":false},"14":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4649,"end":4945},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4660,"end":4666},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4667,"end":4674}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4676,"end":4677}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4705,"end":4706}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4714,"end":4721}],"locals":[["%#1",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898}],["%#2",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4740,"end":4743}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4747},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4756},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4736,"end":4743},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4804,"end":4805},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4809,"end":4812},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4806,"end":4808},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4800,"end":4840},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4820,"end":4840},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4857,"end":4860},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4863,"end":4864},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4861,"end":4862},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4851,"end":4854},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4881,"end":4882},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4885,"end":4888},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4883,"end":4884},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4906,"end":4907},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4910,"end":4911},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4908,"end":4909},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4902,"end":4903},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4913,"end":4914},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4917},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4928},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4939}},"is_native":false},"15":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5279,"end":5579},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5290,"end":5296},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5297,"end":5304}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5306,"end":5307}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5331,"end":5332}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5347,"end":5348}]],"returns":[],"locals":[["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5376},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5385},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5426,"end":5427},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5430,"end":5433},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5428,"end":5429},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5422,"end":5461},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5441,"end":5461},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5473},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5484,"end":5485},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5486},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5503,"end":5504},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5507,"end":5510},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5505,"end":5506},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5527},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5533,"end":5534},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5536,"end":5539},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5540},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5558,"end":5559},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5562,"end":5563},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5560,"end":5561},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5554,"end":5555},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573}},"is_native":false},"16":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5801,"end":6025},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5812,"end":5823},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5824,"end":5831}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5833,"end":5834}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5858,"end":5859}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5867,"end":5874}],"locals":[["last_idx#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5895},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5906},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5893,"end":5894},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5908,"end":5928},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5955},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5964},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5967,"end":5968},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5965,"end":5966},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5979},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5985,"end":5986},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5988,"end":5996},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5997},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6008},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6019}},"is_native":false},"17":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981}},"is_native":false}},"constant_map":{"EINDEX_OUT_OF_BOUNDS":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/m.json new file mode 100644 index 00000000000..007ef04a3a3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":163,"end":164},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":167,"end":235},"definition_location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":171,"end":174},"type_parameters":[],"parameters":[["v#0#0",{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":175,"end":176}]],"returns":[{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":192,"end":195}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":212,"end":213},"1":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":221,"end":222},"2":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":212,"end":223},"3":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":229,"end":233}},"is_native":false},"1":{"location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":245,"end":285},"definition_location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":249,"end":253},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":266,"end":281},"1":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":262,"end":282},"3":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":282,"end":283}},"is_native":false},"2":{"location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":133,"end":285},"definition_location":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":133,"end":285},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[6,250,200,64,243,244,0,170,224,166,223,52,37,241,202,69,118,113,229,127,52,226,194,90,193,222,51,137,204,213,237,77],"start":133,"end":285}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/dependencies/MoveStdlib/vector.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/dependencies/MoveStdlib/vector.move new file mode 100644 index 00000000000..824d0aa1210 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/dependencies/MoveStdlib/vector.move @@ -0,0 +1,365 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(vector)] +/// A variable-sized container that can hold any type. Indexing is 0-based, and +/// vectors are growable. This module has many native functions. +module std::vector { + /// Allows calling `.to_string()` on a vector of `u8` to get a utf8 `String`. + public use fun std::string::utf8 as vector.to_string; + + /// Allows calling `.try_to_string()` on a vector of `u8` to get a utf8 `String`. + /// This will return `None` if the vector is not valid utf8. + public use fun std::string::try_utf8 as vector.try_to_string; + + /// Allows calling `.to_ascii_string()` on a vector of `u8` to get an `ascii::String`. + public use fun std::ascii::string as vector.to_ascii_string; + + /// Allows calling `.try_to_ascii_string()` on a vector of `u8` to get an + /// `ascii::String`. This will return `None` if the vector is not valid ascii. + public use fun std::ascii::try_string as vector.try_to_ascii_string; + + /// The index into the vector is out of bounds + const EINDEX_OUT_OF_BOUNDS: u64 = 0x20000; + + #[bytecode_instruction] + /// Create an empty vector. + public native fun empty(): vector; + + #[bytecode_instruction] + /// Return the length of the vector. + public native fun length(v: &vector): u64; + + #[syntax(index)] + #[bytecode_instruction] + /// Acquire an immutable reference to the `i`th element of the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow(v: &vector, i: u64): ∈ + + #[bytecode_instruction] + /// Add element `e` to the end of the vector `v`. + public native fun push_back(v: &mut vector, e: Element); + + #[syntax(index)] + #[bytecode_instruction] + /// Return a mutable reference to the `i`th element in the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow_mut(v: &mut vector, i: u64): &mut Element; + + #[bytecode_instruction] + /// Pop an element from the end of vector `v`. + /// Aborts if `v` is empty. + public native fun pop_back(v: &mut vector): Element; + + #[bytecode_instruction] + /// Destroy the vector `v`. + /// Aborts if `v` is not empty. + public native fun destroy_empty(v: vector); + + #[bytecode_instruction] + /// Swaps the elements at the `i`th and `j`th indices in the vector `v`. + /// Aborts if `i` or `j` is out of bounds. + public native fun swap(v: &mut vector, i: u64, j: u64); + + /// Return an vector of size one containing element `e`. + public fun singleton(e: Element): vector { + let mut v = empty(); + v.push_back(e); + v + } + + /// Reverses the order of the elements in the vector `v` in place. + public fun reverse(v: &mut vector) { + let len = v.length(); + if (len == 0) return (); + + let mut front_index = 0; + let mut back_index = len - 1; + while (front_index < back_index) { + v.swap(front_index, back_index); + front_index = front_index + 1; + back_index = back_index - 1; + } + } + + /// Pushes all of the elements of the `other` vector into the `lhs` vector. + public fun append(lhs: &mut vector, mut other: vector) { + other.reverse(); + while (!other.is_empty()) lhs.push_back(other.pop_back()); + other.destroy_empty(); + } + + /// Return `true` if the vector `v` has no elements and `false` otherwise. + public fun is_empty(v: &vector): bool { + v.length() == 0 + } + + /// Return true if `e` is in the vector `v`. + /// Otherwise, returns false. + public fun contains(v: &vector, e: &Element): bool { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return true; + i = i + 1; + }; + false + } + + /// Return `(true, i)` if `e` is in the vector `v` at index `i`. + /// Otherwise, returns `(false, 0)`. + public fun index_of(v: &vector, e: &Element): (bool, u64) { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return (true, i); + i = i + 1; + }; + (false, 0) + } + + /// Remove the `i`th element of the vector `v`, shifting all subsequent elements. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun remove(v: &mut vector, mut i: u64): Element { + let mut len = v.length(); + // i out of bounds; abort + if (i >= len) abort EINDEX_OUT_OF_BOUNDS; + + len = len - 1; + while (i < len) v.swap(i, { i = i + 1; i }); + v.pop_back() + } + + /// Insert `e` at position `i` in the vector `v`. + /// If `i` is in bounds, this shifts the old `v[i]` and all subsequent elements to the right. + /// If `i == v.length()`, this adds `e` to the end of the vector. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i > v.length()` + public fun insert(v: &mut vector, e: Element, mut i: u64) { + let len = v.length(); + // i too big abort + if (i > len) abort EINDEX_OUT_OF_BOUNDS; + + v.push_back(e); + while (i < len) { + v.swap(i, len); + i = i + 1 + } + } + + /// Swap the `i`th element of the vector `v` with the last element and then pop the vector. + /// This is O(1), but does not preserve ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun swap_remove(v: &mut vector, i: u64): Element { + assert!(!v.is_empty(), EINDEX_OUT_OF_BOUNDS); + let last_idx = v.length() - 1; + v.swap(i, last_idx); + v.pop_back() + } + + // === Macros === + + /// Create a vector of length `n` by calling the function `f` on each index. + public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> { + let mut v = vector[]; + let n = $n; + n.do!(|i| v.push_back($f(i))); + v + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Does not preserve the order of elements in the vector (starts from the end of the vector). + public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Preserves the order of elements in the vector. + public macro fun do<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Perform an action `f` on each element of the vector `v`. The vector is not modified. + public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) { + let v = $v; + v.length().do!(|i| $f(&v[i])) + } + + /// Perform an action `f` on each element of the vector `v`. + /// The function `f` takes a mutable reference to the element. + public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) { + let v = $v; + v.length().do!(|i| $f(&mut v[i])) + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map<$T, $U>($v: vector<$T>, $f: |$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do!(|e| r.push_back($f(e))); + r + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map_ref<$T, $U>($v: &vector<$T>, $f: |&$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do_ref!(|e| r.push_back($f(e))); + r + } + + /// Filter the vector `v` by applying the function `f` to each element. + /// Return a new vector containing only the elements for which `f` returns `true`. + public macro fun filter<$T: drop>($v: vector<$T>, $f: |&$T| -> bool): vector<$T> { + let v = $v; + let mut r = vector[]; + v.do!(|e| if ($f(&e)) r.push_back(e)); + r + } + + /// Split the vector `v` into two vectors by applying the function `f` to each element. + /// Return a tuple containing two vectors: the first containing the elements for which `f` returns `true`, + /// and the second containing the elements for which `f` returns `false`. + public macro fun partition<$T>($v: vector<$T>, $f: |&$T| -> bool): (vector<$T>, vector<$T>) { + let v = $v; + let mut r1 = vector[]; + let mut r2 = vector[]; + v.do!(|e| if ($f(&e)) r1.push_back(e) else r2.push_back(e)); + (r1, r2) + } + + /// Finds the index of first element in the vector `v` that satisfies the predicate `f`. + /// Returns `some(index)` if such an element is found, otherwise `none()`. + public macro fun find_index<$T>($v: &vector<$T>, $f: |&$T| -> bool): Option { + let v = $v; + 'find_index: { + v.length().do!(|i| if ($f(&v[i])) return 'find_index option::some(i)); + option::none() + } + } + + /// Count how many elements in the vector `v` satisfy the predicate `f`. + public macro fun count<$T>($v: &vector<$T>, $f: |&$T| -> bool): u64 { + let v = $v; + let mut count = 0; + v.do_ref!(|e| if ($f(e)) count = count + 1); + count + } + + /// Reduce the vector `v` to a single value by applying the function `f` to each element. + /// Similar to `fold_left` in Rust and `reduce` in Python and JavaScript. + public macro fun fold<$T, $Acc>($v: vector<$T>, $init: $Acc, $f: |$Acc, $T| -> $Acc): $Acc { + let v = $v; + let mut acc = $init; + v.do!(|e| acc = $f(acc, e)); + acc + } + + /// Whether any element in the vector `v` satisfies the predicate `f`. + /// If the vector is empty, returns `false`. + public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'any: { + v.do_ref!(|e| if ($f(e)) return 'any true); + false + } + } + + /// Whether all elements in the vector `v` satisfy the predicate `f`. + /// If the vector is empty, returns `true`. + public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'all: { + v.do_ref!(|e| if (!$f(e)) return 'all false); + true + } + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + v2.reverse(); + let len = v1.length(); + assert!(len == v2.length()); + v1.do!(|el1| $f(el1, v2.pop_back())); + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// Starts from the end of the vectors. + public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + v1.destroy!(|el1| $f(el1, v2.pop_back())); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The vectors are not modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&v1[i], &v2[i])); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to mutable references of each pair + /// of elements. The vectors may be modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_mut<$T1, $T2>( + $v1: &mut vector<$T1>, + $v2: &mut vector<$T2>, + $f: |&mut $T1, &mut $T2|, + ) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&mut v1[i], &mut v2[i])); + } + + /// Destroys two vectors `v1` and `v2` by applying the function `f` to each pair of elements. + /// The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map<$T1, $T2, $U>( + $v1: vector<$T1>, + $v2: vector<$T2>, + $f: |$T1, $T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map_ref<$T1, $T2, $U>( + $v1: &vector<$T1>, + $v2: &vector<$T2>, + $f: |&$T1, &$T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do_ref!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/m.move new file mode 100644 index 00000000000..35efb0f7569 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/build/abort_native_bytecode/sources/m.move @@ -0,0 +1,14 @@ +// Test abort on a native aborting function representing +// a bytecode, when stepping over a function containing +// the native call. +module abort_native_bytecode::m; + +fun foo(v: vector): u64 { + let val = v.borrow(0); + *val +} + +#[test] +fun test() { + foo(vector::empty()); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/sources/m.move new file mode 100644 index 00000000000..35efb0f7569 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/sources/m.move @@ -0,0 +1,14 @@ +// Test abort on a native aborting function representing +// a bytecode, when stepping over a function containing +// the native call. +module abort_native_bytecode::m; + +fun foo(v: vector): u64 { + let val = v.borrow(0); + *val +} + +#[test] +fun test() { + foo(vector::empty()); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/test.exp new file mode 100644 index 00000000000..2e30fe5759d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/test.exp @@ -0,0 +1 @@ +Exception \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/trace.spec.js new file mode 100644 index 00000000000..efe4d16edf4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/trace.spec.js @@ -0,0 +1,9 @@ +const { ExecutionResult } = require('../../out/runtime'); + +let action = (runtime) => { + let res = ''; + // step over a function to get abort state + res += ExecutionResult[runtime.step(true)]; + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/traces/abort_native_bytecode__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/traces/abort_native_bytecode__m__test.json new file mode 100644 index 00000000000..f374cedec6c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/abort_native_bytecode/traces/abort_native_bytecode__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999990,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999990,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[]}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":999999990}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999979,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[4,0]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999976,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999966,"instruction":"VEC_IMM_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[4,0]},"snapshot":[]}}}},{"Effect":{"ExecutionError":"VECTOR_OPERATION_ERROR"}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/Move.toml new file mode 100644 index 00000000000..2402f9f6a7a --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "breakpoints_line" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +breakpoints_line = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/build/breakpoints_line/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/build/breakpoints_line/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..85130144db6d7d18126d1b0596f8b939287abe81 GIT binary patch literal 369 zcmbtQT@JxO5T2RcE!|x|O+*kL@E~r%NgAZ254zIUfw+NlxrEt@jd=Av%N9UlmU5|Fzfkey<~P5=rZAyC`Nq0Dx5mR9+x$jT}`x-zY^ zs?Lj(I68-C>9hD+U@ { + const filePath = path.join(__dirname, 'sources', `m.move`); + let res = ''; + runtime.setLineBreakpoints(filePath, [ + 10, // invalid (in if branch not traced) + 12, // valid (in traced if branch) + 14, // invalid (empty line) + 18, // valid (past loop) + 20 // valid (in loop) + ]); + res += runtime.toString(); + // advance to the caller + runtime.continue(); + res += runtime.toString(); + // advance beyond the loop + runtime.continue(); + res += runtime.toString(); + // advance into the loop + runtime.continue(); + res += runtime.toString(); + // advance into the loop again + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/traces/breakpoints_line__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/traces/breakpoints_line__m__test.json new file mode 100644 index 00000000000..7527c407590 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/breakpoints_line/traces/breakpoints_line__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999997,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":1}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999997}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999978,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":1}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999975,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999972,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999971,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999953,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":1}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999950,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999947,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999946,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[4,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999928,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999927,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999909,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999906,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999903,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999902,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999901,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999883,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999880,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999877,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999876,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999875,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999857,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":3}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999854,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999851,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999850,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999849,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999831,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":3}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999828,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999825,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999824,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999823,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999805,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999802,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999799,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999798,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999797,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999779,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999776,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999773,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":5}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999772,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":5}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":5}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999771,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999753,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":5}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":5}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999750,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999747,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":5}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999746,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999745,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999727,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":5}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":5}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999724,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999721,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":5}}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999720,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":6}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999719,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999701,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999698,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999695,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999694,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999693,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999675,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999672,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999669,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999668,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":7}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999667,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999649,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":7}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999646,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999643,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999642,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999641,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999623,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":7}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999620,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999617,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999616,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":8}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999615,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999597,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999594,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999591,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999590,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999589,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999571,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999568,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999565,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Push":{"RuntimeValue":{"value":9}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999564,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":9}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":9}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999563,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999545,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":9}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":9}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999542,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999539,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":9}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999538,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999537,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999519,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":9}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":9}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999516,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999513,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":9}}}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999512,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":10}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999511,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999493,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":10}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999490,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999487,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999486,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999468,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":10}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999450,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":1}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999447,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Push":{"RuntimeValue":{"value":11}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999446,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":11}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":11}}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999428,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":11}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":11}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999425,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999422,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":11}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999421,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999420,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999402,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":11}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":11}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999399,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999396,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":11}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999395,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999394,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999376,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999373,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999370,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999369,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999368,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999350,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999347,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999344,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":13}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999343,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":13}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":13}}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999342,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999324,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":13}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":13}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999321,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999318,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":13}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999317,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999316,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999298,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":13}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":13}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999295,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999292,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":13}}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999291,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":14}}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999290,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999272,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":14}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999269,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999266,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999265,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999264,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999246,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":14}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999243,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999240,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Push":{"RuntimeValue":{"value":15}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999239,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":15}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":15}}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999238,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999220,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":15}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":15}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999217,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999214,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":15}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999213,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999212,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999194,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":15}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":15}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999191,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999188,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":15}}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999187,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":16}}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999186,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999168,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999165,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999162,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999161,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":39,"gas_left":999999143,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":40,"gas_left":999999142,"instruction":"RET"}},{"CloseFrame":{"frame_id":4,"return_":[{"RuntimeValue":{"value":16}}],"gas_left":999999142}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999141,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":16}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999123,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999105,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999105,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":409,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":16}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999105}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999086,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,0]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999083,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999080,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999079,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999061,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,0]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999058,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999055,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Push":{"RuntimeValue":{"value":17}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999054,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":17}}}},{"Effect":{"Write":{"location":{"Local":[409,1]},"root_value_after_write":{"RuntimeValue":{"value":17}}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999036,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,1]},"root_value_read":{"RuntimeValue":{"value":17}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":17}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999035,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":17}}}},{"Effect":{"Write":{"location":{"Local":[409,2]},"root_value_after_write":{"RuntimeValue":{"value":17}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999017,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,2]},"root_value_read":{"RuntimeValue":{"value":17}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":17}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999014,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999011,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":17}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999010,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999998992,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,2]},"root_value_read":{"RuntimeValue":{"value":17}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":17}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999998974,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,0]},"root_value_read":{"RuntimeValue":{"value":16}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999998971,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":17}}}},{"Effect":{"Push":{"RuntimeValue":{"value":33}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999998970,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":33}}}},{"Effect":{"Write":{"location":{"Local":[409,2]},"root_value_after_write":{"RuntimeValue":{"value":33}}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999998952,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,2]},"root_value_read":{"RuntimeValue":{"value":33}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":33}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999998949,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999998946,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":33}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999998945,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":39,"gas_left":999998927,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[409,2]},"root_value_read":{"RuntimeValue":{"value":33}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":33}}}},{"Instruction":{"type_parameters":[],"pc":40,"gas_left":999998926,"instruction":"RET"}},{"CloseFrame":{"frame_id":409,"return_":[{"RuntimeValue":{"value":33}}],"gas_left":999998926}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999998923,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":33}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Push":{"RuntimeValue":{"value":49}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999998922,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":49}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":49}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999998904,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":49}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":49}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999998886,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":49}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":49}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999998886,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":493,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":49}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999998886}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998867,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,0]},"root_value_read":{"RuntimeValue":{"value":49}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":49}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998864,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998861,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":49}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998860,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999998842,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,0]},"root_value_read":{"RuntimeValue":{"value":49}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":49}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999998839,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999998836,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":49}}}},{"Effect":{"Push":{"RuntimeValue":{"value":50}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999998835,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":50}}}},{"Effect":{"Write":{"location":{"Local":[493,1]},"root_value_after_write":{"RuntimeValue":{"value":50}}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999998817,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,1]},"root_value_read":{"RuntimeValue":{"value":50}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":50}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999998816,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":50}}}},{"Effect":{"Write":{"location":{"Local":[493,2]},"root_value_after_write":{"RuntimeValue":{"value":50}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999998798,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,2]},"root_value_read":{"RuntimeValue":{"value":50}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":50}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999998795,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999998792,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":50}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999998791,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999998773,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,2]},"root_value_read":{"RuntimeValue":{"value":50}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":50}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999998755,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,0]},"root_value_read":{"RuntimeValue":{"value":49}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":49}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999998752,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":49}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":50}}}},{"Effect":{"Push":{"RuntimeValue":{"value":99}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999998751,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":99}}}},{"Effect":{"Write":{"location":{"Local":[493,2]},"root_value_after_write":{"RuntimeValue":{"value":99}}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999998733,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,2]},"root_value_read":{"RuntimeValue":{"value":99}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":99}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999998730,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":16}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999998727,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":16}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":99}}}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999998726,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Instruction":{"type_parameters":[],"pc":39,"gas_left":999998708,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[493,2]},"root_value_read":{"RuntimeValue":{"value":99}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":99}}}},{"Instruction":{"type_parameters":[],"pc":40,"gas_left":999998707,"instruction":"RET"}},{"CloseFrame":{"frame_id":493,"return_":[{"RuntimeValue":{"value":99}}],"gas_left":999998707}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999998704,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":99}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":49}}}},{"Effect":{"Push":{"RuntimeValue":{"value":148}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999998703,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":148}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999998702,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999998702}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/Move.toml new file mode 100644 index 00000000000..3ae5f158e61 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "compound" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +compound = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/bytecode_modules/dependencies/MoveStdlib/vector.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/bytecode_modules/dependencies/MoveStdlib/vector.mv new file mode 100644 index 0000000000000000000000000000000000000000..79c6d2eb99157a351717e0a6c0cc80cc20a46ce2 GIT binary patch literal 1123 zcmaJ=%}(4f5T3CeCmCm#-35WvB9-mZ_SQ4UQbGF|(XwkGDkM=7{vN0IK1vTg_0(%m zeTmLE5J4qs$)BD1`DQ#b`MUeZSpY~7j5f9DOmw@Bf8h^IzUe*tT~qc`|2D7%Gq8XN zKuR;Bi5N2$0jQY0!KK8=QpSlB+#s)MxVdr~z` zbwmA;UtV>|sw%r>QMNBujbC;?Z;P|iH*J1eHF@XTt|-q&Yd)LmF87ypcNYarigN95 z^Xk;HuW!1fXnVE2@a0)|p43&HpDb5j()y}B4>#NR%j(+4jlbpqK5d!$!gp0^+M8wV z1oGY_y()_?M4t?|ysnD2D($sjbydUl``<#HaLalNR8k|Zj^e^9FuWt)mUqls+KTZ9 zdZ5d2gbt3#p-QD+ZwTHWQl?4E2!%B_j(e|$?@T#u**2`53`r3#%xmH?BK%BF4a#jc z#o>!hqp2{-c))ao2QbD1+%s7e6O8bfjwn)W;PBIs9}}=~cT7tDE&b}DKm64F2TlTqN7TQ5H}paO q+lOd_!>fr<>@bCt-A2@>6eu5M#np7^6jMmpDH;GXJZ(DTDf$cNL2%3f literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..ed59f3dde6851c23188a484d9da7a69839727947 GIT binary patch literal 721 zcmbtS!D`$v5SAZ90IvSpn0R`@tYZqe!ad;CjiPKB$QZ@zmZF+KE0h>{2+ZppUt&6 zv%ke3oc)z1`>y7vKa~WFr+5aE00eIm04X3qMr?9o>IEB2qy}231VKqPAq@gGfYhkb z2%`xFP5}*X_Kmgcs&SVWRaaMS%+7tNW9{2&f5+HO-5mCA6T9O!>Wy#Qm-g70-Wj>P zYJL3by3#RU?rOKce6{Ud6&=%F|<8$05h!-YXBj4!&J{b6c*YZ(@`giQ(UoNH`+; z4xYCVNX^AWqtaLy@se+v2sICh$Mw#j!8KShAX+lG0xJ#XxI(K^oWUH5R4`zX5(5>f zWDrHF7-W$GkCvtAB>7+GV`mLda;t~WecqfU`O$FQ87A-VR5L*07bAh>y;dffXysW5$m2>$?8)^z6p literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/dependencies/MoveStdlib/vector.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/dependencies/MoveStdlib/vector.json new file mode 100644 index 00000000000..9d5a13fdd3b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/dependencies/MoveStdlib/vector.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":261,"end":267},"module_name":["0000000000000000000000000000000000000000000000000000000000000001","vector"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1184,"end":1236},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1202,"end":1207},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1208,"end":1215}]],"parameters":[],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1220,"end":1235}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1311,"end":1371},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1329,"end":1335},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1336,"end":1343}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1345,"end":1346}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1367,"end":1370}],"locals":[],"nops":{},"code_map":{},"is_native":true},"2":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1545,"end":1618},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1563,"end":1569},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1570,"end":1577}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1579,"end":1580}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1600,"end":1601}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1609,"end":1617}],"locals":[],"nops":{},"code_map":{},"is_native":true},"3":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1706,"end":1780},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1724,"end":1733},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1734,"end":1741}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1743,"end":1744}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1768,"end":1769}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"4":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1950,"end":2035},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1968,"end":1978},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1979,"end":1986}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1988,"end":1989}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2013,"end":2014}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2022,"end":2034}],"locals":[],"nops":{},"code_map":{},"is_native":true},"5":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2152,"end":2222},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2170,"end":2178},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2179,"end":2186}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2188,"end":2189}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2214,"end":2221}],"locals":[],"nops":{},"code_map":{},"is_native":true},"6":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2324,"end":2385},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2342,"end":2355},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2356,"end":2363}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2365,"end":2366}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"7":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2543,"end":2616},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2561,"end":2565},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2566,"end":2573}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2575,"end":2576}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2600,"end":2601}],["j#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2608,"end":2609}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"8":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2683,"end":2812},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2694,"end":2703},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2704,"end":2711}]],"parameters":[["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2713,"end":2714}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2726,"end":2741}],"locals":[["v#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2760,"end":2761}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2764,"end":2771},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2756,"end":2761},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2782},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2793,"end":2794},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2795},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2805,"end":2806}},"is_native":false},"9":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2889,"end":3266},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2900,"end":2907},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2908,"end":2915}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2917,"end":2918}]],"returns":[],"locals":[["back_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3057,"end":3067}],["front_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3024,"end":3035}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2963},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2972},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2986,"end":2989},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2993,"end":2994},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2990,"end":2992},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2982,"end":3005},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2996,"end":3005},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3038,"end":3039},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3020,"end":3035},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3070,"end":3073},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3076,"end":3077},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3074,"end":3075},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3053,"end":3067},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3094,"end":3105},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3108,"end":3118},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3106,"end":3107},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3135},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3141,"end":3152},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3154,"end":3164},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3165},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3193,"end":3204},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3207,"end":3208},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3205,"end":3206},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3179,"end":3190},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3235,"end":3245},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3248,"end":3249},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3246,"end":3247},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3222,"end":3232},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260}},"is_native":false},"10":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3352,"end":3564},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3363,"end":3369},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3370,"end":3377}]],"parameters":[["lhs#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3379,"end":3382}],["other#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3410,"end":3415}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3449},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3459},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3482},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3493},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3476,"end":3477},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3498},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3514},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3525},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3526},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3541},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3557,"end":3558}},"is_native":false},"11":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3649,"end":3736},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3660,"end":3668},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3669,"end":3676}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3678,"end":3679}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3700,"end":3704}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3716},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3725},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3729,"end":3730},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3726,"end":3728},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3730}},"is_native":false},"12":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3825,"end":4069},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3836,"end":3844},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3845,"end":3852}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3854,"end":3855}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3875,"end":3876}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3889,"end":3893}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3912,"end":3913}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3916,"end":3917},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3908,"end":3913},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3938},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3947},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3964,"end":3965},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3968,"end":3971},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3966,"end":3967},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3992,"end":3993},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3994,"end":3995},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3991,"end":3996},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4000,"end":4001},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3997,"end":3999},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3987,"end":4014},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4010,"end":4014},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4032,"end":4033},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4036,"end":4037},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4034,"end":4035},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4028,"end":4029},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4058,"end":4063}},"is_native":false},"13":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4185,"end":4446},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4196,"end":4204},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4205,"end":4212}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4214,"end":4215}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4235,"end":4236}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4250,"end":4254},{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4256,"end":4259}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4279,"end":4280}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4283,"end":4284},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4275,"end":4280},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4305},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4314},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4331,"end":4332},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4335,"end":4338},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4333,"end":4334},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4359,"end":4360},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4361,"end":4362},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4358,"end":4363},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4367,"end":4368},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4364,"end":4366},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4354,"end":4386},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4378,"end":4382},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4384,"end":4385},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4404,"end":4405},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4408,"end":4409},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4406,"end":4407},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4400,"end":4401},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4431,"end":4436},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4438,"end":4439},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440}},"is_native":false},"14":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4649,"end":4945},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4660,"end":4666},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4667,"end":4674}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4676,"end":4677}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4705,"end":4706}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4714,"end":4721}],"locals":[["%#1",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898}],["%#2",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4740,"end":4743}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4747},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4756},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4736,"end":4743},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4804,"end":4805},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4809,"end":4812},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4806,"end":4808},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4800,"end":4840},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4820,"end":4840},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4857,"end":4860},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4863,"end":4864},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4861,"end":4862},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4851,"end":4854},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4881,"end":4882},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4885,"end":4888},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4883,"end":4884},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4906,"end":4907},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4910,"end":4911},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4908,"end":4909},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4902,"end":4903},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4913,"end":4914},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4917},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4928},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4939}},"is_native":false},"15":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5279,"end":5579},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5290,"end":5296},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5297,"end":5304}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5306,"end":5307}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5331,"end":5332}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5347,"end":5348}]],"returns":[],"locals":[["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5376},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5385},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5426,"end":5427},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5430,"end":5433},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5428,"end":5429},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5422,"end":5461},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5441,"end":5461},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5473},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5484,"end":5485},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5486},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5503,"end":5504},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5507,"end":5510},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5505,"end":5506},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5527},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5533,"end":5534},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5536,"end":5539},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5540},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5558,"end":5559},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5562,"end":5563},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5560,"end":5561},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5554,"end":5555},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573}},"is_native":false},"16":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5801,"end":6025},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5812,"end":5823},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5824,"end":5831}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5833,"end":5834}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5858,"end":5859}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5867,"end":5874}],"locals":[["last_idx#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5895},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5906},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5893,"end":5894},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5908,"end":5928},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5955},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5964},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5967,"end":5968},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5965,"end":5966},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5979},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5985,"end":5986},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5988,"end":5996},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5997},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6008},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6019}},"is_native":false},"17":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981}},"is_native":false}},"constant_map":{"EINDEX_OUT_OF_BOUNDS":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/m.json new file mode 100644 index 00000000000..adabb7c306b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":98,"end":99},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{"0":{"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":231,"end":241},"type_parameters":[],"fields":[{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":257,"end":269},{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":280,"end":290},{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":306,"end":324},{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":340,"end":356},{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":375,"end":391}]},"1":{"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":432,"end":444},"type_parameters":[],"fields":[{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":466,"end":471}]}},"enum_map":{"0":{"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":114,"end":122},"type_parameters":[],"variants":[[["PositionalVariant",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":138,"end":165}],[{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":156,"end":159},{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":161,"end":164}]],[["NamedVariant",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":171,"end":212}],[{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":186,"end":192},{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":199,"end":205}]]]}},"function_map":{"0":{"location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":481,"end":1020},"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":485,"end":488},"type_parameters":[],"parameters":[["some_struct#0#0",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":493,"end":504}],["p#0#0",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":518,"end":519}]],"returns":[{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":527,"end":537}],"locals":[["named_variant#1#0",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":605,"end":618}],["pos_variant#1#0",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":548,"end":559}],["v#1#0",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":699,"end":700}],["v_struct#1#0",{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":733,"end":741}]],"nops":{},"code_map":{"0":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":590,"end":591},"1":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":593,"end":594},"2":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":562,"end":595},"3":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":548,"end":559},"4":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":662,"end":663},"5":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":681,"end":682},"6":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":621,"end":689},"7":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":605,"end":618},"8":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":721,"end":722},"9":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":703,"end":723},"10":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":699,"end":700},"11":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":784,"end":785},"12":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":762,"end":787},"13":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":744,"end":788},"14":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":733,"end":741},"15":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":822,"end":823},"16":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":795,"end":819},"18":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":795,"end":823},"19":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":854,"end":865},"20":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":829,"end":851},"22":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":829,"end":865},"23":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":904,"end":917},"24":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":871,"end":901},"26":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":871,"end":917},"27":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":954,"end":955},"28":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":923,"end":951},"30":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":923,"end":955},"31":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":992,"end":1000},"32":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":961,"end":989},"34":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":961,"end":1000},"35":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1007,"end":1018}},"is_native":false},"1":{"location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1022,"end":1341},"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1026,"end":1037},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1041,"end":1051}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1093,"end":1094},"1":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1144,"end":1145},"2":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1147,"end":1148},"3":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1116,"end":1149},"4":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1207,"end":1208},"5":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1210,"end":1211},"6":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1179,"end":1212},"7":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1258,"end":1259},"8":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1240,"end":1260},"9":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1328,"end":1329},"10":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1306,"end":1331},"11":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1288,"end":1332},"12":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1058,"end":1339}},"is_native":false},"2":{"location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1351,"end":1428},"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1355,"end":1359},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1386,"end":1399},"1":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1422,"end":1424},"2":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1405,"end":1425},"4":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":1425,"end":1426}},"is_native":false},"3":{"location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":81,"end":1428},"definition_location":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":81,"end":1428},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[123,47,2,242,89,17,168,119,38,143,101,6,62,112,40,165,19,85,26,58,91,184,149,65,204,94,41,244,153,66,177,132],"start":81,"end":1428}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/dependencies/MoveStdlib/vector.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/dependencies/MoveStdlib/vector.move new file mode 100644 index 00000000000..824d0aa1210 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/dependencies/MoveStdlib/vector.move @@ -0,0 +1,365 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(vector)] +/// A variable-sized container that can hold any type. Indexing is 0-based, and +/// vectors are growable. This module has many native functions. +module std::vector { + /// Allows calling `.to_string()` on a vector of `u8` to get a utf8 `String`. + public use fun std::string::utf8 as vector.to_string; + + /// Allows calling `.try_to_string()` on a vector of `u8` to get a utf8 `String`. + /// This will return `None` if the vector is not valid utf8. + public use fun std::string::try_utf8 as vector.try_to_string; + + /// Allows calling `.to_ascii_string()` on a vector of `u8` to get an `ascii::String`. + public use fun std::ascii::string as vector.to_ascii_string; + + /// Allows calling `.try_to_ascii_string()` on a vector of `u8` to get an + /// `ascii::String`. This will return `None` if the vector is not valid ascii. + public use fun std::ascii::try_string as vector.try_to_ascii_string; + + /// The index into the vector is out of bounds + const EINDEX_OUT_OF_BOUNDS: u64 = 0x20000; + + #[bytecode_instruction] + /// Create an empty vector. + public native fun empty(): vector; + + #[bytecode_instruction] + /// Return the length of the vector. + public native fun length(v: &vector): u64; + + #[syntax(index)] + #[bytecode_instruction] + /// Acquire an immutable reference to the `i`th element of the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow(v: &vector, i: u64): ∈ + + #[bytecode_instruction] + /// Add element `e` to the end of the vector `v`. + public native fun push_back(v: &mut vector, e: Element); + + #[syntax(index)] + #[bytecode_instruction] + /// Return a mutable reference to the `i`th element in the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow_mut(v: &mut vector, i: u64): &mut Element; + + #[bytecode_instruction] + /// Pop an element from the end of vector `v`. + /// Aborts if `v` is empty. + public native fun pop_back(v: &mut vector): Element; + + #[bytecode_instruction] + /// Destroy the vector `v`. + /// Aborts if `v` is not empty. + public native fun destroy_empty(v: vector); + + #[bytecode_instruction] + /// Swaps the elements at the `i`th and `j`th indices in the vector `v`. + /// Aborts if `i` or `j` is out of bounds. + public native fun swap(v: &mut vector, i: u64, j: u64); + + /// Return an vector of size one containing element `e`. + public fun singleton(e: Element): vector { + let mut v = empty(); + v.push_back(e); + v + } + + /// Reverses the order of the elements in the vector `v` in place. + public fun reverse(v: &mut vector) { + let len = v.length(); + if (len == 0) return (); + + let mut front_index = 0; + let mut back_index = len - 1; + while (front_index < back_index) { + v.swap(front_index, back_index); + front_index = front_index + 1; + back_index = back_index - 1; + } + } + + /// Pushes all of the elements of the `other` vector into the `lhs` vector. + public fun append(lhs: &mut vector, mut other: vector) { + other.reverse(); + while (!other.is_empty()) lhs.push_back(other.pop_back()); + other.destroy_empty(); + } + + /// Return `true` if the vector `v` has no elements and `false` otherwise. + public fun is_empty(v: &vector): bool { + v.length() == 0 + } + + /// Return true if `e` is in the vector `v`. + /// Otherwise, returns false. + public fun contains(v: &vector, e: &Element): bool { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return true; + i = i + 1; + }; + false + } + + /// Return `(true, i)` if `e` is in the vector `v` at index `i`. + /// Otherwise, returns `(false, 0)`. + public fun index_of(v: &vector, e: &Element): (bool, u64) { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return (true, i); + i = i + 1; + }; + (false, 0) + } + + /// Remove the `i`th element of the vector `v`, shifting all subsequent elements. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun remove(v: &mut vector, mut i: u64): Element { + let mut len = v.length(); + // i out of bounds; abort + if (i >= len) abort EINDEX_OUT_OF_BOUNDS; + + len = len - 1; + while (i < len) v.swap(i, { i = i + 1; i }); + v.pop_back() + } + + /// Insert `e` at position `i` in the vector `v`. + /// If `i` is in bounds, this shifts the old `v[i]` and all subsequent elements to the right. + /// If `i == v.length()`, this adds `e` to the end of the vector. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i > v.length()` + public fun insert(v: &mut vector, e: Element, mut i: u64) { + let len = v.length(); + // i too big abort + if (i > len) abort EINDEX_OUT_OF_BOUNDS; + + v.push_back(e); + while (i < len) { + v.swap(i, len); + i = i + 1 + } + } + + /// Swap the `i`th element of the vector `v` with the last element and then pop the vector. + /// This is O(1), but does not preserve ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun swap_remove(v: &mut vector, i: u64): Element { + assert!(!v.is_empty(), EINDEX_OUT_OF_BOUNDS); + let last_idx = v.length() - 1; + v.swap(i, last_idx); + v.pop_back() + } + + // === Macros === + + /// Create a vector of length `n` by calling the function `f` on each index. + public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> { + let mut v = vector[]; + let n = $n; + n.do!(|i| v.push_back($f(i))); + v + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Does not preserve the order of elements in the vector (starts from the end of the vector). + public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Preserves the order of elements in the vector. + public macro fun do<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Perform an action `f` on each element of the vector `v`. The vector is not modified. + public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) { + let v = $v; + v.length().do!(|i| $f(&v[i])) + } + + /// Perform an action `f` on each element of the vector `v`. + /// The function `f` takes a mutable reference to the element. + public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) { + let v = $v; + v.length().do!(|i| $f(&mut v[i])) + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map<$T, $U>($v: vector<$T>, $f: |$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do!(|e| r.push_back($f(e))); + r + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map_ref<$T, $U>($v: &vector<$T>, $f: |&$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do_ref!(|e| r.push_back($f(e))); + r + } + + /// Filter the vector `v` by applying the function `f` to each element. + /// Return a new vector containing only the elements for which `f` returns `true`. + public macro fun filter<$T: drop>($v: vector<$T>, $f: |&$T| -> bool): vector<$T> { + let v = $v; + let mut r = vector[]; + v.do!(|e| if ($f(&e)) r.push_back(e)); + r + } + + /// Split the vector `v` into two vectors by applying the function `f` to each element. + /// Return a tuple containing two vectors: the first containing the elements for which `f` returns `true`, + /// and the second containing the elements for which `f` returns `false`. + public macro fun partition<$T>($v: vector<$T>, $f: |&$T| -> bool): (vector<$T>, vector<$T>) { + let v = $v; + let mut r1 = vector[]; + let mut r2 = vector[]; + v.do!(|e| if ($f(&e)) r1.push_back(e) else r2.push_back(e)); + (r1, r2) + } + + /// Finds the index of first element in the vector `v` that satisfies the predicate `f`. + /// Returns `some(index)` if such an element is found, otherwise `none()`. + public macro fun find_index<$T>($v: &vector<$T>, $f: |&$T| -> bool): Option { + let v = $v; + 'find_index: { + v.length().do!(|i| if ($f(&v[i])) return 'find_index option::some(i)); + option::none() + } + } + + /// Count how many elements in the vector `v` satisfy the predicate `f`. + public macro fun count<$T>($v: &vector<$T>, $f: |&$T| -> bool): u64 { + let v = $v; + let mut count = 0; + v.do_ref!(|e| if ($f(e)) count = count + 1); + count + } + + /// Reduce the vector `v` to a single value by applying the function `f` to each element. + /// Similar to `fold_left` in Rust and `reduce` in Python and JavaScript. + public macro fun fold<$T, $Acc>($v: vector<$T>, $init: $Acc, $f: |$Acc, $T| -> $Acc): $Acc { + let v = $v; + let mut acc = $init; + v.do!(|e| acc = $f(acc, e)); + acc + } + + /// Whether any element in the vector `v` satisfies the predicate `f`. + /// If the vector is empty, returns `false`. + public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'any: { + v.do_ref!(|e| if ($f(e)) return 'any true); + false + } + } + + /// Whether all elements in the vector `v` satisfy the predicate `f`. + /// If the vector is empty, returns `true`. + public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'all: { + v.do_ref!(|e| if (!$f(e)) return 'all false); + true + } + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + v2.reverse(); + let len = v1.length(); + assert!(len == v2.length()); + v1.do!(|el1| $f(el1, v2.pop_back())); + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// Starts from the end of the vectors. + public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + v1.destroy!(|el1| $f(el1, v2.pop_back())); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The vectors are not modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&v1[i], &v2[i])); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to mutable references of each pair + /// of elements. The vectors may be modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_mut<$T1, $T2>( + $v1: &mut vector<$T1>, + $v2: &mut vector<$T2>, + $f: |&mut $T1, &mut $T2|, + ) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&mut v1[i], &mut v2[i])); + } + + /// Destroys two vectors `v1` and `v2` by applying the function `f` to each pair of elements. + /// The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map<$T1, $T2, $U>( + $v1: vector<$T1>, + $v2: vector<$T2>, + $f: |$T1, $T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map_ref<$T1, $T2, $U>( + $v1: &vector<$T1>, + $v2: &vector<$T2>, + $f: |&$T1, &$T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do_ref!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/m.move new file mode 100644 index 00000000000..193501e8267 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/build/compound/sources/m.move @@ -0,0 +1,54 @@ +// Test tracking values of compound type variables +// (structs, enums, vectors). +module compound::m; + +public enum SomeEnum has drop { + PositionalVariant(u64, u64), + NamedVariant { field1: u64, field2: u64 }, +} + +public struct SomeStruct has drop { + simple_field: u64, + enum_field: SomeEnum, + another_enum_field: SomeEnum, + vec_simple_field: vector, + vec_struct_field: vector, +} + +public struct SimpleStruct has drop, copy { + field: u64, +} + +fun foo(mut some_struct: SomeStruct, p: u64): SomeStruct { + let pos_variant = SomeEnum::PositionalVariant(p, p); + let named_variant = SomeEnum::NamedVariant { + field1: p, + field2: p, + }; + let v = vector::singleton(p); + let v_struct = vector::singleton(SimpleStruct { field: p }); + + some_struct.simple_field = p; + some_struct.enum_field = pos_variant; + some_struct.another_enum_field = named_variant; + some_struct.vec_simple_field = v; + some_struct.vec_struct_field = v_struct; + + some_struct +} + +fun some_struct(): SomeStruct { + SomeStruct { + simple_field: 0, + enum_field: SomeEnum::PositionalVariant(0, 0), + another_enum_field: SomeEnum::PositionalVariant(0, 0), + vec_simple_field: vector::singleton(0), + vec_struct_field: vector::singleton(SimpleStruct { field: 0 }), + } +} + +#[test] +fun test() { + let some_struct = some_struct(); + foo(some_struct, 42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/sources/m.move new file mode 100644 index 00000000000..193501e8267 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/sources/m.move @@ -0,0 +1,54 @@ +// Test tracking values of compound type variables +// (structs, enums, vectors). +module compound::m; + +public enum SomeEnum has drop { + PositionalVariant(u64, u64), + NamedVariant { field1: u64, field2: u64 }, +} + +public struct SomeStruct has drop { + simple_field: u64, + enum_field: SomeEnum, + another_enum_field: SomeEnum, + vec_simple_field: vector, + vec_struct_field: vector, +} + +public struct SimpleStruct has drop, copy { + field: u64, +} + +fun foo(mut some_struct: SomeStruct, p: u64): SomeStruct { + let pos_variant = SomeEnum::PositionalVariant(p, p); + let named_variant = SomeEnum::NamedVariant { + field1: p, + field2: p, + }; + let v = vector::singleton(p); + let v_struct = vector::singleton(SimpleStruct { field: p }); + + some_struct.simple_field = p; + some_struct.enum_field = pos_variant; + some_struct.another_enum_field = named_variant; + some_struct.vec_simple_field = v; + some_struct.vec_struct_field = v_struct; + + some_struct +} + +fun some_struct(): SomeStruct { + SomeStruct { + simple_field: 0, + enum_field: SomeEnum::PositionalVariant(0, 0), + another_enum_field: SomeEnum::PositionalVariant(0, 0), + vec_simple_field: vector::singleton(0), + vec_struct_field: vector::singleton(SimpleStruct { field: 0 }), + } +} + +#[test] +fun test() { + let some_struct = some_struct(); + foo(some_struct, 42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/test.exp new file mode 100644 index 00000000000..089b3a63580 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/test.exp @@ -0,0 +1,55 @@ +current frame stack: + function: test (m.move:53) + scope 0 : + function: foo (m.move:23) + scope 0 : + some_struct : (0x0::m::SomeStruct) { + simple_field : 0 + enum_field : (0x0::m::SomeEnum::PositionalVariant) { + pos0 : 0 + pos1 : 0 + } + another_enum_field : (0x0::m::SomeEnum::PositionalVariant) { + pos0 : 0 + pos1 : 0 + } + vec_simple_field : [ + 0 : 0 + ] + vec_struct_field : [ + 0 : (0x0::m::SimpleStruct) { + field : 0 + } + ] + } + type: 0x0::m::SomeStruct + + p : 42 + type: u64 + +current frame stack: + function: test (m.move:53) + scope 0 : + function: foo (m.move:37) + scope 0 : + some_struct : (0x0::m::SomeStruct) { + simple_field : 42 + enum_field : (0x0::m::SomeEnum::PositionalVariant) { + pos0 : 42 + pos1 : 42 + } + another_enum_field : (0x0::m::SomeEnum::NamedVariant) { + field1 : 42 + field2 : 42 + } + vec_simple_field : [ + 0 : 42 + ] + vec_struct_field : [ + 0 : (0x0::m::SimpleStruct) { + field : 42 + } + ] + } + type: 0x0::m::SomeStruct + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/trace.spec.js new file mode 100644 index 00000000000..9837778eaf0 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/trace.spec.js @@ -0,0 +1,23 @@ +let action = (runtime) => { + let res = ''; + // step over a function creating a complex struct + runtime.step(true); + // step into a function + runtime.step(false); + res += runtime.toString(); + // advance until all struct fields are updated + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/traces/compound__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/traces/compound__m__test.json new file mode 100644 index 00000000000..1b4e077a615 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/compound/traces/compound__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":2,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"some_struct","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null}],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999993,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999990,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999986,"instruction":"PACK_VARIANT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999983,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999980,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999976,"instruction":"PACK_VARIANT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999973,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999973,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":24,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":["u64"],"parameters":[{"RuntimeValue":{"value":0}}],"return_types":[{"type_":{"vector":"u64"},"ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":999999973}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999962,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999961,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[24,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999951,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[24,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[24,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999933,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[24,0]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999932,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[24,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[24,1]},"root_value_after_write":{"RuntimeValue":{"value":[0]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999922,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[24,1]},"root_value_read":{"RuntimeValue":{"value":[0]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[0]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999921,"instruction":"RET"}},{"CloseFrame":{"frame_id":24,"return_":[{"RuntimeValue":{"value":[0]}}],"gas_left":999999921}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999918,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999914,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999914,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":51,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}],"parameters":[{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}}],"return_types":[{"type_":{"vector":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}},"ref_type":null},{"type_":{"vector":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}},"ref_type":null}],"is_native":false},"gas_left":999999914}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999903,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999902,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[51,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999892,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[51,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[51,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999872,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[51,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999871,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[51,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[51,1]},"root_value_after_write":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999849,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[51,1]},"root_value_read":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999848,"instruction":"RET"}},{"CloseFrame":{"frame_id":51,"return_":[{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}],"gas_left":999999848}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999844,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":[0]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999843,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}],"gas_left":999999843}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999840,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999840,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":84,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},{"RuntimeValue":{"value":42}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null},{"type_":"u64","ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeEnum","type_args":[]}},"ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeEnum","type_args":[]}},"ref_type":null},{"type_":{"vector":"u64"},"ref_type":null},{"type_":{"vector":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}},"ref_type":null}],"is_native":false},"gas_left":999999840}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999821,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999803,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999799,"instruction":"PACK_VARIANT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999798,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}}}}}},{"Effect":{"Write":{"location":{"Local":[84,3]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999780,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999762,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999758,"instruction":"PACK_VARIANT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999757,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}}}}}},{"Effect":{"Write":{"location":{"Local":[84,2]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999739,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999739,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":115,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":["u64"],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":{"vector":"u64"},"ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":999999739}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999728,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999727,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[115,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999717,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[115,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[115,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999699,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[115,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999698,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[115,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[115,1]},"root_value_after_write":{"RuntimeValue":{"value":[42]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999688,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[115,1]},"root_value_read":{"RuntimeValue":{"value":[42]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[42]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999687,"instruction":"RET"}},{"CloseFrame":{"frame_id":115,"return_":[{"RuntimeValue":{"value":[42]}}],"gas_left":999999687}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999686,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[42]}}}},{"Effect":{"Write":{"location":{"Local":[84,4]},"root_value_after_write":{"RuntimeValue":{"value":[42]}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999668,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999664,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":42}}}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999664,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":146,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}],"parameters":[{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":42}}}}],"return_types":[{"type_":{"vector":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}},"ref_type":null},{"type_":{"vector":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SimpleStruct","type_args":[]}}},"ref_type":null}],"is_native":false},"gas_left":999999664}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999653,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999652,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[146,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999642,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[146,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[146,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999622,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[146,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":42}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":42}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999621,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":42}}}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[146,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[146,1]},"root_value_after_write":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999599,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[146,1]},"root_value_read":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999598,"instruction":"RET"}},{"CloseFrame":{"frame_id":146,"return_":[{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}],"gas_left":999999598}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999597,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}},{"Effect":{"Write":{"location":{"Local":[84,5]},"root_value_after_write":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999579,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999569,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999559,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999541,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":0,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[84,0]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999505,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,3]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999495,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999485,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999449,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}}}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[84,0]},1]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999413,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,2]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999403,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999393,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},2]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999357,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},2]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":0,"pos1":0}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}}}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[84,0]},2]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999347,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,4]},"root_value_read":{"RuntimeValue":{"value":[42]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[42]}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999337,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999327,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},3]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999317,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},3]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[0],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":[42]}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[84,0]},3]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999295,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,5]},"root_value_read":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999285,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999275,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[84,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},4]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999253,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[84,0]},4]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":0}}]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[84,0]},4]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999137,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[84,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999136,"instruction":"RET"}},{"CloseFrame":{"frame_id":84,"return_":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}}],"gas_left":999999136}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999135,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"simple_field":42,"enum_field":{"type":"0x0::m::SomeEnum","variant_name":"PositionalVariant","variant_tag":0,"fields":{"pos0":42,"pos1":42}},"another_enum_field":{"type":"0x0::m::SomeEnum","variant_name":"NamedVariant","variant_tag":1,"fields":{"field1":42,"field2":42}},"vec_simple_field":[42],"vec_struct_field":[{"type":"0x0::m::SimpleStruct","fields":{"field":42}}]}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999134,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999134}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/Move.toml new file mode 100644 index 00000000000..e737916dbca --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "global_loc" +edition = "2024.beta" + +[dependencies] +Iota = { git = "https://github.com/iotaledger/iota.git", subdir = "crates/iota-framework/packages/iota-framework", rev = "framework/mainnet" } + +[addresses] +global_loc = "0x0" +Iota = "0x2" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..d24eb56fae5a632609168a8edaac128572263ac4 GIT binary patch literal 520 zcmbu6u};G<5Qgv0PU6^ZXaH3e;t4ubLh8T_6`~UZFbCSWRS>aJ<3jrg%sc^)hnRQ+ zoFY|XVd2-E_1ijs!+-C`pDG4`6hV;avi^`?P;@y=p5IWs(w+Pup})w2#4dGc4^RL> z0>n5lA_x`%vexC{K#m=tND`2UVic4nVP0toEG7jJr*K6ET%aVP0K+&9OvE^}Bn(fX z7$%{mrpZ`dyV_h$AI!|BH|uj}y;*y9I~gC%mge4@qNx_vESqBPmW4Nsuk0c&&7<)q zDpz&AVRPrGDpge$-WAhLn8BJ^^TO<^j@_2b+mF((i`fr9UD?WSY2BSGo?O*98?yS3 zLRfz)1V=)U4tWBweg>zYDWg2rEMx7WwmM4>HCJ!|I?B1?BNdH$3P(L^@hZ=Sh7RP( W$zUH&2Kg`F!w@?M;yYN*kl-8jKtwVC literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/object.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/object.json new file mode 100644 index 00000000000..7ceaf5f2151 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/object.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":114,"end":120},"module_name":["0000000000000000000000000000000000000000000000000000000000000002","object"],"struct_map":{"0":{"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":1986,"end":1988},"type_parameters":[],"fields":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2345,"end":2350}]},"1":{"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2882,"end":2885},"type_parameters":[],"fields":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2902,"end":2904}]}},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2960,"end":3036},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2971,"end":2982},"type_parameters":[],"parameters":[["id#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2983,"end":2985}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":2993,"end":3003}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3025,"end":3027},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3024,"end":3033},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3010,"end":3034}},"is_native":false},"1":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3085,"end":3144},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3096,"end":3109},"type_parameters":[],"parameters":[["id#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3110,"end":3112}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3120,"end":3127}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3134,"end":3136},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3134,"end":3142}},"is_native":false},"2":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3179,"end":3269},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3190,"end":3203},"type_parameters":[],"parameters":[["bytes#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3204,"end":3209}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3224,"end":3226}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3253,"end":3258},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3233,"end":3259},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3233,"end":3267}},"is_native":false},"3":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3305,"end":3372},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3316,"end":3331},"type_parameters":[],"parameters":[["bytes#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3332,"end":3337}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3349,"end":3351}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3363,"end":3368},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3358,"end":3370}},"is_native":false},"4":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3535,"end":3705},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3539,"end":3555},"type_parameters":[],"parameters":[["ctx#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3556,"end":3559}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3574,"end":3577}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3592,"end":3595},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3592,"end":3604},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3608,"end":3612},"3":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3605,"end":3607},"4":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3584,"end":3632},"6":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3614,"end":3631},"7":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3584,"end":3632},"8":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3668,"end":3694},"9":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3656,"end":3696},"10":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3638,"end":3703}},"is_native":false},"5":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3812,"end":3911},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3832,"end":3837},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3841,"end":3844}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3881,"end":3900},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3869,"end":3902},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":3851,"end":3909}},"is_native":false},"6":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4045,"end":4165},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4065,"end":4084},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4088,"end":4091}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4128,"end":4154},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4116,"end":4156},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4098,"end":4163}},"is_native":false},"7":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4274,"end":4378},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4294,"end":4310},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4314,"end":4317}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4354,"end":4367},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4342,"end":4369},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4324,"end":4376}},"is_native":false},"8":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4492,"end":4613},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4512,"end":4535},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4539,"end":4542}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4579,"end":4602},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4567,"end":4604},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4549,"end":4611}},"is_native":false},"9":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4748,"end":4826},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4752,"end":4758},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4762,"end":4765}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4802,"end":4815},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4790,"end":4817},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4772,"end":4824}},"is_native":false},"10":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4860,"end":4915},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4871,"end":4883},"type_parameters":[],"parameters":[["uid#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4884,"end":4887}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4896,"end":4899}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4907,"end":4910},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4906,"end":4913}},"is_native":false},"11":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4963,"end":5016},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4974,"end":4986},"type_parameters":[],"parameters":[["uid#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4987,"end":4990}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":4999,"end":5001}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5008,"end":5011},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5008,"end":5014}},"is_native":false},"12":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5051,"end":5134},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5062,"end":5074},"type_parameters":[],"parameters":[["uid#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5075,"end":5078}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5087,"end":5097}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5119,"end":5122},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5119,"end":5131},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5118,"end":5131},"3":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5104,"end":5132}},"is_native":false},"13":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5183,"end":5249},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5194,"end":5208},"type_parameters":[],"parameters":[["uid#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5209,"end":5212}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5221,"end":5228}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5235,"end":5238},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5235,"end":5247}},"is_native":false},"14":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5397,"end":5511},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5408,"end":5411},"type_parameters":[],"parameters":[["ctx#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5412,"end":5415}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5434,"end":5437}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5474,"end":5477},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5474,"end":5500},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5462,"end":5502},"3":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5444,"end":5509}},"is_native":false},"15":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5849,"end":5941},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5860,"end":5866},"type_parameters":[],"parameters":[["id#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5867,"end":5869}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5913,"end":5915},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5886,"end":5910},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5896,"end":5908},"3":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5921,"end":5939}},"is_native":false},"16":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5980,"end":6041},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5991,"end":5993},"type_parameters":[["T",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":5994,"end":5995}]],"parameters":[["obj#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6002,"end":6005}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6012,"end":6014}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6032,"end":6035},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6021,"end":6036},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6021,"end":6039}},"is_native":false},"17":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6083,"end":6153},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6094,"end":6103},"type_parameters":[["T",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6104,"end":6105}]],"parameters":[["obj#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6112,"end":6115}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6122,"end":6125}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6144,"end":6147},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6133,"end":6148},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6132,"end":6151}},"is_native":false},"18":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6210,"end":6301},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6221,"end":6229},"type_parameters":[["T",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6230,"end":6231}]],"parameters":[["obj#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6238,"end":6241}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6248,"end":6258}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6291,"end":6294},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6280,"end":6295},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6279,"end":6298},"3":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6265,"end":6299}},"is_native":false},"19":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6360,"end":6440},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6371,"end":6381},"type_parameters":[["T",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6382,"end":6383}]],"parameters":[["obj#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6390,"end":6393}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6400,"end":6407}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6425,"end":6428},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6414,"end":6429},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6414,"end":6438}},"is_native":false},"20":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6750,"end":6795},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6761,"end":6771},"type_parameters":[["T",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6772,"end":6773}]],"parameters":[["obj#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6780,"end":6783}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6790,"end":6794}],"locals":[],"nops":{},"code_map":{},"is_native":true},"21":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6869,"end":6987},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6889,"end":6906},"type_parameters":[],"parameters":[["bytes#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6907,"end":6912}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6924,"end":6927}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6949,"end":6954},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6934,"end":6955},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6976,"end":6981},"3":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6971,"end":6983},"4":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":6961,"end":6985}},"is_native":false},"22":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7041,"end":7077},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7052,"end":7063},"type_parameters":[],"parameters":[["id#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7064,"end":7066}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"23":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7117,"end":7156},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7128,"end":7142},"type_parameters":[],"parameters":[["id#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7143,"end":7145}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"24":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7217,"end":7312},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7228,"end":7240},"type_parameters":[],"parameters":[["ctx#0#0",{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7241,"end":7244}]],"returns":[{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7259,"end":7261}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7280,"end":7283},"1":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7280,"end":7308},"2":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":7268,"end":7310}},"is_native":false},"25":{"location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":102,"end":7312},"definition_location":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":102,"end":7312},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[103,169,24,233,31,232,113,209,174,110,82,17,119,136,52,139,67,161,201,191,142,219,94,29,103,80,209,55,36,30,13,204],"start":102,"end":7312}},"is_native":false}},"constant_map":{"ENotSystemAddress":6,"IOTA_AUTHENTICATOR_STATE_ID":2,"IOTA_BRIDGE_ID":5,"IOTA_CLOCK_OBJECT_ID":1,"IOTA_DENY_LIST_OBJECT_ID":4,"IOTA_RANDOM_ID":3,"IOTA_SYSTEM_STATE_OBJECT_ID":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/tx_context.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/tx_context.json new file mode 100644 index 00000000000..c887b4de4ab --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/Iota/tx_context.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":87,"end":97},"module_name":["0000000000000000000000000000000000000000000000000000000000000002","tx_context"],"struct_map":{"0":{"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":705,"end":714},"type_parameters":[],"fields":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":798,"end":804},{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":859,"end":866},{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":917,"end":922},{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":977,"end":995},{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1146,"end":1157}]}},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1242,"end":1306},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1253,"end":1259},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1260,"end":1264}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1279,"end":1286}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1293,"end":1297},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1293,"end":1304}},"is_native":false},"1":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1421,"end":1491},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1432,"end":1438},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1439,"end":1443}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1458,"end":1469}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1477,"end":1481},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1476,"end":1489}},"is_native":false},"2":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1522,"end":1580},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1533,"end":1538},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1539,"end":1543}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1558,"end":1561}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1568,"end":1572},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1568,"end":1578}},"is_native":false},"3":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1651,"end":1735},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1662,"end":1680},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1681,"end":1685}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1700,"end":1703}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1710,"end":1714},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1710,"end":1733}},"is_native":false},"4":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1938,"end":2140},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1949,"end":1969},"type_parameters":[],"parameters":[["ctx#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1970,"end":1973}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":1992,"end":1999}],"locals":[["id#1#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2049,"end":2051}],["ids_created#1#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2010,"end":2021}]],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2024,"end":2027},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2024,"end":2039},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2010,"end":2021},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2066,"end":2069},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2065,"end":2077},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2064,"end":2077},"7":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2079,"end":2090},"8":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2054,"end":2091},"9":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2049,"end":2051},"10":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2115,"end":2126},"11":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2129,"end":2130},"12":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2127,"end":2128},"13":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2097,"end":2100},"14":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2097,"end":2112},"15":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2097,"end":2130},"16":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2136,"end":2138}},"is_native":false},"5":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2275,"end":2338},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2279,"end":2290},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2291,"end":2295}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2310,"end":2313}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2320,"end":2324},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2320,"end":2336}},"is_native":false},"6":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2412,"end":2481},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2423,"end":2432},"type_parameters":[],"parameters":[["tx_hash#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2433,"end":2440}],["ids_created#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2454,"end":2465}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2473,"end":2480}],"locals":[],"nops":{},"code_map":{},"is_native":true},"7":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2567,"end":2853},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2578,"end":2581},"type_parameters":[],"parameters":[["sender#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2587,"end":2593}],["tx_hash#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2608,"end":2615}],["epoch#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2633,"end":2638}],["epoch_timestamp_ms#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2649,"end":2667}],["ids_created#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2678,"end":2689}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2699,"end":2708}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2723,"end":2730},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2723,"end":2739},"2":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2743,"end":2757},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2740,"end":2742},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2715,"end":2776},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2759,"end":2775},"7":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2715,"end":2776},"8":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2794,"end":2800},"9":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2802,"end":2809},"10":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2811,"end":2816},"11":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2818,"end":2836},"12":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2838,"end":2849},"13":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2782,"end":2851}},"is_native":false},"8":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2948,"end":3176},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2959,"end":2972},"type_parameters":[],"parameters":[["addr#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2978,"end":2982}],["hint#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":2997,"end":3001}],["epoch#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3012,"end":3017}],["epoch_timestamp_ms#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3028,"end":3046}],["ids_created#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3057,"end":3068}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3078,"end":3087}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3098,"end":3102},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3128,"end":3132},"2":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3104,"end":3133},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3135,"end":3140},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3142,"end":3160},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3162,"end":3173},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3094,"end":3174}},"is_native":false},"9":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3234,"end":3386},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3245,"end":3250},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3254,"end":3263}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3361,"end":3365},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3284,"end":3351},"2":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3376,"end":3377},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3379,"end":3380},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3382,"end":3383},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3357,"end":3384}},"is_native":false},"10":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3523,"end":3706},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3527,"end":3550},"type_parameters":[],"parameters":[["hint#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3551,"end":3555}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3563,"end":3573}],"locals":[["tx_hash#1#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3588,"end":3595}]],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3617,"end":3622},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3598,"end":3623},"2":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3584,"end":3595},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3636,"end":3643},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3636,"end":3652},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3655,"end":3669},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3653,"end":3654},"7":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3629,"end":3691},"9":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3671,"end":3678},"10":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3689,"end":3690},"11":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3671,"end":3691},"12":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3629,"end":3691},"13":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3697,"end":3704}},"is_native":false},"11":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3721,"end":3796},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3732,"end":3747},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3748,"end":3752}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3767,"end":3770}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3789,"end":3793},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3777,"end":3794}},"is_native":false},"12":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3857,"end":4053},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3868,"end":3890},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3891,"end":3895}]],"returns":[{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3910,"end":3917}],"locals":[["ids_created#1#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3928,"end":3939}]],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3942,"end":3946},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3942,"end":3958},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3928,"end":3939},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3972,"end":3983},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3986,"end":3987},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3984,"end":3985},"7":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3964,"end":4003},"11":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3989,"end":4002},"12":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":3964,"end":4003},"13":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4021,"end":4025},"14":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4020,"end":4033},"15":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4019,"end":4033},"16":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4035,"end":4046},"17":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4049,"end":4050},"18":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4047,"end":4048},"19":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4009,"end":4051}},"is_native":false},"13":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4068,"end":4159},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4079,"end":4101},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4102,"end":4106}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4143,"end":4147},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4143,"end":4153},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4156,"end":4157},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4154,"end":4155},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4130,"end":4134},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4130,"end":4140},"7":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4130,"end":4157}},"is_native":false},"14":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4174,"end":4316},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4185,"end":4210},"type_parameters":[],"parameters":[["self#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4211,"end":4215}],["delta_ms#0#0",{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4233,"end":4241}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4280,"end":4284},"1":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4280,"end":4303},"3":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4306,"end":4314},"4":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4304,"end":4305},"5":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4254,"end":4258},"6":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4254,"end":4277},"7":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":4254,"end":4314}},"is_native":false},"15":{"location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":75,"end":4316},"definition_location":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":75,"end":4316},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[222,177,27,65,112,21,18,238,244,38,237,149,174,129,82,131,37,75,210,46,15,2,202,133,208,202,6,116,27,117,173,96],"start":75,"end":4316}},"is_native":false}},"constant_map":{"EBadTxHashLength":1,"ENoIDsCreated":2,"TX_HASH_LENGTH":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/MoveStdlib/bcs.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/MoveStdlib/bcs.json new file mode 100644 index 00000000000..f4e75e0597c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/dependencies/MoveStdlib/bcs.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":395,"end":398},"module_name":["0000000000000000000000000000000000000000000000000000000000000001","bcs"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":492,"end":557},"definition_location":{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":510,"end":518},"type_parameters":[["MoveValue",{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":519,"end":528}]],"parameters":[["v#0#0",{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":530,"end":531}]],"returns":[{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":546,"end":556}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":383,"end":557},"definition_location":{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":383,"end":557},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[34,201,103,208,120,108,208,171,127,162,154,113,96,186,51,169,173,216,199,217,88,54,128,150,101,140,27,7,37,201,47,24],"start":383,"end":557}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/m.json new file mode 100644 index 00000000000..f831241d2d6 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":70,"end":71},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{"0":{"definition_location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":88,"end":98},"type_parameters":[],"fields":[{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":113,"end":115},{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":126,"end":129}]}},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":138,"end":321},"definition_location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":142,"end":145},"type_parameters":[],"parameters":[["o#0#0",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":146,"end":147}],["p#0#0",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":161,"end":162}]],"returns":[{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":169,"end":172}],"locals":[["%#1",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":187,"end":201}],["%#2",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":187,"end":212}],["n#1#0",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":183,"end":184}],["num#1#0",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":242,"end":245}]],"nops":{},"code_map":{"0":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":198,"end":200},"1":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":187,"end":201},"4":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":187,"end":212},"6":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":187,"end":215},"7":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":213,"end":214},"8":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":187,"end":215},"10":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":183,"end":184},"11":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":250,"end":251},"12":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":225,"end":247},"13":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":242,"end":245},"14":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":257,"end":275},"15":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":282,"end":283},"16":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":282,"end":290},"17":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":295,"end":298},"18":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":295,"end":305},"19":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":292,"end":293},"20":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":310,"end":311},"21":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":310,"end":318},"22":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":307,"end":308},"23":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":281,"end":319}},"is_native":false},"1":{"location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":331,"end":618},"definition_location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":335,"end":339},"type_parameters":[],"parameters":[],"returns":[],"locals":[["ctx#1#0",{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":356,"end":359}]],"nops":{},"code_map":{"0":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":362,"end":381},"1":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":352,"end":359},"2":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":435,"end":443},"3":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":423,"end":444},"4":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":451,"end":453},"5":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":406,"end":455},"6":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":457,"end":459},"7":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":402,"end":460},"8":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":590,"end":598},"9":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":578,"end":599},"10":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":606,"end":608},"11":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":561,"end":610},"12":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":612,"end":614},"13":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":557,"end":615},"14":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":555,"end":556},"15":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":543,"end":547},"16":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":615,"end":616}},"is_native":false},"2":{"location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":51,"end":618},"definition_location":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":51,"end":618},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[9,0,245,148,110,8,77,217,5,163,139,61,20,43,54,140,85,157,1,225,181,146,97,220,49,193,128,189,216,45,155,5],"start":51,"end":618}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/object.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/object.move new file mode 100644 index 00000000000..cf06883efbc --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/object.move @@ -0,0 +1,234 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/// Iota object identifiers +module iota::object; + +use std::bcs; +use iota::address; + +/// Allows calling `.to_address` on an `ID` to get an `address`. +public use fun id_to_address as ID.to_address; + +/// Allows calling `.to_bytes` on an `ID` to get a `vector`. +public use fun id_to_bytes as ID.to_bytes; + +/// Allows calling `.as_inner` on a `UID` to get an `&ID`. +public use fun uid_as_inner as UID.as_inner; + +/// Allows calling `.to_inner` on a `UID` to get an `ID`. +public use fun uid_to_inner as UID.to_inner; + +/// Allows calling `.to_address` on a `UID` to get an `address`. +public use fun uid_to_address as UID.to_address; + +/// Allows calling `.to_bytes` on a `UID` to get a `vector`. +public use fun uid_to_bytes as UID.to_bytes; + +/// The hardcoded ID for the singleton Iota System State Object. +const IOTA_SYSTEM_STATE_OBJECT_ID: address = @0x5; + +/// The hardcoded ID for the singleton Clock Object. +const IOTA_CLOCK_OBJECT_ID: address = @0x6; + +/// The hardcoded ID for the singleton AuthenticatorState Object. +const IOTA_AUTHENTICATOR_STATE_ID: address = @0x7; + +/// The hardcoded ID for the singleton Random Object. +const IOTA_RANDOM_ID: address = @0x8; + +/// The hardcoded ID for the singleton DenyList. +const IOTA_DENY_LIST_OBJECT_ID: address = @0x403; + +/// The hardcoded ID for the Bridge Object. +const IOTA_BRIDGE_ID: address = @0x9; + +/// Sender is not @0x0 the system address. +const ENotSystemAddress: u64 = 0; + +/// An object ID. This is used to reference Iota Objects. +/// This is *not* guaranteed to be globally unique--anyone can create an `ID` from a `UID` or +/// from an object, and ID's can be freely copied and dropped. +/// Here, the values are not globally unique because there can be multiple values of type `ID` +/// with the same underlying bytes. For example, `object::id(&obj)` can be called as many times +/// as you want for a given `obj`, and each `ID` value will be identical. +public struct ID has copy, drop, store { + // We use `address` instead of `vector` here because `address` has a more + // compact serialization. `address` is serialized as a BCS fixed-length sequence, + // which saves us the length prefix we would pay for if this were `vector`. + // See https://github.com/diem/bcs#fixed-and-variable-length-sequences. + bytes: address, +} + +/// Globally unique IDs that define an object's ID in storage. Any Iota Object, that is a struct +/// with the `key` ability, must have `id: UID` as its first field. +/// These are globally unique in the sense that no two values of type `UID` are ever equal, in +/// other words for any two values `id1: UID` and `id2: UID`, `id1` != `id2`. +/// This is a privileged type that can only be derived from a `TxContext`. +/// `UID` doesn't have the `drop` ability, so deleting a `UID` requires a call to `delete`. +public struct UID has store { + id: ID, +} + +// === id === + +/// Get the raw bytes of a `ID` +public fun id_to_bytes(id: &ID): vector { + bcs::to_bytes(&id.bytes) +} + +/// Get the inner bytes of `id` as an address. +public fun id_to_address(id: &ID): address { + id.bytes +} + +/// Make an `ID` from raw bytes. +public fun id_from_bytes(bytes: vector): ID { + address::from_bytes(bytes).to_id() +} + +/// Make an `ID` from an address. +public fun id_from_address(bytes: address): ID { + ID { bytes } +} + +// === uid === + +#[allow(unused_function)] +/// Create the `UID` for the singleton `IotaSystemState` object. +/// This should only be called once from `iota_system`. +fun iota_system_state(ctx: &TxContext): UID { + assert!(ctx.sender() == @0x0, ENotSystemAddress); + UID { + id: ID { bytes: IOTA_SYSTEM_STATE_OBJECT_ID }, + } +} + +/// Create the `UID` for the singleton `Clock` object. +/// This should only be called once from `clock`. +public(package) fun clock(): UID { + UID { + id: ID { bytes: IOTA_CLOCK_OBJECT_ID }, + } +} + +/// Create the `UID` for the singleton `AuthenticatorState` object. +/// This should only be called once from `authenticator_state`. +public(package) fun authenticator_state(): UID { + UID { + id: ID { bytes: IOTA_AUTHENTICATOR_STATE_ID }, + } +} + +/// Create the `UID` for the singleton `Random` object. +/// This should only be called once from `random`. +public(package) fun randomness_state(): UID { + UID { + id: ID { bytes: IOTA_RANDOM_ID }, + } +} + +/// Create the `UID` for the singleton `DenyList` object. +/// This should only be called once from `deny_list`. +public(package) fun iota_deny_list_object_id(): UID { + UID { + id: ID { bytes: IOTA_DENY_LIST_OBJECT_ID }, + } +} + +#[allow(unused_function)] +/// Create the `UID` for the singleton `Bridge` object. +/// This should only be called once from `bridge`. +fun bridge(): UID { + UID { + id: ID { bytes: IOTA_BRIDGE_ID }, + } +} + +/// Get the inner `ID` of `uid` +public fun uid_as_inner(uid: &UID): &ID { + &uid.id +} + +/// Get the raw bytes of a `uid`'s inner `ID` +public fun uid_to_inner(uid: &UID): ID { + uid.id +} + +/// Get the raw bytes of a `UID` +public fun uid_to_bytes(uid: &UID): vector { + bcs::to_bytes(&uid.id.bytes) +} + +/// Get the inner bytes of `id` as an address. +public fun uid_to_address(uid: &UID): address { + uid.id.bytes +} + +// === any object === + +/// Create a new object. Returns the `UID` that must be stored in a Iota object. +/// This is the only way to create `UID`s. +public fun new(ctx: &mut TxContext): UID { + UID { + id: ID { bytes: ctx.fresh_object_address() }, + } +} + +/// Delete the object and it's `UID`. This is the only way to eliminate a `UID`. +// This exists to inform Iota of object deletions. When an object +// gets unpacked, the programmer will have to do something with its +// `UID`. The implementation of this function emits a deleted +// system event so Iota knows to process the object deletion +public fun delete(id: UID) { + let UID { id: ID { bytes } } = id; + delete_impl(bytes) +} + +/// Get the underlying `ID` of `obj` +public fun id(obj: &T): ID { + borrow_uid(obj).id +} + +/// Borrow the underlying `ID` of `obj` +public fun borrow_id(obj: &T): &ID { + &borrow_uid(obj).id +} + +/// Get the raw bytes for the underlying `ID` of `obj` +public fun id_bytes(obj: &T): vector { + bcs::to_bytes(&borrow_uid(obj).id) +} + +/// Get the inner bytes for the underlying `ID` of `obj` +public fun id_address(obj: &T): address { + borrow_uid(obj).id.bytes +} + +/// Get the `UID` for `obj`. +/// Safe because Iota has an extra bytecode verifier pass that forces every struct with +/// the `key` ability to have a distinguished `UID` field. +/// Cannot be made public as the access to `UID` for a given object must be privileged, and +/// restrictable in the object's module. +native fun borrow_uid(obj: &T): &UID; + +/// Generate a new UID specifically used for creating a UID from a hash +public(package) fun new_uid_from_hash(bytes: address): UID { + record_new_uid(bytes); + UID { id: ID { bytes } } +} + +// === internal functions === + +// helper for delete +native fun delete_impl(id: address); + +// marks newly created UIDs from hash +native fun record_new_uid(id: address); + +#[test_only] +/// Return the most recent created object ID. +public fun last_created(ctx: &TxContext): ID { + ID { bytes: ctx.last_created_object_id() } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/tx_context.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/tx_context.move new file mode 100644 index 00000000000..3d297c2b04a --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/Iota/tx_context.move @@ -0,0 +1,142 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module iota::tx_context; + +#[test_only] +/// Number of bytes in an tx hash (which will be the transaction digest) +const TX_HASH_LENGTH: u64 = 32; + +#[test_only] +/// Expected an tx hash of length 32, but found a different length +const EBadTxHashLength: u64 = 0; + +#[test_only] +/// Attempt to get the most recent created object ID when none has been created. +const ENoIDsCreated: u64 = 1; + +/// Information about the transaction currently being executed. +/// This cannot be constructed by a transaction--it is a privileged object created by +/// the VM and passed in to the entrypoint of the transaction as `&mut TxContext`. +public struct TxContext has drop { + /// The address of the user that signed the current transaction + sender: address, + /// Hash of the current transaction + tx_hash: vector, + /// The current epoch number + epoch: u64, + /// Timestamp that the epoch started at + epoch_timestamp_ms: u64, + /// Counter recording the number of fresh id's created while executing + /// this transaction. Always 0 at the start of a transaction + ids_created: u64, +} + +/// Return the address of the user that signed the current +/// transaction +public fun sender(self: &TxContext): address { + self.sender +} + +/// Return the transaction digest (hash of transaction inputs). +/// Please do not use as a source of randomness. +public fun digest(self: &TxContext): &vector { + &self.tx_hash +} + +/// Return the current epoch +public fun epoch(self: &TxContext): u64 { + self.epoch +} + +/// Return the epoch start time as a unix timestamp in milliseconds. +public fun epoch_timestamp_ms(self: &TxContext): u64 { + self.epoch_timestamp_ms +} + +/// Create an `address` that has not been used. As it is an object address, it will never +/// occur as the address for a user. +/// In other words, the generated address is a globally unique object ID. +public fun fresh_object_address(ctx: &mut TxContext): address { + let ids_created = ctx.ids_created; + let id = derive_id(*&ctx.tx_hash, ids_created); + ctx.ids_created = ids_created + 1; + id +} + +#[allow(unused_function)] +/// Return the number of id's created by the current transaction. +/// Hidden for now, but may expose later +fun ids_created(self: &TxContext): u64 { + self.ids_created +} + +/// Native function for deriving an ID via hash(tx_hash || ids_created) +native fun derive_id(tx_hash: vector, ids_created: u64): address; + +// ==== test-only functions ==== + +#[test_only] +/// Create a `TxContext` for testing +public fun new( + sender: address, + tx_hash: vector, + epoch: u64, + epoch_timestamp_ms: u64, + ids_created: u64, +): TxContext { + assert!(tx_hash.length() == TX_HASH_LENGTH, EBadTxHashLength); + TxContext { sender, tx_hash, epoch, epoch_timestamp_ms, ids_created } +} + +#[test_only] +/// Create a `TxContext` for testing, with a potentially non-zero epoch number. +public fun new_from_hint( + addr: address, + hint: u64, + epoch: u64, + epoch_timestamp_ms: u64, + ids_created: u64, +): TxContext { + new(addr, dummy_tx_hash_with_hint(hint), epoch, epoch_timestamp_ms, ids_created) +} + +#[test_only] +/// Create a dummy `TxContext` for testing +public fun dummy(): TxContext { + let tx_hash = x"3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"; + new(@0x0, tx_hash, 0, 0, 0) +} + +#[test_only] +/// Utility for creating 256 unique input hashes. +/// These hashes are guaranteed to be unique given a unique `hint: u64` +fun dummy_tx_hash_with_hint(hint: u64): vector { + let mut tx_hash = std::bcs::to_bytes(&hint); + while (tx_hash.length() < TX_HASH_LENGTH) tx_hash.push_back(0); + tx_hash +} + +#[test_only] +public fun get_ids_created(self: &TxContext): u64 { + ids_created(self) +} + +#[test_only] +/// Return the most recent created object ID. +public fun last_created_object_id(self: &TxContext): address { + let ids_created = self.ids_created; + assert!(ids_created > 0, ENoIDsCreated); + derive_id(*&self.tx_hash, ids_created - 1) +} + +#[test_only] +public fun increment_epoch_number(self: &mut TxContext) { + self.epoch = self.epoch + 1 +} + +#[test_only] +public fun increment_epoch_timestamp(self: &mut TxContext, delta_ms: u64) { + self.epoch_timestamp_ms = self.epoch_timestamp_ms + delta_ms +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/MoveStdlib/bcs.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/MoveStdlib/bcs.move new file mode 100644 index 00000000000..12ef11705bd --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/dependencies/MoveStdlib/bcs.move @@ -0,0 +1,12 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/// Utility for converting a Move value to its binary representation in BCS (Binary Canonical +/// Serialization). BCS is the binary encoding for Move resources and other non-module values +/// published on-chain. See https://github.com/diem/bcs#binary-canonical-serialization-bcs for more +/// details on BCS. +module std::bcs; + +/// Return the binary representation of `v` in BCS (Binary Canonical Serialization) format +public native fun to_bytes(v: &MoveValue): vector; diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/m.move new file mode 100644 index 00000000000..86c1a237632 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/build/global_loc/sources/m.move @@ -0,0 +1,22 @@ +// Test handling of global locations in the trace. +module global_loc::m; + +public struct SomeObject has key { + id: UID, + num: u8, +} + +fun foo(o: SomeObject, p: u8): u64 { + let n = object::id(&o).to_bytes()[0]; + let SomeObject { id, num } = o; + object::delete(id); + (n as u64) + (num as u64) + (p as u64) +} + +#[test] +fun test() { + let mut ctx = tx_context::dummy(); + let mut _res = foo(SomeObject { id: object::new(&mut ctx), num: 42 }, 42); + // line below is to force another unoptimized read to keep `res` visible + _res = _res + foo(SomeObject { id: object::new(&mut ctx), num: 42 }, 42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/sources/m.move new file mode 100644 index 00000000000..86c1a237632 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/sources/m.move @@ -0,0 +1,22 @@ +// Test handling of global locations in the trace. +module global_loc::m; + +public struct SomeObject has key { + id: UID, + num: u8, +} + +fun foo(o: SomeObject, p: u8): u64 { + let n = object::id(&o).to_bytes()[0]; + let SomeObject { id, num } = o; + object::delete(id); + (n as u64) + (num as u64) + (p as u64) +} + +#[test] +fun test() { + let mut ctx = tx_context::dummy(); + let mut _res = foo(SomeObject { id: object::new(&mut ctx), num: 42 }, 42); + // line below is to force another unoptimized read to keep `res` visible + _res = _res + foo(SomeObject { id: object::new(&mut ctx), num: 42 }, 42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/test.exp new file mode 100644 index 00000000000..513397bd9d6 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/test.exp @@ -0,0 +1,45 @@ +current frame stack: + function: test (m.move:21) + scope 0 : + ctx : (0x2::tx_context::TxContext) { + sender : 0000000000000000000000000000000000000000000000000000000000000000 + tx_hash : [ + 0 : 58 + 1 : 152 + 2 : 93 + 3 : 167 + 4 : 79 + 5 : 226 + 6 : 37 + 7 : 178 + 8 : 4 + 9 : 92 + 10 : 23 + 11 : 45 + 12 : 107 + 13 : 211 + 14 : 144 + 15 : 189 + 16 : 133 + 17 : 95 + 18 : 8 + 19 : 110 + 20 : 62 + 21 : 157 + 22 : 82 + 23 : 91 + 24 : 70 + 25 : 191 + 26 : 226 + 27 : 69 + 28 : 17 + 29 : 67 + 30 : 21 + 31 : 50 + ] + epoch : 0 + epoch_timestamp_ms : 0 + ids_created : 1 + } + type: 0x2::tx_context::TxContext + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/trace.spec.js new file mode 100644 index 00000000000..12de693d855 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/trace.spec.js @@ -0,0 +1,10 @@ +let action = (runtime) => { + let res = ''; + // step over context creation + runtime.step(true); + // step over function creating a global location + runtime.step(true); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/traces/global_loc__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/traces/global_loc__m__test.json new file mode 100644 index 00000000000..844dd32b381 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/global_loc/traces/global_loc__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"dummy","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"tx_context"},"binary_member_index":9,"type_instantiation":[],"parameters":[],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":null}],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999965,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":"0000000000000000000000000000000000000000000000000000000000000000"}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999930,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999927,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999924,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999921,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999921,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":14,"function_name":"new","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"tx_context"},"binary_member_index":7,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":"0000000000000000000000000000000000000000000000000000000000000000"}},{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}},{"RuntimeValue":{"value":0}},{"RuntimeValue":{"value":0}},{"RuntimeValue":{"value":0}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":"address","ref_type":null},{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999921}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999910,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[14,1]},"root_value_read":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[14,1]},"snapshot":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999907,"instruction":"VEC_LEN"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[14,1]},"snapshot":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":32}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999897,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":32}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999862,"instruction":"EQ"}},{"Effect":{"Pop":{"RuntimeValue":{"value":32}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":32}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999861,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999860,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999826,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[14,0]},"root_value_read":{"RuntimeValue":{"value":"0000000000000000000000000000000000000000000000000000000000000000"}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":"0000000000000000000000000000000000000000000000000000000000000000"}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999792,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[14,1]},"root_value_read":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999774,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[14,2]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999756,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[14,3]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999738,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[14,4]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999734,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":"0000000000000000000000000000000000000000000000000000000000000000"}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999733,"instruction":"RET"}},{"CloseFrame":{"frame_id":14,"return_":[{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}],"gas_left":999999733}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999732,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}],"gas_left":999999732}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999731,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999721,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999721,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":63,"function_name":"new","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":14,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"UID","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":"Mut"}],"is_native":false},"gas_left":999999721}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999710,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[63,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999710,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":68,"function_name":"fresh_object_address","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"tx_context"},"binary_member_index":4,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}],"return_types":[{"type_":"address","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":"Mut"},{"type_":"address","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999710}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999699,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999689,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999671,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},4]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999670,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[68,2]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999660,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999650,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999616,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},1]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999598,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,2]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999598,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":96,"function_name":"derive_id","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"tx_context"},"binary_member_index":6,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}},{"RuntimeValue":{"value":0}}],"return_types":[{"type_":"address","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u64","ref_type":null}],"is_native":true},"gas_left":999999598}},{"Effect":{"Push":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},{"CloseFrame":{"frame_id":96,"return_":[{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}],"gas_left":999999511}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999510,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},{"Effect":{"Write":{"location":{"Local":[68,1]},"root_value_after_write":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999492,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,2]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999489,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999486,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999476,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999466,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999448,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":0}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,0]},4]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999414,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,1]},"root_value_read":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999413,"instruction":"RET"}},{"CloseFrame":{"frame_id":68,"return_":[{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}],"gas_left":999999413}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999409,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999405,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999404,"instruction":"RET"}},{"CloseFrame":{"frame_id":63,"return_":[{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}],"gas_left":999999404}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999401,"instruction":"LD_U8"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999397,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999394,"instruction":"LD_U8"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999394,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":143,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}},{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}},"ref_type":null},{"type_":"u8","ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"ID","type_args":[]}},"ref_type":null},{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u8","ref_type":null},{"type_":"u8","ref_type":null}],"is_native":false},"gas_left":999999394}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999383,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[143,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999383,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":148,"function_name":"id","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":16,"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}}],"parameters":[{"ImmRef":{"location":{"Local":[143,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"ID","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999999383}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999372,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[148,0]},"root_value_read":{"ImmRef":{"location":{"Local":[143,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[143,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999372,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":153,"function_name":"borrow_uid","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":20,"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}}],"parameters":[{"ImmRef":{"location":{"Local":[143,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"UID","type_args":[]}},"ref_type":"Imm"}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}},"ref_type":"Imm"}],"is_native":true},"gas_left":999999372}},{"Effect":{"DataLoad":{"ref_type":"Imm","location":{"Global":154},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Global":154},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"CloseFrame":{"frame_id":153,"return_":[{"ImmRef":{"location":{"Global":154},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}],"gas_left":999999309}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999299,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Global":154},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Global":154},0]},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999263,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Global":154},0]},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Global":154},0]},"root_value_read":{"ImmRef":{"location":{"Global":154},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999262,"instruction":"RET"}},{"CloseFrame":{"frame_id":148,"return_":[{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}],"gas_left":999999262}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999261,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Effect":{"Write":{"location":{"Local":[143,2]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999251,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,2]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[143,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999251,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":173,"function_name":"id_to_bytes","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[143,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}],"return_types":[{"type_":{"vector":"u8"},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"ID","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999999251}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999240,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[173,0]},"root_value_read":{"ImmRef":{"location":{"Local":[143,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[143,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999230,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[143,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[143,2]},0]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999230,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":181,"function_name":"to_bytes","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"bcs"},"binary_member_index":0,"type_instantiation":["address"],"parameters":[{"ImmRef":{"location":{"Indexed":[{"Local":[143,2]},0]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}],"return_types":[{"type_":{"vector":"u8"},"ref_type":null}],"locals_types":[{"type_":"address","ref_type":"Imm"}],"is_native":true},"gas_left":999999230}},{"Effect":{"Push":{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}},{"CloseFrame":{"frame_id":181,"return_":[{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}],"gas_left":999999131}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999130,"instruction":"RET"}},{"CloseFrame":{"frame_id":173,"return_":[{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}],"gas_left":999999130}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999129,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}},{"Effect":{"Write":{"location":{"Local":[143,3]},"root_value_after_write":{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999119,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,3]},"root_value_read":{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[143,3]},"snapshot":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999116,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999106,"instruction":"VEC_IMM_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[143,3]},"snapshot":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[143,3]},0]},"snapshot":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999088,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[143,3]},0]},"snapshot":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[143,3]},0]},"root_value_read":{"RuntimeValue":{"value":[56,29,217,7,140,50,42,70,99,195,146,118,26,2,17,181,39,193,39,178,149,131,133,18,23,249,72,214,33,49,244,9]}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":56}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999087,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":56}}}},{"Effect":{"Write":{"location":{"Local":[143,4]},"root_value_after_write":{"RuntimeValue":{"value":56}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999031,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999028,"instruction":"UNPACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},"num":42}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999027,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Local":[143,5]},"root_value_after_write":{"RuntimeValue":{"value":42}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999027,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":216,"function_name":"delete","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":15,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}],"return_types":[],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"UID","type_args":[]}},"ref_type":null}],"is_native":false},"gas_left":999999027}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998988,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[216,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998986,"instruction":"UNPACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998984,"instruction":"UNPACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998984,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":227,"function_name":"delete_impl","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":22,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":"381dd9078c322a4663c392761a0211b527c127b29583851217f948d62131f409"}}],"return_types":[],"locals_types":[{"type_":"address","ref_type":null}],"is_native":true},"gas_left":999998984}},{"CloseFrame":{"frame_id":227,"return_":[],"gas_left":999998930}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999998929,"instruction":"RET"}},{"CloseFrame":{"frame_id":216,"return_":[],"gas_left":999998929}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999998911,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,4]},"root_value_read":{"RuntimeValue":{"value":56}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":56}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999998908,"instruction":"CAST_U64"}},{"Effect":{"Pop":{"RuntimeValue":{"value":56}}}},{"Effect":{"Push":{"RuntimeValue":{"value":56}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999998890,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,5]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999998887,"instruction":"CAST_U64"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999998884,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":56}}}},{"Effect":{"Push":{"RuntimeValue":{"value":98}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999998866,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[143,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999998863,"instruction":"CAST_U64"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999998860,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":98}}}},{"Effect":{"Push":{"RuntimeValue":{"value":140}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999998859,"instruction":"RET"}},{"CloseFrame":{"frame_id":143,"return_":[{"RuntimeValue":{"value":140}}],"gas_left":999998859}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999998849,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999998849,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":263,"function_name":"new","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":14,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"UID","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":"Mut"}],"is_native":false},"gas_left":999998849}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998838,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[263,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998838,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":268,"function_name":"fresh_object_address","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"tx_context"},"binary_member_index":4,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}],"return_types":[{"type_":"address","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"tx_context","name":"TxContext","type_args":[]}},"ref_type":"Mut"},{"type_":"address","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999998838}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998827,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[268,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998817,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998799,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},4]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998798,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[268,2]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999998788,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[268,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999998778,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999998744,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},1]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999998726,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[268,2]},"root_value_read":{"RuntimeValue":{"value":1}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999998726,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":296,"function_name":"derive_id","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"tx_context"},"binary_member_index":6,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50]}},{"RuntimeValue":{"value":1}}],"return_types":[{"type_":"address","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u64","ref_type":null}],"is_native":true},"gas_left":999998726}},{"Effect":{"Push":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},{"CloseFrame":{"frame_id":296,"return_":[{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}],"gas_left":999998639}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999998638,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},{"Effect":{"Write":{"location":{"Local":[268,1]},"root_value_after_write":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999998620,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[268,2]},"root_value_read":{"RuntimeValue":{"value":1}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999998617,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999998614,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999998604,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[268,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999998594,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999998576,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},4]},"snapshot":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":1}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,0]},4]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x2::tx_context::TxContext","fields":{"sender":"0000000000000000000000000000000000000000000000000000000000000000","tx_hash":[58,152,93,167,79,226,37,178,4,92,23,45,107,211,144,189,133,95,8,110,62,157,82,91,70,191,226,69,17,67,21,50],"epoch":0,"epoch_timestamp_ms":0,"ids_created":2}}}}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999998542,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[268,1]},"root_value_read":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999998541,"instruction":"RET"}},{"CloseFrame":{"frame_id":268,"return_":[{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}],"gas_left":999998541}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998537,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998533,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999998532,"instruction":"RET"}},{"CloseFrame":{"frame_id":263,"return_":[{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}],"gas_left":999998532}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999998529,"instruction":"LD_U8"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999998525,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999998522,"instruction":"LD_U8"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999998522,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":343,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}},{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}},"ref_type":null},{"type_":"u8","ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"ID","type_args":[]}},"ref_type":null},{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u8","ref_type":null},{"type_":"u8","ref_type":null}],"is_native":false},"gas_left":999998522}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998511,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[343,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998511,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":348,"function_name":"id","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":16,"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}}],"parameters":[{"ImmRef":{"location":{"Local":[343,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"ID","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999998511}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998500,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[348,0]},"root_value_read":{"ImmRef":{"location":{"Local":[343,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[343,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998500,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":353,"function_name":"borrow_uid","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":20,"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}}],"parameters":[{"ImmRef":{"location":{"Local":[343,0]},"snapshot":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"UID","type_args":[]}},"ref_type":"Imm"}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeObject","type_args":[]}},"ref_type":"Imm"}],"is_native":true},"gas_left":999998500}},{"Effect":{"DataLoad":{"ref_type":"Imm","location":{"Global":354},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Global":354},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"CloseFrame":{"frame_id":353,"return_":[{"ImmRef":{"location":{"Global":354},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}],"gas_left":999998437}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998427,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Global":354},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Global":354},0]},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998391,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Global":354},0]},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Global":354},0]},"root_value_read":{"ImmRef":{"location":{"Global":354},"snapshot":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999998390,"instruction":"RET"}},{"CloseFrame":{"frame_id":348,"return_":[{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}],"gas_left":999998390}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998389,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Effect":{"Write":{"location":{"Local":[343,2]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998379,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,2]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[343,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999998379,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":373,"function_name":"id_to_bytes","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[343,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}],"return_types":[{"type_":{"vector":"u8"},"ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"ID","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999998379}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998368,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[373,0]},"root_value_read":{"ImmRef":{"location":{"Local":[343,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[343,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998358,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[343,2]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[343,2]},0]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998358,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":381,"function_name":"to_bytes","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"bcs"},"binary_member_index":0,"type_instantiation":["address"],"parameters":[{"ImmRef":{"location":{"Indexed":[{"Local":[343,2]},0]},"snapshot":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}],"return_types":[{"type_":{"vector":"u8"},"ref_type":null}],"locals_types":[{"type_":"address","ref_type":"Imm"}],"is_native":true},"gas_left":999998358}},{"Effect":{"Push":{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}},{"CloseFrame":{"frame_id":381,"return_":[{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}],"gas_left":999998259}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998258,"instruction":"RET"}},{"CloseFrame":{"frame_id":373,"return_":[{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}],"gas_left":999998258}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999998257,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}},{"Effect":{"Write":{"location":{"Local":[343,3]},"root_value_after_write":{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999998247,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,3]},"root_value_read":{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[343,3]},"snapshot":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999998244,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999998234,"instruction":"VEC_IMM_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[343,3]},"snapshot":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[343,3]},0]},"snapshot":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999998216,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[343,3]},0]},"snapshot":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[343,3]},0]},"root_value_read":{"RuntimeValue":{"value":[238,254,212,242,183,246,173,95,101,214,234,46,239,80,180,241,209,233,140,57,202,142,236,188,151,54,218,128,27,131,135,230]}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":238}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999998215,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":238}}}},{"Effect":{"Write":{"location":{"Local":[343,4]},"root_value_after_write":{"RuntimeValue":{"value":238}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999998159,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999998156,"instruction":"UNPACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeObject","fields":{"id":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},"num":42}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999998155,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Local":[343,5]},"root_value_after_write":{"RuntimeValue":{"value":42}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999998155,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":416,"function_name":"delete","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":15,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}],"return_types":[],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000002","module":"object","name":"UID","type_args":[]}},"ref_type":null}],"is_native":false},"gas_left":999998155}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999998116,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[416,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999998114,"instruction":"UNPACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::UID","fields":{"id":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999998112,"instruction":"UNPACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x2::object::ID","fields":{"bytes":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999998112,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":427,"function_name":"delete_impl","module":{"address":"0000000000000000000000000000000000000000000000000000000000000002","name":"object"},"binary_member_index":22,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":"eefed4f2b7f6ad5f65d6ea2eef50b4f1d1e98c39ca8eecbc9736da801b8387e6"}}],"return_types":[],"locals_types":[{"type_":"address","ref_type":null}],"is_native":true},"gas_left":999998112}},{"CloseFrame":{"frame_id":427,"return_":[],"gas_left":999998058}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999998057,"instruction":"RET"}},{"CloseFrame":{"frame_id":416,"return_":[],"gas_left":999998057}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999998039,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,4]},"root_value_read":{"RuntimeValue":{"value":238}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":238}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999998036,"instruction":"CAST_U64"}},{"Effect":{"Pop":{"RuntimeValue":{"value":238}}}},{"Effect":{"Push":{"RuntimeValue":{"value":238}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999998018,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,5]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999998015,"instruction":"CAST_U64"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999998012,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":238}}}},{"Effect":{"Push":{"RuntimeValue":{"value":280}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999997994,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[343,1]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999997991,"instruction":"CAST_U64"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999997988,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":280}}}},{"Effect":{"Push":{"RuntimeValue":{"value":322}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999997987,"instruction":"RET"}},{"CloseFrame":{"frame_id":343,"return_":[{"RuntimeValue":{"value":322}}],"gas_left":999997987}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999997984,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":322}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":140}}}},{"Effect":{"Push":{"RuntimeValue":{"value":462}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999997983,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":462}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999997982,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999997982}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/Move.toml new file mode 100644 index 00000000000..5535891fbcd --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_abort" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_abort = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..6f778980be453165dc0b15ec5d6bf254274fd3ba GIT binary patch literal 294 zcmbtQK?=e^3`{n=+jf&f3(|^+XP==jsUmIJgI#IsgFN~+KjF5hA8oM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m.json new file mode 100644 index 00000000000..7baa9a89dc2 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":53,"end":54},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":87,"end":189},"definition_location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":98,"end":101},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":105,"end":108}],"locals":[["%#2",{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":152,"end":157}],["%#3",{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":135,"end":138}],["%#5",{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":181,"end":186}],["%#6",{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":135,"end":138}],["ret#1#1",{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":100,"end":103}],["ret#1#5",{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":100,"end":103}],["v#1#0",{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":119,"end":120}],["x#1#4",{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":149,"end":150}],["x#2#8",{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":178,"end":179}]],"nops":{},"code_map":{"0":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":106,"end":123},"1":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":96,"end":103},"2":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":135,"end":138},"4":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":144,"end":147},"5":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":149,"end":150},"6":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":152,"end":153},"7":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":156,"end":157},"8":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":154,"end":155},"9":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":152,"end":157},"10":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":135,"end":138},"11":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":152,"end":157},"12":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":139,"end":140},"13":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":119,"end":120},"14":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":174,"end":175},"16":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":114,"end":115},"17":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":96,"end":103},"18":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":135,"end":138},"20":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":144,"end":147},"21":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":178,"end":179},"22":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":181,"end":182},"23":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":185,"end":186},"24":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":183,"end":184},"25":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":181,"end":186},"26":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":135,"end":138},"27":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":181,"end":186},"28":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":139,"end":140},"29":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":169,"end":187}},"is_native":false},"1":{"location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":199,"end":231},"definition_location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":210,"end":214},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":223,"end":228},"2":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":228,"end":229}},"is_native":false},"2":{"location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":33,"end":231},"definition_location":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":33,"end":231},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[83,91,211,158,180,198,69,95,158,81,23,109,97,57,192,38,157,110,94,170,105,20,146,79,231,8,91,46,169,111,186,51],"start":33,"end":231}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m_dep.json new file mode 100644 index 00000000000..15539921483 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":20,"end":25},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":0,"end":159},"definition_location":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":0,"end":159},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[130,117,191,224,79,113,117,73,60,63,155,240,111,105,66,214,129,111,67,120,159,65,113,46,26,198,10,158,166,30,230,47],"start":0,"end":159}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m.move new file mode 100644 index 00000000000..760303cfbd3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m.move @@ -0,0 +1,17 @@ +// Test aborting inside a macro. +module macro_abort::m; + +use macro_abort::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m_dep.move new file mode 100644 index 00000000000..34cc42810fe --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/build/macro_abort/sources/m_dep.move @@ -0,0 +1,7 @@ +module macro_abort::m_dep; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret - $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m.move new file mode 100644 index 00000000000..760303cfbd3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m.move @@ -0,0 +1,17 @@ +// Test aborting inside a macro. +module macro_abort::m; + +use macro_abort::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m_dep.move new file mode 100644 index 00000000000..34cc42810fe --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/sources/m_dep.move @@ -0,0 +1,7 @@ +module macro_abort::m_dep; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret - $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/test.exp new file mode 100644 index 00000000000..2e30fe5759d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/test.exp @@ -0,0 +1 @@ +Exception \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/trace.spec.js new file mode 100644 index 00000000000..1cb103a0b9e --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/trace.spec.js @@ -0,0 +1,9 @@ +const { ExecutionResult } = require('../../out/runtime'); + +let action = (runtime) => { + let res = ''; + // continue to reach abort due to incorrect arithmetics + res += ExecutionResult[runtime.continue()]; + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/traces/macro_abort__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/traces/macro_abort__m__test.json new file mode 100644 index 00000000000..20bc35695fe --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_abort/traces/macro_abort__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"SUB"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/Move.toml new file mode 100644 index 00000000000..6f4aaa2f9d0 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_breakpoint" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_breakpoint = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..860fd9802d70e97638b75593faf91a5b890728e6 GIT binary patch literal 294 zcmbtQK?=e^3`{n=+jf&f3$loaXP==jsUmIJgI#IsgFN~+KjF5hA8g%hP{A95W*`j! literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m.json new file mode 100644 index 00000000000..9577c66b826 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":68,"end":69},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":107,"end":209},"definition_location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":118,"end":121},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":125,"end":128}],"locals":[["%#2",{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":172,"end":177}],["%#3",{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":140,"end":143}],["%#5",{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":201,"end":206}],["%#6",{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":140,"end":143}],["ret#1#1",{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":105,"end":108}],["ret#1#5",{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":105,"end":108}],["v#1#0",{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":139,"end":140}],["x#1#4",{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":169,"end":170}],["x#2#8",{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":198,"end":199}]],"nops":{},"code_map":{"0":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":111,"end":128},"1":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":101,"end":108},"2":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":140,"end":143},"4":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":149,"end":152},"5":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":169,"end":170},"6":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":172,"end":173},"7":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":176,"end":177},"8":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":174,"end":175},"9":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":172,"end":177},"10":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":140,"end":143},"11":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":172,"end":177},"12":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":144,"end":145},"13":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":139,"end":140},"14":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":194,"end":195},"16":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":119,"end":120},"17":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":101,"end":108},"18":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":140,"end":143},"20":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":149,"end":152},"21":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":198,"end":199},"22":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":201,"end":202},"23":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":205,"end":206},"24":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":203,"end":204},"25":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":201,"end":206},"26":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":140,"end":143},"27":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":201,"end":206},"28":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":144,"end":145},"29":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":189,"end":207}},"is_native":false},"1":{"location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":219,"end":251},"definition_location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":230,"end":234},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":243,"end":248},"2":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":248,"end":249}},"is_native":false},"2":{"location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":43,"end":251},"definition_location":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":43,"end":251},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[120,8,1,106,147,6,207,254,197,43,223,249,199,170,79,101,109,86,222,168,6,134,111,229,38,55,101,165,203,207,119,160],"start":43,"end":251}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m_dep.json new file mode 100644 index 00000000000..73b832f880b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":25,"end":30},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":0,"end":164},"definition_location":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":0,"end":164},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[231,65,62,90,130,17,198,226,86,171,104,146,237,181,219,127,61,55,189,46,228,222,156,26,242,227,58,211,159,103,229,205],"start":0,"end":164}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m.move new file mode 100644 index 00000000000..40b32df9476 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m.move @@ -0,0 +1,17 @@ +// Test setting breakpoint inside a macro. +module macro_breakpoint::m; + +use macro_breakpoint::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m_dep.move new file mode 100644 index 00000000000..7c0171df88c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/build/macro_breakpoint/sources/m_dep.move @@ -0,0 +1,7 @@ +module macro_breakpoint::m_dep; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m.move new file mode 100644 index 00000000000..40b32df9476 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m.move @@ -0,0 +1,17 @@ +// Test setting breakpoint inside a macro. +module macro_breakpoint::m; + +use macro_breakpoint::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m_dep.move new file mode 100644 index 00000000000..7c0171df88c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/sources/m_dep.move @@ -0,0 +1,7 @@ +module macro_breakpoint::m_dep; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/test.exp new file mode 100644 index 00000000000..cabee7ac778 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/test.exp @@ -0,0 +1,10 @@ +current frame stack: + function: test (m.move:16) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:4) + scope 0 : +line breakpoints + m_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/trace.spec.js new file mode 100644 index 00000000000..2200aae5f34 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/trace.spec.js @@ -0,0 +1,12 @@ +const path = require('path'); + +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep.move`); + let res = ''; + runtime.setLineBreakpoints(filePath, [4]); + // continue to the breakpoint set in the macro + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/traces/macro_breakpoint__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/traces/macro_breakpoint__m__test.json new file mode 100644 index 00000000000..b9c523cb63f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_breakpoint/traces/macro_breakpoint__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999877,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":6}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999859,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999841,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999838,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999837,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999819,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999818,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999800,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999799,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999781,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999763,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999760,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999759,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999741,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999723,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999720,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999719,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":36}}],"gas_left":999999719}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999718,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999717,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999717}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/Move.toml new file mode 100644 index 00000000000..4de7b69935c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_different_different_files" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_different_different_files = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..c0586490cc981e9665477fe3a80d89acd5f14f6d GIT binary patch literal 300 zcmbtQK?=e^3`{oJZM(@qK^75Do_vPBq=>Y#2fNbN2YK{ue!^{0Ki~|3ObA0JkL^nw z05}9DUfK1c*dNPy&?mNFkO4D+@&?#kS>+z7qA$?v=G-@@v8ji6>6(71+tk-%GmNpj zP@587c~aHAi{m_B{JQ#<;*h$@{SVA1nw{g1hq7lyVJ&oM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m_dep_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/bytecode_modules/m_dep_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..b864448837dcebb55246313da3f48a86fafa7615 GIT binary patch literal 196 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fnBgBDc3ZpOsBO?<7GfsAf RbO{Rs0}IH-U?2!`A^C literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m.json new file mode 100644 index 00000000000..e2f6e101670 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":235,"end":236},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":289,"end":391},"definition_location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":300,"end":303},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":307,"end":310}],"locals":[["%#3",{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":354,"end":359}],["%#4",{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":215,"end":218}],["%#7",{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":383,"end":388}],["%#8",{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":215,"end":218}],["ret#1#1",{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":174,"end":177}],["ret#1#8",{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":174,"end":177}],["v#1#0",{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":321,"end":322}],["x#1#4",{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":351,"end":352}],["x#2#11",{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":380,"end":381}]],"nops":{},"code_map":{"0":{"file_hash":[31,75,248,230,38,255,48,178,141,227,79,21,190,81,225,174,10,106,91,83,133,83,131,144,26,62,46,57,147,60,8,151],"start":103,"end":110},"1":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":170,"end":177},"2":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":215,"end":218},"4":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":224,"end":227},"5":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":351,"end":352},"6":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":354,"end":355},"7":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":358,"end":359},"8":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":356,"end":357},"9":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":354,"end":359},"10":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":215,"end":218},"11":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":354,"end":359},"12":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":219,"end":220},"13":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":321,"end":322},"14":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":376,"end":377},"16":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":193,"end":194},"17":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":376,"end":377},"19":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":193,"end":194},"20":{"file_hash":[31,75,248,230,38,255,48,178,141,227,79,21,190,81,225,174,10,106,91,83,133,83,131,144,26,62,46,57,147,60,8,151],"start":106,"end":107},"21":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":170,"end":177},"22":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":215,"end":218},"24":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":224,"end":227},"25":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":380,"end":381},"26":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":383,"end":384},"27":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":387,"end":388},"28":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":385,"end":386},"29":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":383,"end":388},"30":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":215,"end":218},"31":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":383,"end":388},"32":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":219,"end":220},"33":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":371,"end":389}},"is_native":false},"1":{"location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":401,"end":433},"definition_location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":412,"end":416},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":425,"end":430},"2":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":430,"end":431}},"is_native":false},"2":{"location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":195,"end":433},"definition_location":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":195,"end":433},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[249,189,137,223,195,159,172,175,194,42,112,143,180,15,106,4,234,251,91,123,49,152,23,66,219,199,196,151,114,112,25,59],"start":195,"end":433}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep.json new file mode 100644 index 00000000000..73a233e1cdc --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":40,"end":45},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":0,"end":239},"definition_location":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":0,"end":239},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[84,199,25,202,109,95,108,183,136,222,158,158,73,154,118,103,146,29,74,236,136,204,40,144,245,199,213,20,253,36,158,248],"start":0,"end":239}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep_dep.json new file mode 100644 index 00000000000..cbb7a66e070 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/source_maps/m_dep_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[31,75,248,230,38,255,48,178,141,227,79,21,190,81,225,174,10,106,91,83,133,83,131,144,26,62,46,57,147,60,8,151],"start":40,"end":49},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[31,75,248,230,38,255,48,178,141,227,79,21,190,81,225,174,10,106,91,83,133,83,131,144,26,62,46,57,147,60,8,151],"start":0,"end":121},"definition_location":{"file_hash":[31,75,248,230,38,255,48,178,141,227,79,21,190,81,225,174,10,106,91,83,133,83,131,144,26,62,46,57,147,60,8,151],"start":0,"end":121},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[31,75,248,230,38,255,48,178,141,227,79,21,190,81,225,174,10,106,91,83,133,83,131,144,26,62,46,57,147,60,8,151],"start":0,"end":121}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m.move new file mode 100644 index 00000000000..3547bc0e4de --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m.move @@ -0,0 +1,19 @@ +// Test calling into another macro inside a macro where the second +// macro is called right at the beginning of the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_different_files::m; + +use macro_different_different_files::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep.move new file mode 100644 index 00000000000..8442fd105ee --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep.move @@ -0,0 +1,9 @@ +module macro_different_different_files::m_dep; + +use macro_different_different_files::m_dep_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz!($param1 + $param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep_dep.move new file mode 100644 index 00000000000..d8eef45c5a1 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/build/macro_different_different_files/sources/m_dep_dep.move @@ -0,0 +1,6 @@ +module macro_different_different_files::m_dep_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m.move new file mode 100644 index 00000000000..3445084f6c2 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m.move @@ -0,0 +1,20 @@ +// Test calling into another macro inside a macro (both macros +// defined in different files than where they are called). +// The second macro is called right at the beginning of the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_different_files::m; + +use macro_different_different_files::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep.move new file mode 100644 index 00000000000..8442fd105ee --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep.move @@ -0,0 +1,9 @@ +module macro_different_different_files::m_dep; + +use macro_different_different_files::m_dep_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz!($param1 + $param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep_dep.move new file mode 100644 index 00000000000..d8eef45c5a1 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/sources/m_dep_dep.move @@ -0,0 +1,6 @@ +module macro_different_different_files::m_dep_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/test.exp new file mode 100644 index 00000000000..679908bd3c1 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/test.exp @@ -0,0 +1,27 @@ +current frame stack: + function: test (m.move:18) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep_dep.move:4) + scope 0 : +current frame stack: + function: test (m.move:18) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:6) + scope 0 : +current frame stack: + function: test (m.move:18) + scope 0 : + function: foo (m.move:13) + scope 0 : + v : 12 + type: u64 + + function: __inlined__ (m_dep_dep.move:4) + scope 0 : +line breakpoints + m_dep_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/trace.spec.js new file mode 100644 index 00000000000..2706a613bcf --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/trace.spec.js @@ -0,0 +1,18 @@ +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro, + // and then the inner macro + runtime.step(false); + res += runtime.toString(); + // step to leave the inner macro + runtime.step(false); + res += runtime.toString(); + // set a breakpoint in the inner macro and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/traces/macro_different_different_files__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/traces/macro_different_different_files__m__test.json new file mode 100644 index 00000000000..36b8cb69325 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files/traces/macro_different_different_files__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":8}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999877,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999859,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999841,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999838,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999820,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999802,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999799,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999796,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999795,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999777,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999776,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999758,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999757,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999739,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999721,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999718,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999717,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":96}}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999699,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999681,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":96}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999678,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999677,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":144}}],"gas_left":999999677}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999676,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999675,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999675}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/Move.toml new file mode 100644 index 00000000000..5a33d38a3eb --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_different_different_files2" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_different_different_files2 = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..7646ab37ce89f550508a2877a347a24c5e5dbca4 GIT binary patch literal 320 zcmbtQ(Fwvp3{5WAYn$XlMGg@M5U0>dibyL(>`7a}b^LZTm+)Go4&VzR?}ZSO_uRb2 z0f0lWWS7Zmk?s!JWv?%MfI$lw11L^F5;LmEk%WFg*7d0^k9}Em^|>kAuBbv=^kvuA z&6%nY@M;H@-x&}+sqyjspA l77{DuHRV)6Qe|dguZe&p-eCM6XbxxwJHQTZjhGV}_yEuWAqxNi literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m_dep_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/bytecode_modules/m_dep_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..b864448837dcebb55246313da3f48a86fafa7615 GIT binary patch literal 196 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fnBgBDc3ZpOsBO?<7GfsAf RbO{Rs0}IH-U?2!`A^C literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m.json new file mode 100644 index 00000000000..b7fc23dc08e --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":305,"end":306},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":360,"end":462},"definition_location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":371,"end":374},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":378,"end":381}],"locals":[["%#10",{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":242,"end":245}],["%#4",{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":425,"end":430}],["%#5",{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":242,"end":245}],["%#7",{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":217,"end":230}],["%#8",{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":211,"end":214}],["%#9",{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":454,"end":459}],["ret#1#1",{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":176,"end":179}],["ret#1#9",{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":176,"end":179}],["v#1#0",{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":392,"end":393}],["x#1#5",{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":422,"end":423}],["x#2#13",{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":451,"end":452}]],"nops":{},"code_map":{"0":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":182,"end":199},"1":{"file_hash":[173,46,101,31,251,26,37,4,55,117,145,175,205,182,90,157,64,10,72,116,171,5,234,80,150,209,158,26,145,14,2,80],"start":104,"end":111},"2":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":215,"end":216},"3":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":205,"end":208},"4":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":242,"end":245},"6":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":251,"end":254},"7":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":422,"end":423},"8":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":425,"end":426},"9":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":429,"end":430},"10":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":427,"end":428},"11":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":425,"end":430},"12":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":242,"end":245},"13":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":425,"end":430},"14":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":246,"end":247},"15":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":392,"end":393},"16":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":447,"end":448},"18":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":190,"end":191},"19":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":211,"end":214},"20":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":447,"end":448},"22":{"file_hash":[173,46,101,31,251,26,37,4,55,117,145,175,205,182,90,157,64,10,72,116,171,5,234,80,150,209,158,26,145,14,2,80],"start":107,"end":108},"23":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":217,"end":230},"24":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":211,"end":214},"25":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":217,"end":230},"26":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":215,"end":216},"27":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":205,"end":208},"28":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":242,"end":245},"30":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":251,"end":254},"31":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":451,"end":452},"32":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":454,"end":455},"33":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":458,"end":459},"34":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":456,"end":457},"35":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":454,"end":459},"36":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":242,"end":245},"37":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":454,"end":459},"38":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":246,"end":247},"39":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":442,"end":460}},"is_native":false},"1":{"location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":472,"end":504},"definition_location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":483,"end":487},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":496,"end":501},"2":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":501,"end":502}},"is_native":false},"2":{"location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":264,"end":504},"definition_location":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":264,"end":504},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[96,145,249,212,202,193,182,28,44,104,123,4,6,157,68,218,35,231,210,249,236,247,170,143,205,125,172,52,55,71,94,248],"start":264,"end":504}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep.json new file mode 100644 index 00000000000..c80366272e1 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":41,"end":46},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":0,"end":266},"definition_location":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":0,"end":266},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[225,228,34,104,170,85,216,85,188,42,157,151,249,222,215,20,179,48,190,9,48,73,44,9,20,39,48,41,129,96,211,159],"start":0,"end":266}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep_dep.json new file mode 100644 index 00000000000..713969296da --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/source_maps/m_dep_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[173,46,101,31,251,26,37,4,55,117,145,175,205,182,90,157,64,10,72,116,171,5,234,80,150,209,158,26,145,14,2,80],"start":41,"end":50},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[173,46,101,31,251,26,37,4,55,117,145,175,205,182,90,157,64,10,72,116,171,5,234,80,150,209,158,26,145,14,2,80],"start":0,"end":122},"definition_location":{"file_hash":[173,46,101,31,251,26,37,4,55,117,145,175,205,182,90,157,64,10,72,116,171,5,234,80,150,209,158,26,145,14,2,80],"start":0,"end":122},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[173,46,101,31,251,26,37,4,55,117,145,175,205,182,90,157,64,10,72,116,171,5,234,80,150,209,158,26,145,14,2,80],"start":0,"end":122}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m.move new file mode 100644 index 00000000000..3115f978afa --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m.move @@ -0,0 +1,20 @@ +// Test calling into another macro inside a macro (both macros +// defined in different files than where they are called). +// The second macro is called after another instruction in the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_different_files2::m; + +use macro_different_different_files2::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep.move new file mode 100644 index 00000000000..9b26bd915e9 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep.move @@ -0,0 +1,10 @@ +module macro_different_different_files2::m_dep; + +use macro_different_different_files2::m_dep_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + baz!($param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep_dep.move new file mode 100644 index 00000000000..f7c2cdecf10 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/build/macro_different_different_files2/sources/m_dep_dep.move @@ -0,0 +1,6 @@ +module macro_different_different_files2::m_dep_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m.move new file mode 100644 index 00000000000..3115f978afa --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m.move @@ -0,0 +1,20 @@ +// Test calling into another macro inside a macro (both macros +// defined in different files than where they are called). +// The second macro is called after another instruction in the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_different_files2::m; + +use macro_different_different_files2::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep.move new file mode 100644 index 00000000000..9b26bd915e9 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep.move @@ -0,0 +1,10 @@ +module macro_different_different_files2::m_dep; + +use macro_different_different_files2::m_dep_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + baz!($param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep_dep.move new file mode 100644 index 00000000000..f7c2cdecf10 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/sources/m_dep_dep.move @@ -0,0 +1,6 @@ +module macro_different_different_files2::m_dep_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/test.exp new file mode 100644 index 00000000000..185d7716cae --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/test.exp @@ -0,0 +1,35 @@ +current frame stack: + function: test (m.move:19) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:6) + scope 0 : +current frame stack: + function: test (m.move:19) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep_dep.move:4) + scope 0 : +current frame stack: + function: test (m.move:19) + scope 0 : + function: foo (m.move:14) + scope 0 : + v : 12 + type: u64 + +current frame stack: + function: test (m.move:19) + scope 0 : + function: foo (m.move:14) + scope 0 : + v : 12 + type: u64 + + function: __inlined__ (m_dep_dep.move:4) + scope 0 : +line breakpoints + m_dep_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/trace.spec.js new file mode 100644 index 00000000000..ff10fadbd28 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/trace.spec.js @@ -0,0 +1,28 @@ +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro + runtime.step(false); + res += runtime.toString(); + // step to the second macro + runtime.step(false); + res += runtime.toString(); + // step to leave the second macro, and keep stepping + // to leave to the outer function + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + res += runtime.toString(); + // set a breakpoint in the inner macro and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/traces/macro_different_different_files2__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/traces/macro_different_different_files2__m__test.json new file mode 100644 index 00000000000..8636c1aa500 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_different_files2/traces/macro_different_different_files2__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999993,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999990,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999989,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999971,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999970,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999952,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999951,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,9]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999933,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,9]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999915,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,9]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999912,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999911,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":8}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999893,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999875,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999872,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999871,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999853,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999835,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999832,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999831,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999813,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999795,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999792,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999791,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999773,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999755,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999752,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999751,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999733,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999732,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999714,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999713,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,10]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999695,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,10]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999677,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,10]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999674,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999673,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":96}}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999655,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999637,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":96}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999634,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":39,"gas_left":999999633,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":144}}],"gas_left":999999633}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999632,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999631,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999631}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/Move.toml new file mode 100644 index 00000000000..a68bcc53b5f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_different_files" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_different_files = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..860fd9802d70e97638b75593faf91a5b890728e6 GIT binary patch literal 294 zcmbtQK?=e^3`{n=+jf&f3$loaXP==jsUmIJgI#IsgFN~+KjF5hA8g%hP{A95W*`j! literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m.json new file mode 100644 index 00000000000..c876f60da21 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":86,"end":87},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":130,"end":232},"definition_location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":141,"end":144},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":148,"end":151}],"locals":[["%#2",{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":195,"end":200}],["%#3",{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":145,"end":148}],["%#5",{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":224,"end":229}],["%#6",{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":145,"end":148}],["ret#1#1",{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":110,"end":113}],["ret#1#5",{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":110,"end":113}],["v#1#0",{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":162,"end":163}],["x#1#4",{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":192,"end":193}],["x#2#8",{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":221,"end":222}]],"nops":{},"code_map":{"0":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":116,"end":133},"1":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":106,"end":113},"2":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":145,"end":148},"4":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":154,"end":157},"5":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":192,"end":193},"6":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":195,"end":196},"7":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":199,"end":200},"8":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":197,"end":198},"9":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":195,"end":200},"10":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":145,"end":148},"11":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":195,"end":200},"12":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":149,"end":150},"13":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":162,"end":163},"14":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":217,"end":218},"16":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":124,"end":125},"17":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":106,"end":113},"18":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":145,"end":148},"20":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":154,"end":157},"21":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":221,"end":222},"22":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":224,"end":225},"23":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":228,"end":229},"24":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":226,"end":227},"25":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":224,"end":229},"26":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":145,"end":148},"27":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":224,"end":229},"28":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":149,"end":150},"29":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":212,"end":230}},"is_native":false},"1":{"location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":242,"end":274},"definition_location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":253,"end":257},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":266,"end":271},"2":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":271,"end":272}},"is_native":false},"2":{"location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":56,"end":274},"definition_location":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":56,"end":274},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[88,28,80,35,42,128,203,67,135,138,133,134,227,98,175,180,208,3,30,160,17,180,120,104,4,184,68,217,54,115,13,91],"start":56,"end":274}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m_dep.json new file mode 100644 index 00000000000..14e9cb0add3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":30,"end":35},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":0,"end":169},"definition_location":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":0,"end":169},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[2,218,102,73,175,191,248,114,178,154,190,10,104,78,196,112,123,66,134,2,253,214,70,139,99,2,216,133,79,144,229,131],"start":0,"end":169}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m.move new file mode 100644 index 00000000000..fbdc7472d79 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m.move @@ -0,0 +1,17 @@ +// Test stepping through macro defined different files. +module macro_different_files::m; + +use macro_different_files::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m_dep.move new file mode 100644 index 00000000000..af0f07335dd --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/build/macro_different_files/sources/m_dep.move @@ -0,0 +1,7 @@ +module macro_different_files::m_dep; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m.move new file mode 100644 index 00000000000..fbdc7472d79 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m.move @@ -0,0 +1,17 @@ +// Test stepping through macro defined different files. +module macro_different_files::m; + +use macro_different_files::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m_dep.move new file mode 100644 index 00000000000..af0f07335dd --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/sources/m_dep.move @@ -0,0 +1,7 @@ +module macro_different_files::m_dep; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/test.exp new file mode 100644 index 00000000000..ee4b98a1247 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/test.exp @@ -0,0 +1,22 @@ +current frame stack: + function: test (m.move:16) + scope 0 : + function: foo (m.move:0) + scope 0 : + ret : 2 + type: u64 + + function: __inlined__ (m_dep.move:5) + scope 0 : +current frame stack: + function: test (m.move:16) + scope 0 : + function: foo (m.move:9) + scope 0 : +current frame stack: + function: test (m.move:16) + scope 0 : + function: foo (m.move:9) + scope 0 : + function: __inlined__ (m_dep.move:5) + scope 0 : diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/trace.spec.js new file mode 100644 index 00000000000..b967f832950 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/trace.spec.js @@ -0,0 +1,16 @@ +let action = (runtime) => { + let res = ''; + // step into a function, which immediately step in to a macro + runtime.step(false); + // step inside the macro + runtime.step(false); + res += runtime.toString(); + // step into lambda + runtime.step(false); + res += runtime.toString(); + // step from lambda back into macro + runtime.step(false); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/traces/macro_different_files__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/traces/macro_different_files__m__test.json new file mode 100644 index 00000000000..b9c523cb63f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_files/traces/macro_different_files__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999877,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":6}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999859,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999841,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999838,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999837,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999819,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999818,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999800,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999799,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999781,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999763,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999760,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999759,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999741,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999723,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999720,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999719,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":36}}],"gas_left":999999719}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999718,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999717,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999717}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/Move.toml new file mode 100644 index 00000000000..bf0aa3e41e9 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_different_same_files" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_different_same_files = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..860fd9802d70e97638b75593faf91a5b890728e6 GIT binary patch literal 294 zcmbtQK?=e^3`{n=+jf&f3$loaXP==jsUmIJgI#IsgFN~+KjF5hA8g%hP{A95W*`j! literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m.json new file mode 100644 index 00000000000..56e50096c17 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":142,"end":143},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":191,"end":293},"definition_location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":202,"end":205},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":209,"end":212}],"locals":[["%#3",{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":256,"end":261}],["%#4",{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":218,"end":221}],["%#7",{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":285,"end":290}],["%#8",{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":218,"end":221}],["ret#1#1",{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":187,"end":190}],["ret#1#7",{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":187,"end":190}],["v#1#0",{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":223,"end":224}],["x#1#3",{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":253,"end":254}],["x#2#9",{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":282,"end":283}]],"nops":{},"code_map":{"0":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":94,"end":101},"1":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":183,"end":190},"2":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":218,"end":221},"4":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":227,"end":230},"5":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":253,"end":254},"6":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":256,"end":257},"7":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":260,"end":261},"8":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":258,"end":259},"9":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":256,"end":261},"10":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":218,"end":221},"11":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":256,"end":261},"12":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":222,"end":223},"13":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":223,"end":224},"14":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":278,"end":279},"16":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":97,"end":98},"17":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":183,"end":190},"18":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":218,"end":221},"20":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":227,"end":230},"21":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":282,"end":283},"22":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":285,"end":286},"23":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":289,"end":290},"24":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":287,"end":288},"25":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":285,"end":290},"26":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":218,"end":221},"27":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":285,"end":290},"28":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":222,"end":223},"29":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":273,"end":291}},"is_native":false},"1":{"location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":303,"end":335},"definition_location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":314,"end":318},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":327,"end":332},"2":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":332,"end":333}},"is_native":false},"2":{"location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":107,"end":335},"definition_location":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":107,"end":335},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[8,218,176,171,73,116,89,167,13,226,112,193,67,60,26,61,56,218,89,205,211,80,235,233,69,145,95,249,204,239,240,201],"start":107,"end":335}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m_dep.json new file mode 100644 index 00000000000..8957cf8981e --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":35,"end":40},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":0,"end":242},"definition_location":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":0,"end":242},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[203,176,245,157,158,191,177,228,121,179,234,90,181,158,7,42,11,52,175,238,167,221,36,7,96,28,176,113,90,136,53,152],"start":0,"end":242}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m.move new file mode 100644 index 00000000000..d591ebc1cce --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m.move @@ -0,0 +1,18 @@ +// Test stepping through two macros, one defined in a different file, +// and one defined in the same file. +module macro_different_same_files::m; + +use macro_different_same_files::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m_dep.move new file mode 100644 index 00000000000..e58f96bf767 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/build/macro_different_same_files/sources/m_dep.move @@ -0,0 +1,13 @@ +module macro_different_same_files::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} + + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz!($param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m.move new file mode 100644 index 00000000000..b2c13508a6a --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m.move @@ -0,0 +1,21 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called right at the beginning of the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_same_files::m; + +use macro_different_same_files::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m_dep.move new file mode 100644 index 00000000000..e58f96bf767 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/sources/m_dep.move @@ -0,0 +1,13 @@ +module macro_different_same_files::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} + + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz!($param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/test.exp new file mode 100644 index 00000000000..de0af6675d2 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/test.exp @@ -0,0 +1,27 @@ +current frame stack: + function: test (m.move:17) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:4) + scope 0 : +current frame stack: + function: test (m.move:17) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:10) + scope 0 : +current frame stack: + function: test (m.move:17) + scope 0 : + function: foo (m.move:12) + scope 0 : + v : 6 + type: u64 + + function: __inlined__ (m_dep.move:4) + scope 0 : +line breakpoints + m_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/trace.spec.js new file mode 100644 index 00000000000..c0ab9535685 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/trace.spec.js @@ -0,0 +1,18 @@ +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro, + // and then the inner macro + runtime.step(false); + res += runtime.toString(); + // step to leave the inner macro + runtime.step(false); + res += runtime.toString(); + // set a breakpoint in the inner macro and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/traces/macro_different_same_files__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/traces/macro_different_same_files__m__test.json new file mode 100644 index 00000000000..b9c523cb63f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files/traces/macro_different_same_files__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999877,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":6}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999859,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999841,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999838,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999837,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999819,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999818,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999800,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999799,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999781,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999763,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999760,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999759,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999741,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999723,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999720,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999719,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":36}}],"gas_left":999999719}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999718,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999717,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999717}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/Move.toml new file mode 100644 index 00000000000..8efd1fba65e --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_different_same_files2" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_different_same_files2 = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..7646ab37ce89f550508a2877a347a24c5e5dbca4 GIT binary patch literal 320 zcmbtQ(Fwvp3{5WAYn$XlMGg@M5U0>dibyL(>`7a}b^LZTm+)Go4&VzR?}ZSO_uRb2 z0f0lWWS7Zmk?s!JWv?%MfI$lw11L^F5;LmEk%WFg*7d0^k9}Em^|>kAuBbv=^kvuA z&6%nY@M;H@-x&}+sqyjspA l77{DuHRV)6Qe|dguZe&p-eCM6XbxxwJHQTZjhGV}_yEuWAqxNi literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m.json new file mode 100644 index 00000000000..ae7d5c5c72d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":363,"end":364},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":413,"end":515},"definition_location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":424,"end":427},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":431,"end":434}],"locals":[["%#10",{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":254,"end":257}],["%#4",{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":478,"end":483}],["%#5",{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":254,"end":257}],["%#7",{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":229,"end":242}],["%#8",{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":223,"end":226}],["%#9",{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":507,"end":512}],["ret#1#1",{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":188,"end":191}],["ret#1#9",{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":188,"end":191}],["v#1#0",{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":445,"end":446}],["x#1#5",{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":475,"end":476}],["x#2#13",{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":504,"end":505}]],"nops":{},"code_map":{"0":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":194,"end":211},"1":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":95,"end":102},"2":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":227,"end":228},"3":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":217,"end":220},"4":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":254,"end":257},"6":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":263,"end":266},"7":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":475,"end":476},"8":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":478,"end":479},"9":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":482,"end":483},"10":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":480,"end":481},"11":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":478,"end":483},"12":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":254,"end":257},"13":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":478,"end":483},"14":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":258,"end":259},"15":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":445,"end":446},"16":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":500,"end":501},"18":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":202,"end":203},"19":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":223,"end":226},"20":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":500,"end":501},"22":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":98,"end":99},"23":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":229,"end":242},"24":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":223,"end":226},"25":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":229,"end":242},"26":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":227,"end":228},"27":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":217,"end":220},"28":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":254,"end":257},"30":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":263,"end":266},"31":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":504,"end":505},"32":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":507,"end":508},"33":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":511,"end":512},"34":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":509,"end":510},"35":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":507,"end":512},"36":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":254,"end":257},"37":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":507,"end":512},"38":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":258,"end":259},"39":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":495,"end":513}},"is_native":false},"1":{"location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":525,"end":557},"definition_location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":536,"end":540},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":549,"end":554},"2":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":554,"end":555}},"is_native":false},"2":{"location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":327,"end":557},"definition_location":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":327,"end":557},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[26,63,99,113,250,123,156,46,80,75,173,23,193,164,137,7,126,68,134,201,86,30,169,114,209,31,254,72,122,29,208,61],"start":327,"end":557}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m_dep.json new file mode 100644 index 00000000000..c93a7328b93 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":36,"end":41},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":0,"end":278},"definition_location":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":0,"end":278},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[95,14,136,172,194,138,103,180,220,243,216,184,240,4,12,20,227,205,228,79,250,75,114,180,151,33,191,159,228,225,54,124],"start":0,"end":278}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m.move new file mode 100644 index 00000000000..72051003d64 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m.move @@ -0,0 +1,21 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called after another instruction in the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_same_files2::m; + +use macro_different_same_files2::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m_dep.move new file mode 100644 index 00000000000..42b3ec68a83 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/build/macro_different_same_files2/sources/m_dep.move @@ -0,0 +1,14 @@ +module macro_different_same_files2::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} + + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + baz!($param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m.move new file mode 100644 index 00000000000..72051003d64 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m.move @@ -0,0 +1,21 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called after another instruction in the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_different_same_files2::m; + +use macro_different_same_files2::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m_dep.move new file mode 100644 index 00000000000..42b3ec68a83 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/sources/m_dep.move @@ -0,0 +1,14 @@ +module macro_different_same_files2::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} + + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + baz!($param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/test.exp new file mode 100644 index 00000000000..4e996585189 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/test.exp @@ -0,0 +1,35 @@ +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:10) + scope 0 : +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:4) + scope 0 : +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:15) + scope 0 : + v : 12 + type: u64 + +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:15) + scope 0 : + v : 12 + type: u64 + + function: __inlined__ (m_dep.move:4) + scope 0 : +line breakpoints + m_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/trace.spec.js new file mode 100644 index 00000000000..19daaa7ff86 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/trace.spec.js @@ -0,0 +1,28 @@ +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro + runtime.step(false); + res += runtime.toString(); + // step to the second macro + runtime.step(false); + res += runtime.toString(); + // step to leave the second macro, and keep stepping + // to leave to the outer function + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + res += runtime.toString(); + // set a breakpoint in the inner macro and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/traces/macro_different_same_files2__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/traces/macro_different_same_files2__m__test.json new file mode 100644 index 00000000000..8636c1aa500 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_different_same_files2/traces/macro_different_same_files2__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999993,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999990,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999989,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999971,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999970,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999952,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999951,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,9]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999933,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,9]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999915,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,9]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999912,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999911,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":8}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999893,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999875,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999872,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999871,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999853,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999835,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999832,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999831,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999813,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999795,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999792,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999791,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999773,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999755,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999752,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999751,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999733,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999732,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999714,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999713,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,10]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999695,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,10]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999677,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,10]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999674,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999673,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":96}}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999655,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999637,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":96}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999634,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":39,"gas_left":999999633,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":144}}],"gas_left":999999633}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999632,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999631,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999631}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/Move.toml new file mode 100644 index 00000000000..533f577f62c --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_inner_call" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_inner_call = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..1ffa590fead935fe3b70b70c3d56d39e66443544 GIT binary patch literal 319 zcmbtQ+fBnj5S+cehkd&r@y|(#B0&eVKnIj?3dD*05np7RA3o@XMrep8I7dJOj5N|{ zcQpI>*nf!!;0d1n*4=Hw!&CGAsGoEM!;*&q0j_!wDhWg|L|i4e{0oZ8&xg0&%hVs1 zKF`B>?58=O%9NLWUWW0^r&8$BUh=WOuC!~teI1A8=GgqHd@aLV#&zI7Q1=APy*ED@ z9jlF2Nvwt#BqW89AgPaDe5!31ow7J>Vk1pbBP=G>OKSjkAY;e^c74_joh5^BXWb=& literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m_dep_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/bytecode_modules/m_dep_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..aab6770d51d80e3b7a75a717fa5a9f82a07e4c56 GIT binary patch literal 217 zcmZ1|^O~EDfq{XIk%5Jog`ZWJja|}(Bi4auE~7jH6C*QF3J6#j85w|xi2*3U$i>5) zlvpK|T$Gwvk{Vx}nVy$gR2-j{Uld=GT3nKum(H0RpORVt!kndfnI&Lh0XQqZAV0G> kKM!Is*(A_C3=E7cTnyX{VoZ#TEI>BM8(<*F#K^<|0H u64): u64 { + let mut ret = baz($param1 + $param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/sources/m_dep_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/sources/m_dep_dep.move new file mode 100644 index 00000000000..8bca00d40d9 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/build/macro_inner_call/sources/m_dep_dep.move @@ -0,0 +1,5 @@ +module macro_inner_call::m_dep_dep; + +public fun baz(p: u64): u64 { + p + p +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/hw_trace.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/hw_trace.json new file mode 100644 index 00000000000..d1b8c2e011d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/hw_trace.json @@ -0,0 +1,1472 @@ +{ + "version": 1, + "events": [ + { + "OpenFrame": { + "frame": { + "frame_id": 0, + "function_name": "test", + "module": { + "address": "0000000000000000000000000000000000000000000000000000000000000000", + "name": "m" + }, + "binary_member_index": 1, + "type_instantiation": [], + "parameters": [], + "return_types": [], + "locals_types": [], + "is_native": false + }, + "gas_left": 1000000000 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 0, + "gas_left": 1000000000, + "instruction": "CALL" + } + }, + { + "OpenFrame": { + "frame": { + "frame_id": 2, + "function_name": "foo", + "module": { + "address": "0000000000000000000000000000000000000000000000000000000000000000", + "name": "m" + }, + "binary_member_index": 0, + "type_instantiation": [], + "parameters": [], + "return_types": [ + { + "type_": "u64", + "ref_type": null + } + ], + "locals_types": [ + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + }, + { + "type_": "u64", + "ref_type": null + } + ], + "is_native": false + }, + "gas_left": 1000000000 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 0, + "gas_left": 999999996, + "instruction": "LD_U64" + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 2 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 1, + "gas_left": 999999996, + "instruction": "CALL" + } + }, + { + "OpenFrame": { + "frame": { + "frame_id": 6, + "function_name": "baz", + "module": { + "address": "0000000000000000000000000000000000000000000000000000000000000000", + "name": "m_dep_dep" + }, + "binary_member_index": 0, + "type_instantiation": [], + "parameters": [ + { + "RuntimeValue": { + "value": 2 + } + } + ], + "return_types": [ + { + "type_": "u64", + "ref_type": null + } + ], + "locals_types": [ + { + "type_": "u64", + "ref_type": null + } + ], + "is_native": false + }, + "gas_left": 999999996 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 0, + "gas_left": 999999977, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 6, + 0 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 2 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 2 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 1, + "gas_left": 999999959, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 6, + 0 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 2 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 2 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 2, + "gas_left": 999999956, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 2 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 2 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 3, + "gas_left": 999999955, + "instruction": "RET" + } + }, + { + "CloseFrame": { + "frame_id": 6, + "return_": [ + { + "RuntimeValue": { + "value": 4 + } + } + ], + "gas_left": 999999955 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 2, + "gas_left": 999999954, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 4 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 4 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 3, + "gas_left": 999999936, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 4 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 4 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 4, + "gas_left": 999999935, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 1 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 4 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 5, + "gas_left": 999999917, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 4 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 4 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 6, + "gas_left": 999999916, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 7 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 4 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 7, + "gas_left": 999999898, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 7 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 4 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 8, + "gas_left": 999999880, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 7 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 4 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 9, + "gas_left": 999999877, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 8 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 10, + "gas_left": 999999876, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 8 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 0 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 8 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 11, + "gas_left": 999999858, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 1 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 4 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 12, + "gas_left": 999999840, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 0 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 8 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 8 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 13, + "gas_left": 999999837, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 8 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 4 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 12 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 14, + "gas_left": 999999836, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 12 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 6 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 12 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 15, + "gas_left": 999999818, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 6 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 12 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 12 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 16, + "gas_left": 999999800, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 6 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 12 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 12 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 17, + "gas_left": 999999797, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 12 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 12 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 24 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 18, + "gas_left": 999999797, + "instruction": "CALL" + } + }, + { + "OpenFrame": { + "frame": { + "frame_id": 71, + "function_name": "baz", + "module": { + "address": "0000000000000000000000000000000000000000000000000000000000000000", + "name": "m_dep_dep" + }, + "binary_member_index": 0, + "type_instantiation": [], + "parameters": [ + { + "RuntimeValue": { + "value": 24 + } + } + ], + "return_types": [ + { + "type_": "u64", + "ref_type": null + } + ], + "locals_types": [ + { + "type_": "u64", + "ref_type": null + } + ], + "is_native": false + }, + "gas_left": 999999797 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 0, + "gas_left": 999999778, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 71, + 0 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 24 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 24 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 1, + "gas_left": 999999760, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 71, + 0 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 24 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 24 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 2, + "gas_left": 999999757, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 24 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 24 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 3, + "gas_left": 999999756, + "instruction": "RET" + } + }, + { + "CloseFrame": { + "frame_id": 71, + "return_": [ + { + "RuntimeValue": { + "value": 48 + } + } + ], + "gas_left": 999999756 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 19, + "gas_left": 999999755, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 5 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 48 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 20, + "gas_left": 999999737, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 5 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 48 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 21, + "gas_left": 999999736, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 3 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 48 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 22, + "gas_left": 999999718, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 5 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 48 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 23, + "gas_left": 999999717, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 8 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 48 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 24, + "gas_left": 999999699, + "instruction": "COPY_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 8 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 48 + } + }, + "moved": false + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 25, + "gas_left": 999999681, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 8 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 48 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 26, + "gas_left": 999999678, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 96 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 27, + "gas_left": 999999677, + "instruction": "ST_LOC" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 96 + } + } + } + }, + { + "Effect": { + "Write": { + "location": { + "Local": [ + 2, + 2 + ] + }, + "root_value_after_write": { + "RuntimeValue": { + "value": 96 + } + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 28, + "gas_left": 999999659, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 3 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 48 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 29, + "gas_left": 999999641, + "instruction": "MOVE_LOC" + } + }, + { + "Effect": { + "Read": { + "location": { + "Local": [ + 2, + 2 + ] + }, + "root_value_read": { + "RuntimeValue": { + "value": 96 + } + }, + "moved": true + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 96 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 30, + "gas_left": 999999638, + "instruction": "ADD" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 96 + } + } + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 48 + } + } + } + }, + { + "Effect": { + "Push": { + "RuntimeValue": { + "value": 144 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 31, + "gas_left": 999999637, + "instruction": "RET" + } + }, + { + "CloseFrame": { + "frame_id": 2, + "return_": [ + { + "RuntimeValue": { + "value": 144 + } + } + ], + "gas_left": 999999637 + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 1, + "gas_left": 999999636, + "instruction": "POP" + } + }, + { + "Effect": { + "Pop": { + "RuntimeValue": { + "value": 144 + } + } + } + }, + { + "Instruction": { + "type_parameters": [], + "pc": 2, + "gas_left": 999999635, + "instruction": "RET" + } + }, + { + "CloseFrame": { + "frame_id": 0, + "return_": [], + "gas_left": 999999635 + } + } + ] +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m.move new file mode 100644 index 00000000000..c29ac867078 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m.move @@ -0,0 +1,18 @@ +// Test calling into another function inside a macro +// (stepping into a functino and braking in the function). +module macro_inner_call::m; + +use macro_inner_call::m_dep::bar; + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep.move new file mode 100644 index 00000000000..51b7212d701 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep.move @@ -0,0 +1,9 @@ +module macro_inner_call::m_dep; + +use macro_inner_call::m_dep_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz($param1 + $param1); + ret = ret + $f(ret); + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep_dep.move new file mode 100644 index 00000000000..8bca00d40d9 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/sources/m_dep_dep.move @@ -0,0 +1,5 @@ +module macro_inner_call::m_dep_dep; + +public fun baz(p: u64): u64 { + p + p +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/test.exp new file mode 100644 index 00000000000..37c146c5b1f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/test.exp @@ -0,0 +1,40 @@ +current frame stack: + function: test (m.move:17) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:6) + scope 0 : + function: baz (m_dep_dep.move:4) + scope 0 : + p : 2 + type: u64 + +current frame stack: + function: test (m.move:17) + scope 0 : + function: foo (m.move:0) + scope 0 : + ret : 4 + type: u64 + + function: __inlined__ (m_dep.move:7) + scope 0 : +current frame stack: + function: test (m.move:17) + scope 0 : + function: foo (m.move:12) + scope 0 : + v : 12 + type: u64 + + function: __inlined__ (m_dep.move:6) + scope 0 : + function: baz (m_dep_dep.move:4) + scope 0 : + p : 24 + type: u64 + +line breakpoints + m_dep_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/trace.spec.js new file mode 100644 index 00000000000..9215f35e046 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/trace.spec.js @@ -0,0 +1,19 @@ +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro + runtime.step(false); + // step into inner function + runtime.step(false); + res += runtime.toString(); + // step out into the macro + runtime.stepOut(); + res += runtime.toString(); + // set a brakepoint in the inner function and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/traces/macro_inner_call__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/traces/macro_inner_call__m__test.json new file mode 100644 index 00000000000..e246e5fedf8 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_inner_call/traces/macro_inner_call__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999996,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":6,"function_name":"baz","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m_dep_dep"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999996}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[6,0]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999959,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[6,0]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999956,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999955,"instruction":"RET"}},{"CloseFrame":{"frame_id":6,"return_":[{"RuntimeValue":{"value":4}}],"gas_left":999999955}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999954,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999936,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999935,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999917,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999916,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999898,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999880,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999877,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999876,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":8}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999858,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999840,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999837,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999836,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999818,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999800,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999797,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999797,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":71,"function_name":"baz","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m_dep_dep"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":24}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999797}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999778,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[71,0]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999760,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[71,0]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999757,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999756,"instruction":"RET"}},{"CloseFrame":{"frame_id":71,"return_":[{"RuntimeValue":{"value":48}}],"gas_left":999999756}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999755,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999737,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999736,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999718,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999717,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999699,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999681,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999678,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999677,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":96}}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999659,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999641,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":96}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999638,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999637,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":144}}],"gas_left":999999637}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999636,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999635,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999635}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/Move.toml new file mode 100644 index 00000000000..d66dcbb094b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_same_different_files" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_same_different_files = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..860fd9802d70e97638b75593faf91a5b890728e6 GIT binary patch literal 294 zcmbtQK?=e^3`{n=+jf&f3$loaXP==jsUmIJgI#IsgFN~+KjF5hA8g%hP{A95W*`j! literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m.json new file mode 100644 index 00000000000..42bab8b9de0 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":359,"end":360},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":537,"end":639},"definition_location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":548,"end":551},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":555,"end":558}],"locals":[["%#3",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":602,"end":607}],["%#4",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":511,"end":514}],["%#7",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":631,"end":636}],["%#8",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":511,"end":514}],["ret#1#1",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":480,"end":483}],["ret#1#7",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":480,"end":483}],["v#1#0",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":569,"end":570}],["x#1#3",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":599,"end":600}],["x#2#9",{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":628,"end":629}]],"nops":{},"code_map":{"0":{"file_hash":[184,219,80,205,30,165,53,214,50,173,118,77,99,18,57,208,196,131,130,87,128,112,8,4,122,174,100,156,85,210,174,19],"start":94,"end":101},"1":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":476,"end":483},"2":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":511,"end":514},"4":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":520,"end":523},"5":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":599,"end":600},"6":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":602,"end":603},"7":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":606,"end":607},"8":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":604,"end":605},"9":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":602,"end":607},"10":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":511,"end":514},"11":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":602,"end":607},"12":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":515,"end":516},"13":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":569,"end":570},"14":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":624,"end":625},"16":{"file_hash":[184,219,80,205,30,165,53,214,50,173,118,77,99,18,57,208,196,131,130,87,128,112,8,4,122,174,100,156,85,210,174,19],"start":97,"end":98},"17":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":476,"end":483},"18":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":511,"end":514},"20":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":520,"end":523},"21":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":628,"end":629},"22":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":631,"end":632},"23":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":635,"end":636},"24":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":633,"end":634},"25":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":631,"end":636},"26":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":511,"end":514},"27":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":631,"end":636},"28":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":515,"end":516},"29":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":619,"end":637}},"is_native":false},"1":{"location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":649,"end":681},"definition_location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":660,"end":664},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":673,"end":678},"2":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":678,"end":679}},"is_native":false},"2":{"location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":324,"end":681},"definition_location":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":324,"end":681},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[123,78,133,116,164,87,124,212,22,221,25,253,28,189,120,159,231,247,11,124,93,34,144,19,18,155,69,190,115,238,63,254],"start":324,"end":681}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m_dep.json new file mode 100644 index 00000000000..b6ded3923f2 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[184,219,80,205,30,165,53,214,50,173,118,77,99,18,57,208,196,131,130,87,128,112,8,4,122,174,100,156,85,210,174,19],"start":35,"end":40},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[184,219,80,205,30,165,53,214,50,173,118,77,99,18,57,208,196,131,130,87,128,112,8,4,122,174,100,156,85,210,174,19],"start":0,"end":112},"definition_location":{"file_hash":[184,219,80,205,30,165,53,214,50,173,118,77,99,18,57,208,196,131,130,87,128,112,8,4,122,174,100,156,85,210,174,19],"start":0,"end":112},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[184,219,80,205,30,165,53,214,50,173,118,77,99,18,57,208,196,131,130,87,128,112,8,4,122,174,100,156,85,210,174,19],"start":0,"end":112}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m.move new file mode 100644 index 00000000000..b72c0686da5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m.move @@ -0,0 +1,27 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called right at the beginning of the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_same_different_files::m; + +use macro_same_different_files::m_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz!($param1); + ret = ret + $f(ret); + ret +} + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m_dep.move new file mode 100644 index 00000000000..f7931c0afc4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/build/macro_same_different_files/sources/m_dep.move @@ -0,0 +1,6 @@ +module macro_same_different_files::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m.move new file mode 100644 index 00000000000..b72c0686da5 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m.move @@ -0,0 +1,27 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called right at the beginning of the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_same_different_files::m; + +use macro_same_different_files::m_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = baz!($param1); + ret = ret + $f(ret); + ret +} + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m_dep.move new file mode 100644 index 00000000000..f7931c0afc4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/sources/m_dep.move @@ -0,0 +1,6 @@ +module macro_same_different_files::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/test.exp new file mode 100644 index 00000000000..3e0266183f0 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/test.exp @@ -0,0 +1,32 @@ +current frame stack: + function: test (m.move:26) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m_dep.move:4) + scope 0 : +current frame stack: + function: test (m.move:26) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m.move:11) + scope 0 : +current frame stack: + function: test (m.move:26) + scope 0 : + function: foo (m.move:19) + scope 0 : +current frame stack: + function: test (m.move:26) + scope 0 : + function: foo (m.move:21) + scope 0 : + v : 6 + type: u64 + + function: __inlined__ (m_dep.move:4) + scope 0 : +line breakpoints + m_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/trace.spec.js new file mode 100644 index 00000000000..6a98b03e38b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/trace.spec.js @@ -0,0 +1,24 @@ +const { run } = require('node:test'); +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro, + // and then the inner macro + runtime.step(false); + res += runtime.toString(); + // step to leave the inner macro to the outer macro + runtime.step(false); + res += runtime.toString(); + // step inside outer macro + runtime.step(false); + // step to the outer function + runtime.step(false); + res += runtime.toString(); + // set a breakpoint in the inner macro and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/traces/macro_same_different_files__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/traces/macro_same_different_files__m__test.json new file mode 100644 index 00000000000..b9c523cb63f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files/traces/macro_same_different_files__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999877,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":6}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999859,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999841,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999838,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999837,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999819,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999818,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999800,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999799,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999781,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999763,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999760,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999759,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999741,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999723,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999720,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999719,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":36}}],"gas_left":999999719}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999718,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999717,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999717}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/Move.toml new file mode 100644 index 00000000000..5a5cd431249 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_same_different_files2" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_same_different_files2 = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..7646ab37ce89f550508a2877a347a24c5e5dbca4 GIT binary patch literal 320 zcmbtQ(Fwvp3{5WAYn$XlMGg@M5U0>dibyL(>`7a}b^LZTm+)Go4&VzR?}ZSO_uRb2 z0f0lWWS7Zmk?s!JWv?%MfI$lw11L^F5;LmEk%WFg*7d0^k9}Em^|>kAuBbv=^kvuA z&6%nY@M;H@-x&}+sqyjspA l77{DuHRV)6Qe|dguZe&p-eCM6XbxxwJHQTZjhGV}_yEuWAqxNi literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/bytecode_modules/m_dep.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/bytecode_modules/m_dep.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ecd523db78af62313da40ed790c64c4b8adc96 GIT binary patch literal 192 zcmZ1|^O~EDfq{XIk%5Jog^QJsja|fsBfx=Y0;4bkBO?<7GfoM QurM&NfLsd(f*|Js050+yoB#j- literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m.json new file mode 100644 index 00000000000..0110b81aaf2 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":363,"end":364},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":577,"end":679},"definition_location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":588,"end":591},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":595,"end":598}],"locals":[["%#10",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":551,"end":554}],["%#4",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":642,"end":647}],["%#5",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":551,"end":554}],["%#7",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":526,"end":539}],["%#8",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":520,"end":523}],["%#9",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":671,"end":676}],["ret#1#1",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":485,"end":488}],["ret#1#9",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":485,"end":488}],["v#1#0",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":609,"end":610}],["x#1#5",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":639,"end":640}],["x#2#13",{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":668,"end":669}]],"nops":{},"code_map":{"0":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":491,"end":508},"1":{"file_hash":[127,214,134,18,185,163,168,30,218,131,82,67,130,113,55,16,185,195,10,227,2,54,119,149,18,199,130,82,48,24,71,130],"start":95,"end":102},"2":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":524,"end":525},"3":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":514,"end":517},"4":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":551,"end":554},"6":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":560,"end":563},"7":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":639,"end":640},"8":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":642,"end":643},"9":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":646,"end":647},"10":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":644,"end":645},"11":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":642,"end":647},"12":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":551,"end":554},"13":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":642,"end":647},"14":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":555,"end":556},"15":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":609,"end":610},"16":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":664,"end":665},"18":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":499,"end":500},"19":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":520,"end":523},"20":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":664,"end":665},"22":{"file_hash":[127,214,134,18,185,163,168,30,218,131,82,67,130,113,55,16,185,195,10,227,2,54,119,149,18,199,130,82,48,24,71,130],"start":98,"end":99},"23":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":526,"end":539},"24":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":520,"end":523},"25":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":526,"end":539},"26":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":524,"end":525},"27":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":514,"end":517},"28":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":551,"end":554},"30":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":560,"end":563},"31":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":668,"end":669},"32":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":671,"end":672},"33":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":675,"end":676},"34":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":673,"end":674},"35":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":671,"end":676},"36":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":551,"end":554},"37":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":671,"end":676},"38":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":555,"end":556},"39":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":659,"end":677}},"is_native":false},"1":{"location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":689,"end":721},"definition_location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":700,"end":704},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":713,"end":718},"2":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":718,"end":719}},"is_native":false},"2":{"location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":327,"end":721},"definition_location":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":327,"end":721},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[29,213,177,2,186,219,141,172,90,87,214,138,250,208,95,49,61,22,73,82,63,146,80,200,179,91,119,69,215,89,30,54],"start":327,"end":721}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m_dep.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m_dep.json new file mode 100644 index 00000000000..98c902417e9 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/source_maps/m_dep.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[127,214,134,18,185,163,168,30,218,131,82,67,130,113,55,16,185,195,10,227,2,54,119,149,18,199,130,82,48,24,71,130],"start":36,"end":41},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m_dep"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[127,214,134,18,185,163,168,30,218,131,82,67,130,113,55,16,185,195,10,227,2,54,119,149,18,199,130,82,48,24,71,130],"start":0,"end":113},"definition_location":{"file_hash":[127,214,134,18,185,163,168,30,218,131,82,67,130,113,55,16,185,195,10,227,2,54,119,149,18,199,130,82,48,24,71,130],"start":0,"end":113},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[127,214,134,18,185,163,168,30,218,131,82,67,130,113,55,16,185,195,10,227,2,54,119,149,18,199,130,82,48,24,71,130],"start":0,"end":113}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m.move new file mode 100644 index 00000000000..b1772bb97d3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m.move @@ -0,0 +1,28 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called after another instruction in the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_same_different_files2::m; + +use macro_same_different_files2::m_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + baz!($param1); + ret = ret + $f(ret); + ret +} + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m_dep.move new file mode 100644 index 00000000000..ccbd2d595d4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/build/macro_same_different_files2/sources/m_dep.move @@ -0,0 +1,6 @@ +module macro_same_different_files2::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m.move new file mode 100644 index 00000000000..b1772bb97d3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m.move @@ -0,0 +1,28 @@ +// Test calling into another macro inside a macro (first macro +// defined in the same file than where it's called, the second +// macro defined in the same file where it is are called). +// The second macro is called after another instruction in the first macro +// (stepping into the inner macro and braking in the inner macro). +module macro_same_different_files2::m; + +use macro_same_different_files2::m_dep::baz; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + baz!($param1); + ret = ret + $f(ret); + ret +} + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m_dep.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m_dep.move new file mode 100644 index 00000000000..ccbd2d595d4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/sources/m_dep.move @@ -0,0 +1,6 @@ +module macro_same_different_files2::m_dep; + +public macro fun baz($p: u64): u64 { + let ret = $p + $p; + ret +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/test.exp new file mode 100644 index 00000000000..eb72cdb1296 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/test.exp @@ -0,0 +1,37 @@ +current frame stack: + function: test (m.move:27) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m.move:11) + scope 0 : +current frame stack: + function: test (m.move:27) + scope 0 : + function: foo (m.move:0) + scope 0 : + function: __inlined__ (m.move:11) + scope 0 : + function: __inlined__ (m_dep.move:4) + scope 0 : +current frame stack: + function: test (m.move:27) + scope 0 : + function: foo (m.move:22) + scope 0 : + v : 12 + type: u64 + +current frame stack: + function: test (m.move:27) + scope 0 : + function: foo (m.move:22) + scope 0 : + v : 12 + type: u64 + + function: __inlined__ (m_dep.move:4) + scope 0 : +line breakpoints + m_dep.move + 4 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/trace.spec.js new file mode 100644 index 00000000000..974a51ee681 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/trace.spec.js @@ -0,0 +1,29 @@ +const { run } = require('node:test'); +const path = require('path'); +let action = (runtime) => { + const filePath = path.join(__dirname, 'sources', `m_dep.move`); + let res = ''; + // step into a function, which immediately step in to a macro + runtime.step(false); + res += runtime.toString(); + // step to the second macro + runtime.step(false); + res += runtime.toString(); + // step to leave the second macro, and keep stepping + // to leave to the outer function + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + runtime.step(false); + res += runtime.toString(); + // set a breakpoint in the inner macro and continue to hit it + runtime.setLineBreakpoints(filePath, [4]); + runtime.continue(); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/traces/macro_same_different_files2__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/traces/macro_same_different_files2__m__test.json new file mode 100644 index 00000000000..8636c1aa500 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_different_files2/traces/macro_same_different_files2__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999993,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999990,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999989,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999971,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999970,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999952,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999951,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,9]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999933,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,9]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999915,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,9]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999912,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999911,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":8}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999893,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999875,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":8}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":8}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999872,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":8}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999871,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999853,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999835,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999832,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999831,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999813,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999795,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999792,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999791,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999773,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999755,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999752,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999751,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999733,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999732,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999714,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999713,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Write":{"location":{"Local":[2,10]},"root_value_after_write":{"RuntimeValue":{"value":48}}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999695,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,10]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999677,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,10]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999674,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999673,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":96}}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999655,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":48}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":48}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999637,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":96}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":96}}}},{"Instruction":{"type_parameters":[],"pc":38,"gas_left":999999634,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":96}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":48}}}},{"Effect":{"Push":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":39,"gas_left":999999633,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":144}}],"gas_left":999999633}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999632,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":144}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999631,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999631}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/Move.toml new file mode 100644 index 00000000000..b3e3788846e --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "macro_same_file" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +macro_same_file = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..860fd9802d70e97638b75593faf91a5b890728e6 GIT binary patch literal 294 zcmbtQK?=e^3`{n=+jf&f3$loaXP==jsUmIJgI#IsgFN~+KjF5hA8g%hP{A95W*`j! literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/source_maps/m.json new file mode 100644 index 00000000000..1d08bc45a90 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":81,"end":82},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":218,"end":320},"definition_location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":229,"end":232},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":236,"end":239}],"locals":[["%#2",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":283,"end":288}],["%#3",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":192,"end":195}],["%#5",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":312,"end":317}],["%#6",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":192,"end":195}],["ret#1#1",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":157,"end":160}],["ret#1#5",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":157,"end":160}],["v#1#0",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":250,"end":251}],["x#1#4",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":280,"end":281}],["x#2#8",{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":309,"end":310}]],"nops":{},"code_map":{"0":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":163,"end":180},"1":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":153,"end":160},"2":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":192,"end":195},"4":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":201,"end":204},"5":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":280,"end":281},"6":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":283,"end":284},"7":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":287,"end":288},"8":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":285,"end":286},"9":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":283,"end":288},"10":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":192,"end":195},"11":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":283,"end":288},"12":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":196,"end":197},"13":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":250,"end":251},"14":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":305,"end":306},"16":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":171,"end":172},"17":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":153,"end":160},"18":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":192,"end":195},"20":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":201,"end":204},"21":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":309,"end":310},"22":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":312,"end":313},"23":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":316,"end":317},"24":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":314,"end":315},"25":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":312,"end":317},"26":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":192,"end":195},"27":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":312,"end":317},"28":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":196,"end":197},"29":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":300,"end":318}},"is_native":false},"1":{"location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":330,"end":362},"definition_location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":341,"end":345},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":354,"end":359},"2":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":359,"end":360}},"is_native":false},"2":{"location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":57,"end":362},"definition_location":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":57,"end":362},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[255,18,107,99,93,255,70,75,47,4,119,173,78,249,186,154,194,111,141,229,224,41,247,252,60,166,20,193,26,202,204,160],"start":57,"end":362}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/sources/m.move new file mode 100644 index 00000000000..8ff3c179427 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/build/macro_same_file/sources/m.move @@ -0,0 +1,21 @@ +// Test stepping through macro defined in the same file. +module macro_same_file::m; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + $f(ret); + ret +} + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/sources/m.move new file mode 100644 index 00000000000..8ff3c179427 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/sources/m.move @@ -0,0 +1,21 @@ +// Test stepping through macro defined in the same file. +module macro_same_file::m; + +public macro fun bar($param1: u64, $f: |u64| -> u64): u64 { + let mut ret = $param1 + $param1; + ret = ret + $f(ret); + ret +} + +public fun foo(): u64 { + let v = bar!( + 1, + |x| x + x + ); + bar!(v, |x| x + x) +} + +#[test] +public fun test() { + foo(); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/test.exp new file mode 100644 index 00000000000..7aa15db715f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/test.exp @@ -0,0 +1,30 @@ +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:0) + scope 0 : + ret : 2 + type: u64 + + function: __inlined__ (m.move:6) + scope 0 : +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:13) + scope 0 : +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:13) + scope 0 : + function: __inlined__ (m.move:6) + scope 0 : +current frame stack: + function: test (m.move:20) + scope 0 : + function: foo (m.move:15) + scope 0 : + v : 6 + type: u64 + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/trace.spec.js new file mode 100644 index 00000000000..a36dc89fe37 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/trace.spec.js @@ -0,0 +1,25 @@ +let action = (runtime) => { + let res = ''; + // step into a function, which immediately step in to a macro + runtime.step(false); + // step inside the macro + runtime.step(false); + res += runtime.toString(); + // step into lambda + runtime.step(false); + res += runtime.toString(); + // step from lambda back into macro + runtime.step(false); + res += runtime.toString(); + // we need to step into lambda and back to finish the macro, + // likely because how lambda is compiled not being a real function + runtime.step(false); + runtime.step(false); + // step into the caller function and take the next step to show + // result of macro execution + runtime.step(false); + runtime.step(false); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/traces/macro_same_file__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/traces/macro_same_file__m__test.json new file mode 100644 index 00000000000..b9c523cb63f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/macro_same_file/traces/macro_same_file__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999995,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,4]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999977,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999976,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999958,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,4]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999957,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,7]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999921,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,7]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999918,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999917,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":4}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999899,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,1]},"root_value_read":{"RuntimeValue":{"value":2}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,0]},"root_value_read":{"RuntimeValue":{"value":4}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999878,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999877,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Write":{"location":{"Local":[2,6]},"root_value_after_write":{"RuntimeValue":{"value":6}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999859,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999841,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,6]},"root_value_read":{"RuntimeValue":{"value":6}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":6}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999838,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":6}}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999837,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,5]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999819,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999818,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,3]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999800,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,5]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999799,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Write":{"location":{"Local":[2,8]},"root_value_after_write":{"RuntimeValue":{"value":12}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999781,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999763,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,8]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999760,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999759,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Write":{"location":{"Local":[2,2]},"root_value_after_write":{"RuntimeValue":{"value":24}}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999741,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,3]},"root_value_read":{"RuntimeValue":{"value":12}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":12}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999723,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[2,2]},"root_value_read":{"RuntimeValue":{"value":24}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":24}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999720,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":24}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":12}}}},{"Effect":{"Push":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999719,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":36}}],"gas_left":999999719}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999718,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":36}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999717,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999717}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/Move.toml new file mode 100644 index 00000000000..bd6df8584e0 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "native_fun" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +native_fun = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..ed85ed416f69dcb7aa713b0da4c010ecef76082f GIT binary patch literal 369 zcmbtQOG*SW5Ph$bPBNWlGzha0(XDs_m+m}(xRhql^w=Z61I2Z@kLI)|{5;W#6kNvPaeH`O9$9C#>Lma2JOJkeklnbT0lw3bN#kV$fd@<9~ zpl5b<82Y@_9shalYwD*o=tJ(V%M1Upa;vGH<9?rN5ylzz^E~C(XtZb0jq-Y}g7UJF jq5*hh5wxYb`rRAQpe`Dfq<92uScYhbp5, + } + + /// An ASCII character. + public struct Char has copy, drop, store { + byte: u8, + } + + /// Convert a `byte` into a `Char` that is checked to make sure it is valid ASCII. + public fun char(byte: u8): Char { + assert!(is_valid_char(byte), EInvalidASCIICharacter); + Char { byte } + } + + /// Convert a vector of bytes `bytes` into an `String`. Aborts if + /// `bytes` contains non-ASCII characters. + public fun string(bytes: vector): String { + let x = try_string(bytes); + assert!(x.is_some(), EInvalidASCIICharacter); + x.destroy_some() + } + + /// Convert a vector of bytes `bytes` into an `String`. Returns + /// `Some()` if the `bytes` contains all valid ASCII + /// characters. Otherwise returns `None`. + public fun try_string(bytes: vector): Option { + let is_valid = bytes.all!(|byte| is_valid_char(*byte)); + if (is_valid) option::some(String { bytes }) + else option::none() + } + + /// Returns `true` if all characters in `string` are printable characters + /// Returns `false` otherwise. Not all `String`s are printable strings. + public fun all_characters_printable(string: &String): bool { + string.bytes.all!(|byte| is_printable_char(*byte)) + } + + /// Push a `Char` to the end of the `string`. + public fun push_char(string: &mut String, char: Char) { + string.bytes.push_back(char.byte); + } + + /// Pop a `Char` from the end of the `string`. + public fun pop_char(string: &mut String): Char { + Char { byte: string.bytes.pop_back() } + } + + /// Returns the length of the `string` in bytes. + public fun length(string: &String): u64 { + string.as_bytes().length() + } + + /// Append the `other` string to the end of `string`. + public fun append(string: &mut String, other: String) { + string.bytes.append(other.into_bytes()) + } + + /// Insert the `other` string at the `at` index of `string`. + public fun insert(s: &mut String, at: u64, o: String) { + assert!(at <= s.length(), EInvalidIndex); + o.into_bytes().destroy!(|e| s.bytes.insert(e, at)); + } + + /// Copy the slice of the `string` from `i` to `j` into a new `String`. + public fun substring(string: &String, i: u64, j: u64): String { + assert!(i <= j && j <= string.length(), EInvalidIndex); + let mut bytes = vector[]; + i.range_do!(j, |i| bytes.push_back(string.bytes[i])); + String { bytes } + } + + /// Get the inner bytes of the `string` as a reference + public fun as_bytes(string: &String): &vector { + &string.bytes + } + + /// Unpack the `string` to get its backing bytes + public fun into_bytes(string: String): vector { + let String { bytes } = string; + bytes + } + + /// Unpack the `char` into its underlying bytes. + public fun byte(char: Char): u8 { + let Char { byte } = char; + byte + } + + /// Returns `true` if `b` is a valid ASCII character. + /// Returns `false` otherwise. + public fun is_valid_char(b: u8): bool { + b <= 0x7F + } + + /// Returns `true` if `byte` is an printable ASCII character. + /// Returns `false` otherwise. + public fun is_printable_char(byte: u8): bool { + byte >= 0x20 && // Disallow metacharacters + byte <= 0x7E // Don't allow DEL metacharacter + } + + /// Returns `true` if `string` is empty. + public fun is_empty(string: &String): bool { + string.bytes.is_empty() + } + + /// Convert a `string` to its uppercase equivalent. + public fun to_uppercase(string: &String): String { + let bytes = string.as_bytes().map_ref!(|byte| char_to_uppercase(*byte)); + String { bytes } + } + + /// Convert a `string` to its lowercase equivalent. + public fun to_lowercase(string: &String): String { + let bytes = string.as_bytes().map_ref!(|byte| char_to_lowercase(*byte)); + String { bytes } + } + + /// Computes the index of the first occurrence of the `substr` in the `string`. + /// Returns the length of the `string` if the `substr` is not found. + /// Returns 0 if the `substr` is empty. + public fun index_of(string: &String, substr: &String): u64 { + let mut i = 0; + let (n, m) = (string.length(), substr.length()); + if (n < m) return n; + while (i <= n - m) { + let mut j = 0; + while (j < m && string.bytes[i + j] == substr.bytes[j]) j = j + 1; + if (j == m) return i; + i = i + 1; + }; + n + } + + /// Convert a `char` to its lowercase equivalent. + fun char_to_uppercase(byte: u8): u8 { + if (byte >= 0x61 && byte <= 0x7A) byte - 0x20 + else byte + } + + /// Convert a `char` to its lowercase equivalent. + fun char_to_lowercase(byte: u8): u8 { + if (byte >= 0x41 && byte <= 0x5A) byte + 0x20 + else byte + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/macros.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/macros.move new file mode 100644 index 00000000000..344794e358b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/macros.move @@ -0,0 +1,103 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/// This module holds shared implementation of macros used in `std` +module std::macros { + public macro fun num_max($x: _, $y: _): _ { + let x = $x; + let y = $y; + if (x > y) x + else y + } + + public macro fun num_min($x: _, $y: _): _ { + let x = $x; + let y = $y; + if (x < y) x + else y + } + + public macro fun num_diff($x: _, $y: _): _ { + let x = $x; + let y = $y; + if (x > y) x - y + else y - x + } + + public macro fun num_divide_and_round_up($x: _, $y: _): _ { + let x = $x; + let y = $y; + if (x % y == 0) x / y + else x / y + 1 + } + + + public macro fun num_pow($base: _, $exponent: u8): _ { + let mut base = $base; + let mut exponent = $exponent; + let mut res = 1; + while (exponent >= 1) { + if (exponent % 2 == 0) { + base = base * base; + exponent = exponent / 2; + } else { + res = res * base; + exponent = exponent - 1; + } + }; + + res + } + + public macro fun num_sqrt<$T, $U>($x: $T, $bitsize: u8): $T { + let x = $x; + let mut bit = (1: $U) << $bitsize; + let mut res = (0: $U); + let mut x = x as $U; + + while (bit != 0) { + if (x >= res + bit) { + x = x - (res + bit); + res = (res >> 1) + bit; + } else { + res = res >> 1; + }; + bit = bit >> 2; + }; + + res as $T + } + + public macro fun range_do($start: _, $stop: _, $f: |_|) { + let mut i = $start; + let stop = $stop; + while (i < stop) { + $f(i); + i = i + 1; + } + } + + public macro fun range_do_eq($start: _, $stop: _, $f: |_|) { + let mut i = $start; + let stop = $stop; + // we check `i >= stop` inside the loop instead of `i <= stop` as `while` condition to avoid + // incrementing `i` past the MAX integer value. + // Because of this, we need to check if `i > stop` and return early--instead of letting the + // loop bound handle it, like in the `range_do` macro. + if (i > stop) return; + loop { + $f(i); + if (i >= stop) break; + i = i + 1; + } + } + + public macro fun do($stop: _, $f: |_|) { + range_do!(0, $stop, $f) + } + + public macro fun do_eq($stop: _, $f: |_|) { + range_do_eq!(0, $stop, $f) + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/string.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/string.move new file mode 100644 index 00000000000..15303e8df87 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/string.move @@ -0,0 +1,138 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/// The `string` module defines the `String` type which represents UTF8 encoded +/// strings. +module std::string { + use std::ascii; + + /// An invalid UTF8 encoding. + const EInvalidUTF8: u64 = 1; + + /// Index out of range. + const EInvalidIndex: u64 = 2; + + /// A `String` holds a sequence of bytes which is guaranteed to be in utf8 + /// format. + public struct String has copy, drop, store { + bytes: vector, + } + + /// Creates a new string from a sequence of bytes. Aborts if the bytes do + /// not represent valid utf8. + public fun utf8(bytes: vector): String { + assert!(internal_check_utf8(&bytes), EInvalidUTF8); + String { bytes } + } + + /// Convert an ASCII string to a UTF8 string + public fun from_ascii(s: ascii::String): String { + String { bytes: s.into_bytes() } + } + + /// Convert an UTF8 string to an ASCII string. + /// Aborts if `s` is not valid ASCII + public fun to_ascii(s: String): ascii::String { + let String { bytes } = s; + bytes.to_ascii_string() + } + + /// Tries to create a new string from a sequence of bytes. + public fun try_utf8(bytes: vector): Option { + if (internal_check_utf8(&bytes)) option::some(String { bytes }) + else option::none() + } + + /// Returns a reference to the underlying byte vector. + public fun as_bytes(s: &String): &vector { + &s.bytes + } + + /// Unpack the `string` to get its underlying bytes. + public fun into_bytes(s: String): vector { + let String { bytes } = s; + bytes + } + + /// Checks whether this string is empty. + public fun is_empty(s: &String): bool { + s.bytes.is_empty() + } + + /// Returns the length of this string, in bytes. + public fun length(s: &String): u64 { + s.bytes.length() + } + + /// Appends a string. + public fun append(s: &mut String, r: String) { + s.bytes.append(r.bytes) + } + + /// Appends bytes which must be in valid utf8 format. + public fun append_utf8(s: &mut String, bytes: vector) { + s.append(utf8(bytes)) + } + + /// Insert the other string at the byte index in given string. The index + /// must be at a valid utf8 char boundary. + public fun insert(s: &mut String, at: u64, o: String) { + let bytes = &s.bytes; + assert!( + at <= bytes.length() && internal_is_char_boundary(bytes, at), + EInvalidIndex, + ); + let l = s.length(); + let mut front = s.substring(0, at); + let end = s.substring(at, l); + front.append(o); + front.append(end); + *s = front; + } + + /// Returns a sub-string using the given byte indices, where `i` is the first + /// byte position and `j` is the start of the first byte not included (or the + /// length of the string). The indices must be at valid utf8 char boundaries, + /// guaranteeing that the result is valid utf8. + public fun substring(s: &String, i: u64, j: u64): String { + let bytes = &s.bytes; + let l = bytes.length(); + assert!( + j <= l && + i <= j && + internal_is_char_boundary(bytes, i) && + internal_is_char_boundary(bytes, j), + EInvalidIndex, + ); + String { bytes: internal_sub_string(bytes, i, j) } + } + + /// Computes the index of the first occurrence of a string. Returns `s.length()` + /// if no occurrence found. + public fun index_of(s: &String, r: &String): u64 { + internal_index_of(&s.bytes, &r.bytes) + } + + // Native API + + native fun internal_check_utf8(v: &vector): bool; + native fun internal_is_char_boundary(v: &vector, i: u64): bool; + native fun internal_sub_string(v: &vector, i: u64, j: u64): vector; + native fun internal_index_of(v: &vector, r: &vector): u64; + + #[test_only] + public fun internal_sub_string_for_testing(v: &vector, i: u64, j: u64): vector { + internal_sub_string(v, i, j) + } + + // === Deprecated === + + #[deprecated(note = b"Use `std::string::as_bytes` instead.")] + public fun bytes(s: &String): &vector { s.as_bytes() } + + #[deprecated(note = b"Use `std::string::substring` instead.")] + public fun sub_string(s: &String, i: u64, j: u64): String { + s.substring(i, j) + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/u64.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/u64.move new file mode 100644 index 00000000000..adea617bfa6 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/u64.move @@ -0,0 +1,80 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(u64)] +module std::u64 { + /// Return the larger of `x` and `y` + public fun max(x: u64, y: u64): u64 { + std::macros::num_max!(x, y) + } + + /// Return the smaller of `x` and `y` + public fun min(x: u64, y: u64): u64 { + std::macros::num_min!(x, y) + } + + /// Return the absolute value of x - y + public fun diff(x: u64, y: u64): u64 { + std::macros::num_diff!(x, y) + } + + /// Calculate x / y, but round up the result. + public fun divide_and_round_up(x: u64, y: u64): u64 { + std::macros::num_divide_and_round_up!(x, y) + } + + /// Return the value of a base raised to a power + public fun pow(base: u64, exponent: u8): u64 { + std::macros::num_pow!(base, exponent) + } + + /// Get a nearest lower integer Square Root for `x`. Given that this + /// function can only operate with integers, it is impossible + /// to get perfect (or precise) integer square root for some numbers. + /// + /// Example: + /// ``` + /// math::sqrt(9) => 3 + /// math::sqrt(8) => 2 // the nearest lower square root is 4; + /// ``` + /// + /// In integer math, one of the possible ways to get results with more + /// precision is to use higher values or temporarily multiply the + /// value by some bigger number. Ideally if this is a square of 10 or 100. + /// + /// Example: + /// ``` + /// math::sqrt(8) => 2; + /// math::sqrt(8 * 10000) => 282; + /// // now we can use this value as if it was 2.82; + /// // but to get the actual result, this value needs + /// // to be divided by 100 (because sqrt(10000)). + /// + /// + /// math::sqrt(8 * 1000000) => 2828; // same as above, 2828 / 1000 (2.828) + /// ``` + public fun sqrt(x: u64): u64 { + std::macros::num_sqrt!(x, 64) + } + + /// Loops applying `$f` to each number from `$start` to `$stop` (exclusive) + public macro fun range_do($start: u64, $stop: u64, $f: |u64|) { + std::macros::range_do!($start, $stop, $f) + } + + /// Loops applying `$f` to each number from `$start` to `$stop` (inclusive) + public macro fun range_do_eq($start: u64, $stop: u64, $f: |u64|) { + std::macros::range_do_eq!($start, $stop, $f) + } + + /// Loops applying `$f` to each number from `0` to `$stop` (exclusive) + public macro fun do($stop: u64, $f: |u64|) { + std::macros::do!($stop, $f) + } + + /// Loops applying `$f` to each number from `0` to `$stop` (inclusive) + public macro fun do_eq($stop: u64, $f: |u64|) { + std::macros::do_eq!($stop, $f) + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/vector.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/vector.move new file mode 100644 index 00000000000..824d0aa1210 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/dependencies/MoveStdlib/vector.move @@ -0,0 +1,365 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(vector)] +/// A variable-sized container that can hold any type. Indexing is 0-based, and +/// vectors are growable. This module has many native functions. +module std::vector { + /// Allows calling `.to_string()` on a vector of `u8` to get a utf8 `String`. + public use fun std::string::utf8 as vector.to_string; + + /// Allows calling `.try_to_string()` on a vector of `u8` to get a utf8 `String`. + /// This will return `None` if the vector is not valid utf8. + public use fun std::string::try_utf8 as vector.try_to_string; + + /// Allows calling `.to_ascii_string()` on a vector of `u8` to get an `ascii::String`. + public use fun std::ascii::string as vector.to_ascii_string; + + /// Allows calling `.try_to_ascii_string()` on a vector of `u8` to get an + /// `ascii::String`. This will return `None` if the vector is not valid ascii. + public use fun std::ascii::try_string as vector.try_to_ascii_string; + + /// The index into the vector is out of bounds + const EINDEX_OUT_OF_BOUNDS: u64 = 0x20000; + + #[bytecode_instruction] + /// Create an empty vector. + public native fun empty(): vector; + + #[bytecode_instruction] + /// Return the length of the vector. + public native fun length(v: &vector): u64; + + #[syntax(index)] + #[bytecode_instruction] + /// Acquire an immutable reference to the `i`th element of the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow(v: &vector, i: u64): ∈ + + #[bytecode_instruction] + /// Add element `e` to the end of the vector `v`. + public native fun push_back(v: &mut vector, e: Element); + + #[syntax(index)] + #[bytecode_instruction] + /// Return a mutable reference to the `i`th element in the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow_mut(v: &mut vector, i: u64): &mut Element; + + #[bytecode_instruction] + /// Pop an element from the end of vector `v`. + /// Aborts if `v` is empty. + public native fun pop_back(v: &mut vector): Element; + + #[bytecode_instruction] + /// Destroy the vector `v`. + /// Aborts if `v` is not empty. + public native fun destroy_empty(v: vector); + + #[bytecode_instruction] + /// Swaps the elements at the `i`th and `j`th indices in the vector `v`. + /// Aborts if `i` or `j` is out of bounds. + public native fun swap(v: &mut vector, i: u64, j: u64); + + /// Return an vector of size one containing element `e`. + public fun singleton(e: Element): vector { + let mut v = empty(); + v.push_back(e); + v + } + + /// Reverses the order of the elements in the vector `v` in place. + public fun reverse(v: &mut vector) { + let len = v.length(); + if (len == 0) return (); + + let mut front_index = 0; + let mut back_index = len - 1; + while (front_index < back_index) { + v.swap(front_index, back_index); + front_index = front_index + 1; + back_index = back_index - 1; + } + } + + /// Pushes all of the elements of the `other` vector into the `lhs` vector. + public fun append(lhs: &mut vector, mut other: vector) { + other.reverse(); + while (!other.is_empty()) lhs.push_back(other.pop_back()); + other.destroy_empty(); + } + + /// Return `true` if the vector `v` has no elements and `false` otherwise. + public fun is_empty(v: &vector): bool { + v.length() == 0 + } + + /// Return true if `e` is in the vector `v`. + /// Otherwise, returns false. + public fun contains(v: &vector, e: &Element): bool { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return true; + i = i + 1; + }; + false + } + + /// Return `(true, i)` if `e` is in the vector `v` at index `i`. + /// Otherwise, returns `(false, 0)`. + public fun index_of(v: &vector, e: &Element): (bool, u64) { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return (true, i); + i = i + 1; + }; + (false, 0) + } + + /// Remove the `i`th element of the vector `v`, shifting all subsequent elements. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun remove(v: &mut vector, mut i: u64): Element { + let mut len = v.length(); + // i out of bounds; abort + if (i >= len) abort EINDEX_OUT_OF_BOUNDS; + + len = len - 1; + while (i < len) v.swap(i, { i = i + 1; i }); + v.pop_back() + } + + /// Insert `e` at position `i` in the vector `v`. + /// If `i` is in bounds, this shifts the old `v[i]` and all subsequent elements to the right. + /// If `i == v.length()`, this adds `e` to the end of the vector. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i > v.length()` + public fun insert(v: &mut vector, e: Element, mut i: u64) { + let len = v.length(); + // i too big abort + if (i > len) abort EINDEX_OUT_OF_BOUNDS; + + v.push_back(e); + while (i < len) { + v.swap(i, len); + i = i + 1 + } + } + + /// Swap the `i`th element of the vector `v` with the last element and then pop the vector. + /// This is O(1), but does not preserve ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun swap_remove(v: &mut vector, i: u64): Element { + assert!(!v.is_empty(), EINDEX_OUT_OF_BOUNDS); + let last_idx = v.length() - 1; + v.swap(i, last_idx); + v.pop_back() + } + + // === Macros === + + /// Create a vector of length `n` by calling the function `f` on each index. + public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> { + let mut v = vector[]; + let n = $n; + n.do!(|i| v.push_back($f(i))); + v + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Does not preserve the order of elements in the vector (starts from the end of the vector). + public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Preserves the order of elements in the vector. + public macro fun do<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Perform an action `f` on each element of the vector `v`. The vector is not modified. + public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) { + let v = $v; + v.length().do!(|i| $f(&v[i])) + } + + /// Perform an action `f` on each element of the vector `v`. + /// The function `f` takes a mutable reference to the element. + public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) { + let v = $v; + v.length().do!(|i| $f(&mut v[i])) + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map<$T, $U>($v: vector<$T>, $f: |$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do!(|e| r.push_back($f(e))); + r + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map_ref<$T, $U>($v: &vector<$T>, $f: |&$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do_ref!(|e| r.push_back($f(e))); + r + } + + /// Filter the vector `v` by applying the function `f` to each element. + /// Return a new vector containing only the elements for which `f` returns `true`. + public macro fun filter<$T: drop>($v: vector<$T>, $f: |&$T| -> bool): vector<$T> { + let v = $v; + let mut r = vector[]; + v.do!(|e| if ($f(&e)) r.push_back(e)); + r + } + + /// Split the vector `v` into two vectors by applying the function `f` to each element. + /// Return a tuple containing two vectors: the first containing the elements for which `f` returns `true`, + /// and the second containing the elements for which `f` returns `false`. + public macro fun partition<$T>($v: vector<$T>, $f: |&$T| -> bool): (vector<$T>, vector<$T>) { + let v = $v; + let mut r1 = vector[]; + let mut r2 = vector[]; + v.do!(|e| if ($f(&e)) r1.push_back(e) else r2.push_back(e)); + (r1, r2) + } + + /// Finds the index of first element in the vector `v` that satisfies the predicate `f`. + /// Returns `some(index)` if such an element is found, otherwise `none()`. + public macro fun find_index<$T>($v: &vector<$T>, $f: |&$T| -> bool): Option { + let v = $v; + 'find_index: { + v.length().do!(|i| if ($f(&v[i])) return 'find_index option::some(i)); + option::none() + } + } + + /// Count how many elements in the vector `v` satisfy the predicate `f`. + public macro fun count<$T>($v: &vector<$T>, $f: |&$T| -> bool): u64 { + let v = $v; + let mut count = 0; + v.do_ref!(|e| if ($f(e)) count = count + 1); + count + } + + /// Reduce the vector `v` to a single value by applying the function `f` to each element. + /// Similar to `fold_left` in Rust and `reduce` in Python and JavaScript. + public macro fun fold<$T, $Acc>($v: vector<$T>, $init: $Acc, $f: |$Acc, $T| -> $Acc): $Acc { + let v = $v; + let mut acc = $init; + v.do!(|e| acc = $f(acc, e)); + acc + } + + /// Whether any element in the vector `v` satisfies the predicate `f`. + /// If the vector is empty, returns `false`. + public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'any: { + v.do_ref!(|e| if ($f(e)) return 'any true); + false + } + } + + /// Whether all elements in the vector `v` satisfy the predicate `f`. + /// If the vector is empty, returns `true`. + public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'all: { + v.do_ref!(|e| if (!$f(e)) return 'all false); + true + } + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + v2.reverse(); + let len = v1.length(); + assert!(len == v2.length()); + v1.do!(|el1| $f(el1, v2.pop_back())); + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// Starts from the end of the vectors. + public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + v1.destroy!(|el1| $f(el1, v2.pop_back())); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The vectors are not modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&v1[i], &v2[i])); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to mutable references of each pair + /// of elements. The vectors may be modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_mut<$T1, $T2>( + $v1: &mut vector<$T1>, + $v2: &mut vector<$T2>, + $f: |&mut $T1, &mut $T2|, + ) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&mut v1[i], &mut v2[i])); + } + + /// Destroys two vectors `v1` and `v2` by applying the function `f` to each pair of elements. + /// The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map<$T1, $T2, $U>( + $v1: vector<$T1>, + $v2: vector<$T2>, + $f: |$T1, $T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map_ref<$T1, $T2, $U>( + $v1: &vector<$T1>, + $v2: &vector<$T2>, + $f: |&$T1, &$T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do_ref!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/m.move new file mode 100644 index 00000000000..1c64328ea36 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/build/native_fun/sources/m.move @@ -0,0 +1,14 @@ +// Test native function execution (vector length). +module native_fun::m; + +use std::string::{String, utf8, index_of}; + +fun foo(s: String, sub: vector, p: u64): u64 { + s.index_of(&utf8(sub)) + p +} + +#[test] +fun test() { + let mut _res = foo(utf8(b"hello"), b"e", 42); + _res = _res + foo(utf8(b"hello"), b"l", _res); // to force another unoptimized read to keep `res` visible +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/sources/m.move new file mode 100644 index 00000000000..1c64328ea36 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/sources/m.move @@ -0,0 +1,14 @@ +// Test native function execution (vector length). +module native_fun::m; + +use std::string::{String, utf8, index_of}; + +fun foo(s: String, sub: vector, p: u64): u64 { + s.index_of(&utf8(sub)) + p +} + +#[test] +fun test() { + let mut _res = foo(utf8(b"hello"), b"e", 42); + _res = _res + foo(utf8(b"hello"), b"l", _res); // to force another unoptimized read to keep `res` visible +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/test.exp new file mode 100644 index 00000000000..2bb0e676ee4 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/test.exp @@ -0,0 +1,6 @@ +current frame stack: + function: test (m.move:13) + scope 0 : + _res : 43 + type: u64 + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/trace.spec.js new file mode 100644 index 00000000000..2c2fa18537f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/trace.spec.js @@ -0,0 +1,8 @@ +let action = (runtime) => { + let res = ''; + // step over a function containing a native call + runtime.step(true); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/traces/native_fun__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/traces/native_fun__m__test.json new file mode 100644 index 00000000000..979d3eac38d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/native_fun/traces/native_fun__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999992,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":[104,101,108,108,111]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999992,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[104,101,108,108,111]}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null}],"is_native":false},"gas_left":999999992}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999981,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":[104,101,108,108,111]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[4,0]},"snapshot":[104,101,108,108,111]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999981,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":9,"function_name":"internal_check_utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":13,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[4,0]},"snapshot":[104,101,108,108,111]}}],"return_types":[{"type_":"bool","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":"Imm"}],"is_native":true},"gas_left":999999981}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"CloseFrame":{"frame_id":9,"return_":[{"RuntimeValue":{"value":true}}],"gas_left":999999900}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999899,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999898,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999891,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":[104,101,108,108,111]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[104,101,108,108,111]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999887,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[104,101,108,108,111]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999886,"instruction":"RET"}},{"CloseFrame":{"frame_id":4,"return_":[{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}],"gas_left":999999886}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999882,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":[101]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999879,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999879,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":28,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},{"RuntimeValue":{"value":[101]}},{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null},{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u64","ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999999879}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999868,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999867,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Effect":{"Write":{"location":{"Local":[28,4]},"root_value_after_write":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999864,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,1]},"root_value_read":{"RuntimeValue":{"value":[101]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[101]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999864,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":39,"function_name":"utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[101]}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null}],"is_native":false},"gas_left":999999864}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999853,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[39,0]},"root_value_read":{"RuntimeValue":{"value":[101]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[39,0]},"snapshot":[101]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999853,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":44,"function_name":"internal_check_utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":13,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[39,0]},"snapshot":[101]}}],"return_types":[{"type_":"bool","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":"Imm"}],"is_native":true},"gas_left":999999853}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"CloseFrame":{"frame_id":44,"return_":[{"RuntimeValue":{"value":true}}],"gas_left":999999780}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999779,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999778,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999775,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[39,0]},"root_value_read":{"RuntimeValue":{"value":[101]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[101]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999771,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[101]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999770,"instruction":"RET"}},{"CloseFrame":{"frame_id":39,"return_":[{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}],"gas_left":999999770}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999769,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}},{"Effect":{"Write":{"location":{"Local":[28,3]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999759,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,4]},"root_value_read":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999749,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,3]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[101]}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[28,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999749,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":68,"function_name":"index_of","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":12,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},{"ImmRef":{"location":{"Local":[28,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":"Imm"},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999999749}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999738,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,0]},"root_value_read":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999728,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[28,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[28,0]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999718,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,1]},"root_value_read":{"ImmRef":{"location":{"Local":[28,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[28,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999708,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[28,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[28,3]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999708,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":82,"function_name":"internal_index_of","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":16,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Indexed":[{"Local":[28,0]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},{"ImmRef":{"location":{"Indexed":[{"Local":[28,3]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[101]}}}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":"Imm"},{"type_":{"vector":"u8"},"ref_type":"Imm"}],"is_native":true},"gas_left":999999708}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"CloseFrame":{"frame_id":82,"return_":[{"RuntimeValue":{"value":1}}],"gas_left":999999633}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999632,"instruction":"RET"}},{"CloseFrame":{"frame_id":68,"return_":[{"RuntimeValue":{"value":1}}],"gas_left":999999632}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999614,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[28,2]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999611,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":43}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999610,"instruction":"RET"}},{"CloseFrame":{"frame_id":28,"return_":[{"RuntimeValue":{"value":43}}],"gas_left":999999610}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999609,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":43}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":43}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999591,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":43}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":43}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999583,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":[104,101,108,108,111]}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999583,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":105,"function_name":"utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[104,101,108,108,111]}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null}],"is_native":false},"gas_left":999999583}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999572,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[105,0]},"root_value_read":{"RuntimeValue":{"value":[104,101,108,108,111]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[105,0]},"snapshot":[104,101,108,108,111]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999572,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":110,"function_name":"internal_check_utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":13,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[105,0]},"snapshot":[104,101,108,108,111]}}],"return_types":[{"type_":"bool","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":"Imm"}],"is_native":true},"gas_left":999999572}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"CloseFrame":{"frame_id":110,"return_":[{"RuntimeValue":{"value":true}}],"gas_left":999999491}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999490,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999489,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999482,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[105,0]},"root_value_read":{"RuntimeValue":{"value":[104,101,108,108,111]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[104,101,108,108,111]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999478,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[104,101,108,108,111]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999477,"instruction":"RET"}},{"CloseFrame":{"frame_id":105,"return_":[{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}],"gas_left":999999477}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999473,"instruction":"LD_CONST"}},{"Effect":{"Push":{"RuntimeValue":{"value":[108]}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999455,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":43}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":43}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999455,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":130,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},{"RuntimeValue":{"value":[108]}},{"RuntimeValue":{"value":43}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null},{"type_":{"vector":"u8"},"ref_type":null},{"type_":"u64","ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999999455}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999444,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[130,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999443,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Effect":{"Write":{"location":{"Local":[130,4]},"root_value_after_write":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999440,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[130,1]},"root_value_read":{"RuntimeValue":{"value":[108]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[108]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999440,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":141,"function_name":"utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":[108]}}],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":null}],"is_native":false},"gas_left":999999440}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999429,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[141,0]},"root_value_read":{"RuntimeValue":{"value":[108]}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[141,0]},"snapshot":[108]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999429,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":146,"function_name":"internal_check_utf8","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":13,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[141,0]},"snapshot":[108]}}],"return_types":[{"type_":"bool","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":"Imm"}],"is_native":true},"gas_left":999999429}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"CloseFrame":{"frame_id":146,"return_":[{"RuntimeValue":{"value":true}}],"gas_left":999999356}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999355,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999354,"instruction":"BRANCH"}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999351,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[141,0]},"root_value_read":{"RuntimeValue":{"value":[108]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[108]}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999347,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[108]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999346,"instruction":"RET"}},{"CloseFrame":{"frame_id":141,"return_":[{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}],"gas_left":999999346}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999345,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}},{"Effect":{"Write":{"location":{"Local":[130,3]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999335,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[130,4]},"root_value_read":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999325,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[130,3]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x1::string::String","fields":{"bytes":[108]}}}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[130,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999325,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":170,"function_name":"index_of","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":12,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},{"ImmRef":{"location":{"Local":[130,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":"Imm"},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"string","name":"String","type_args":[]}},"ref_type":"Imm"}],"is_native":false},"gas_left":999999325}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999314,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[170,0]},"root_value_read":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999304,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[130,0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[130,0]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999294,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[170,1]},"root_value_read":{"ImmRef":{"location":{"Local":[130,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[130,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999284,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[130,3]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[130,3]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999284,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":184,"function_name":"internal_index_of","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"binary_member_index":16,"type_instantiation":[],"parameters":[{"ImmRef":{"location":{"Indexed":[{"Local":[130,0]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[104,101,108,108,111]}}}},{"ImmRef":{"location":{"Indexed":[{"Local":[130,3]},0]},"snapshot":{"type":"0x1::string::String","fields":{"bytes":[108]}}}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"vector":"u8"},"ref_type":"Imm"},{"type_":{"vector":"u8"},"ref_type":"Imm"}],"is_native":true},"gas_left":999999284}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"CloseFrame":{"frame_id":184,"return_":[{"RuntimeValue":{"value":2}}],"gas_left":999999207}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999206,"instruction":"RET"}},{"CloseFrame":{"frame_id":170,"return_":[{"RuntimeValue":{"value":2}}],"gas_left":999999206}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999188,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[130,2]},"root_value_read":{"RuntimeValue":{"value":43}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":43}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999185,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":43}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":45}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999184,"instruction":"RET"}},{"CloseFrame":{"frame_id":130,"return_":[{"RuntimeValue":{"value":45}}],"gas_left":999999184}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999181,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":45}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":43}}}},{"Effect":{"Push":{"RuntimeValue":{"value":88}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999180,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":88}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999179,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999179}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/Move.toml new file mode 100644 index 00000000000..441337ac1f6 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "references" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +references = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/bytecode_modules/dependencies/MoveStdlib/vector.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/bytecode_modules/dependencies/MoveStdlib/vector.mv new file mode 100644 index 0000000000000000000000000000000000000000..79c6d2eb99157a351717e0a6c0cc80cc20a46ce2 GIT binary patch literal 1123 zcmaJ=%}(4f5T3CeCmCm#-35WvB9-mZ_SQ4UQbGF|(XwkGDkM=7{vN0IK1vTg_0(%m zeTmLE5J4qs$)BD1`DQ#b`MUeZSpY~7j5f9DOmw@Bf8h^IzUe*tT~qc`|2D7%Gq8XN zKuR;Bi5N2$0jQY0!KK8=QpSlB+#s)MxVdr~z` zbwmA;UtV>|sw%r>QMNBujbC;?Z;P|iH*J1eHF@XTt|-q&Yd)LmF87ypcNYarigN95 z^Xk;HuW!1fXnVE2@a0)|p43&HpDb5j()y}B4>#NR%j(+4jlbpqK5d!$!gp0^+M8wV z1oGY_y()_?M4t?|ysnD2D($sjbydUl``<#HaLalNR8k|Zj^e^9FuWt)mUqls+KTZ9 zdZ5d2gbt3#p-QD+ZwTHWQl?4E2!%B_j(e|$?@T#u**2`53`r3#%xmH?BK%BF4a#jc z#o>!hqp2{-c))ao2QbD1+%s7e6O8bfjwn)W;PBIs9}}=~cT7tDE&b}DKm64F2TlTqN7TQ5H}paO q+lOd_!>fr<>@bCt-A2@>6eu5M#np7^6jMmpDH;GXJZ(DTDf$cNL2%3f literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..d9ae7daf44225ae558ee3aa99f6872d33a2f5c10 GIT binary patch literal 612 zcmbtSJ5Iwu5S`C@ZLimf6WJ*c5)Gn20@{=axPcE~q2NT85<9XD_o1TW033mH&~XDQ z#&+b;v&HV{&6_tn`}XzpJJ0}N5Hx9zCui!4oSSnueM9dDZ_Niq_LIIad{-Vg7~lku zq<{ewAb>{_84}3KhJ+rF>u3}%yB@fPH6ue0v&-lM8XuTFFpS39wAk&pdD_;`tJb8| z?hu}=>in_Iv!>XTdEI2|s?OTHX^V2>tc!g6#OtcUoo)K^tcUzYvfI3^%AgUUtm#GV za10dHY531&(e`T57-jpaXsR-L$yd^|yV6jg1!${U2L8`NAoe}f9LmsyEKerSccCv2 zq6Vfg#l%o75hb#5XG*{B(eg+PI5GG)rH(0;1QZ7lQM?H7dL-RpydW`3Y#FinQDelG uFo(`YaHAR8BVj4VhNRu$Ht>LBM++f_G=Z7e&ZvOYC^l2wCy}l)Is5{zyH8vI literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/dependencies/MoveStdlib/vector.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/dependencies/MoveStdlib/vector.json new file mode 100644 index 00000000000..9d5a13fdd3b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/dependencies/MoveStdlib/vector.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":261,"end":267},"module_name":["0000000000000000000000000000000000000000000000000000000000000001","vector"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1184,"end":1236},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1202,"end":1207},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1208,"end":1215}]],"parameters":[],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1220,"end":1235}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1311,"end":1371},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1329,"end":1335},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1336,"end":1343}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1345,"end":1346}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1367,"end":1370}],"locals":[],"nops":{},"code_map":{},"is_native":true},"2":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1545,"end":1618},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1563,"end":1569},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1570,"end":1577}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1579,"end":1580}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1600,"end":1601}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1609,"end":1617}],"locals":[],"nops":{},"code_map":{},"is_native":true},"3":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1706,"end":1780},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1724,"end":1733},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1734,"end":1741}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1743,"end":1744}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1768,"end":1769}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"4":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1950,"end":2035},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1968,"end":1978},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1979,"end":1986}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1988,"end":1989}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2013,"end":2014}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2022,"end":2034}],"locals":[],"nops":{},"code_map":{},"is_native":true},"5":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2152,"end":2222},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2170,"end":2178},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2179,"end":2186}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2188,"end":2189}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2214,"end":2221}],"locals":[],"nops":{},"code_map":{},"is_native":true},"6":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2324,"end":2385},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2342,"end":2355},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2356,"end":2363}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2365,"end":2366}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"7":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2543,"end":2616},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2561,"end":2565},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2566,"end":2573}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2575,"end":2576}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2600,"end":2601}],["j#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2608,"end":2609}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"8":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2683,"end":2812},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2694,"end":2703},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2704,"end":2711}]],"parameters":[["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2713,"end":2714}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2726,"end":2741}],"locals":[["v#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2760,"end":2761}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2764,"end":2771},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2756,"end":2761},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2782},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2793,"end":2794},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2795},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2805,"end":2806}},"is_native":false},"9":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2889,"end":3266},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2900,"end":2907},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2908,"end":2915}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2917,"end":2918}]],"returns":[],"locals":[["back_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3057,"end":3067}],["front_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3024,"end":3035}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2963},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2972},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2986,"end":2989},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2993,"end":2994},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2990,"end":2992},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2982,"end":3005},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2996,"end":3005},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3038,"end":3039},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3020,"end":3035},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3070,"end":3073},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3076,"end":3077},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3074,"end":3075},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3053,"end":3067},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3094,"end":3105},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3108,"end":3118},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3106,"end":3107},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3135},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3141,"end":3152},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3154,"end":3164},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3165},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3193,"end":3204},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3207,"end":3208},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3205,"end":3206},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3179,"end":3190},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3235,"end":3245},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3248,"end":3249},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3246,"end":3247},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3222,"end":3232},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260}},"is_native":false},"10":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3352,"end":3564},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3363,"end":3369},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3370,"end":3377}]],"parameters":[["lhs#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3379,"end":3382}],["other#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3410,"end":3415}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3449},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3459},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3482},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3493},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3476,"end":3477},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3498},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3514},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3525},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3526},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3541},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3557,"end":3558}},"is_native":false},"11":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3649,"end":3736},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3660,"end":3668},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3669,"end":3676}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3678,"end":3679}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3700,"end":3704}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3716},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3725},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3729,"end":3730},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3726,"end":3728},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3730}},"is_native":false},"12":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3825,"end":4069},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3836,"end":3844},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3845,"end":3852}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3854,"end":3855}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3875,"end":3876}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3889,"end":3893}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3912,"end":3913}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3916,"end":3917},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3908,"end":3913},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3938},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3947},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3964,"end":3965},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3968,"end":3971},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3966,"end":3967},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3992,"end":3993},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3994,"end":3995},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3991,"end":3996},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4000,"end":4001},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3997,"end":3999},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3987,"end":4014},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4010,"end":4014},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4032,"end":4033},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4036,"end":4037},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4034,"end":4035},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4028,"end":4029},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4058,"end":4063}},"is_native":false},"13":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4185,"end":4446},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4196,"end":4204},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4205,"end":4212}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4214,"end":4215}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4235,"end":4236}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4250,"end":4254},{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4256,"end":4259}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4279,"end":4280}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4283,"end":4284},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4275,"end":4280},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4305},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4314},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4331,"end":4332},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4335,"end":4338},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4333,"end":4334},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4359,"end":4360},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4361,"end":4362},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4358,"end":4363},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4367,"end":4368},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4364,"end":4366},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4354,"end":4386},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4378,"end":4382},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4384,"end":4385},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4404,"end":4405},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4408,"end":4409},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4406,"end":4407},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4400,"end":4401},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4431,"end":4436},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4438,"end":4439},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440}},"is_native":false},"14":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4649,"end":4945},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4660,"end":4666},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4667,"end":4674}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4676,"end":4677}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4705,"end":4706}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4714,"end":4721}],"locals":[["%#1",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898}],["%#2",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4740,"end":4743}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4747},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4756},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4736,"end":4743},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4804,"end":4805},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4809,"end":4812},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4806,"end":4808},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4800,"end":4840},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4820,"end":4840},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4857,"end":4860},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4863,"end":4864},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4861,"end":4862},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4851,"end":4854},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4881,"end":4882},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4885,"end":4888},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4883,"end":4884},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4906,"end":4907},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4910,"end":4911},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4908,"end":4909},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4902,"end":4903},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4913,"end":4914},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4917},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4928},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4939}},"is_native":false},"15":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5279,"end":5579},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5290,"end":5296},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5297,"end":5304}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5306,"end":5307}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5331,"end":5332}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5347,"end":5348}]],"returns":[],"locals":[["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5376},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5385},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5426,"end":5427},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5430,"end":5433},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5428,"end":5429},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5422,"end":5461},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5441,"end":5461},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5473},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5484,"end":5485},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5486},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5503,"end":5504},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5507,"end":5510},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5505,"end":5506},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5527},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5533,"end":5534},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5536,"end":5539},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5540},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5558,"end":5559},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5562,"end":5563},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5560,"end":5561},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5554,"end":5555},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573}},"is_native":false},"16":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5801,"end":6025},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5812,"end":5823},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5824,"end":5831}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5833,"end":5834}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5858,"end":5859}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5867,"end":5874}],"locals":[["last_idx#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5895},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5906},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5893,"end":5894},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5908,"end":5928},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5955},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5964},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5967,"end":5968},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5965,"end":5966},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5979},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5985,"end":5986},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5988,"end":5996},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5997},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6008},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6019}},"is_native":false},"17":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981}},"is_native":false}},"constant_map":{"EINDEX_OUT_OF_BOUNDS":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/m.json new file mode 100644 index 00000000000..7b17936d2cc --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":54,"end":55},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{"0":{"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":72,"end":82},"type_parameters":[],"fields":[{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":98,"end":110},{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":130,"end":142},{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":153,"end":169}]},"1":{"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":201,"end":213},"type_parameters":[],"fields":[{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":235,"end":240}]}},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":250,"end":654},"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":254,"end":257},"type_parameters":[],"parameters":[["some_struct_ref#0#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":263,"end":278}],["vec_ref#0#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":301,"end":308}],["num_ref#0#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":332,"end":339}]],"returns":[{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":350,"end":353}],"locals":[["e1#1#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":455,"end":457}],["e2#1#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":545,"end":547}]],"nops":{},"code_map":{"0":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":397,"end":399},"1":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":360,"end":375},"2":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":360,"end":394},"4":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":360,"end":399},"5":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":437,"end":444},"6":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":436,"end":444},"7":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":405,"end":420},"8":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":405,"end":433},"9":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":405,"end":444},"10":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":484,"end":499},"11":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":479,"end":516},"12":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":518,"end":519},"13":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":460,"end":520},"14":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":455,"end":457},"15":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":532,"end":534},"16":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":527,"end":529},"17":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":526,"end":534},"18":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":569,"end":576},"19":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":578,"end":579},"20":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":550,"end":580},"21":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":545,"end":547},"22":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":592,"end":594},"23":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":587,"end":589},"24":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":586,"end":594},"25":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":601,"end":608},"26":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":600,"end":608},"27":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":611,"end":626},"28":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":611,"end":639},"30":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":609,"end":610},"31":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":642,"end":649},"33":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":650,"end":651},"34":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":642,"end":652},"36":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":640,"end":641},"37":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":600,"end":652}},"is_native":false},"1":{"location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":656,"end":834},"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":660,"end":671},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":675,"end":685}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":749,"end":750},"1":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":727,"end":752},"2":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":776,"end":777},"3":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":823,"end":824},"4":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":805,"end":825},"5":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":692,"end":832}},"is_native":false},"2":{"location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":844,"end":1036},"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":848,"end":852},"type_parameters":[],"parameters":[],"returns":[],"locals":[["num#1#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":982,"end":985}],["some_struct#1#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":869,"end":880}],["vec#1#0",{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":910,"end":913}]],"nops":{},"code_map":{"0":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":883,"end":896},"1":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":865,"end":880},"2":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":934,"end":935},"3":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":916,"end":936},"4":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":906,"end":913},"5":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":960,"end":968},"6":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":970,"end":971},"7":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":942,"end":972},"8":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":988,"end":990},"9":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":982,"end":985},"10":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":1000,"end":1016},"11":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":1018,"end":1026},"12":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":1028,"end":1032},"13":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":996,"end":1033},"15":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":1033,"end":1034}},"is_native":false},"3":{"location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":35,"end":1036},"definition_location":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":35,"end":1036},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[229,240,178,48,60,183,228,141,55,148,99,201,16,75,204,42,202,88,124,209,100,38,8,162,249,132,38,205,211,78,130,234],"start":35,"end":1036}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/dependencies/MoveStdlib/vector.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/dependencies/MoveStdlib/vector.move new file mode 100644 index 00000000000..824d0aa1210 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/dependencies/MoveStdlib/vector.move @@ -0,0 +1,365 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(vector)] +/// A variable-sized container that can hold any type. Indexing is 0-based, and +/// vectors are growable. This module has many native functions. +module std::vector { + /// Allows calling `.to_string()` on a vector of `u8` to get a utf8 `String`. + public use fun std::string::utf8 as vector.to_string; + + /// Allows calling `.try_to_string()` on a vector of `u8` to get a utf8 `String`. + /// This will return `None` if the vector is not valid utf8. + public use fun std::string::try_utf8 as vector.try_to_string; + + /// Allows calling `.to_ascii_string()` on a vector of `u8` to get an `ascii::String`. + public use fun std::ascii::string as vector.to_ascii_string; + + /// Allows calling `.try_to_ascii_string()` on a vector of `u8` to get an + /// `ascii::String`. This will return `None` if the vector is not valid ascii. + public use fun std::ascii::try_string as vector.try_to_ascii_string; + + /// The index into the vector is out of bounds + const EINDEX_OUT_OF_BOUNDS: u64 = 0x20000; + + #[bytecode_instruction] + /// Create an empty vector. + public native fun empty(): vector; + + #[bytecode_instruction] + /// Return the length of the vector. + public native fun length(v: &vector): u64; + + #[syntax(index)] + #[bytecode_instruction] + /// Acquire an immutable reference to the `i`th element of the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow(v: &vector, i: u64): ∈ + + #[bytecode_instruction] + /// Add element `e` to the end of the vector `v`. + public native fun push_back(v: &mut vector, e: Element); + + #[syntax(index)] + #[bytecode_instruction] + /// Return a mutable reference to the `i`th element in the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow_mut(v: &mut vector, i: u64): &mut Element; + + #[bytecode_instruction] + /// Pop an element from the end of vector `v`. + /// Aborts if `v` is empty. + public native fun pop_back(v: &mut vector): Element; + + #[bytecode_instruction] + /// Destroy the vector `v`. + /// Aborts if `v` is not empty. + public native fun destroy_empty(v: vector); + + #[bytecode_instruction] + /// Swaps the elements at the `i`th and `j`th indices in the vector `v`. + /// Aborts if `i` or `j` is out of bounds. + public native fun swap(v: &mut vector, i: u64, j: u64); + + /// Return an vector of size one containing element `e`. + public fun singleton(e: Element): vector { + let mut v = empty(); + v.push_back(e); + v + } + + /// Reverses the order of the elements in the vector `v` in place. + public fun reverse(v: &mut vector) { + let len = v.length(); + if (len == 0) return (); + + let mut front_index = 0; + let mut back_index = len - 1; + while (front_index < back_index) { + v.swap(front_index, back_index); + front_index = front_index + 1; + back_index = back_index - 1; + } + } + + /// Pushes all of the elements of the `other` vector into the `lhs` vector. + public fun append(lhs: &mut vector, mut other: vector) { + other.reverse(); + while (!other.is_empty()) lhs.push_back(other.pop_back()); + other.destroy_empty(); + } + + /// Return `true` if the vector `v` has no elements and `false` otherwise. + public fun is_empty(v: &vector): bool { + v.length() == 0 + } + + /// Return true if `e` is in the vector `v`. + /// Otherwise, returns false. + public fun contains(v: &vector, e: &Element): bool { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return true; + i = i + 1; + }; + false + } + + /// Return `(true, i)` if `e` is in the vector `v` at index `i`. + /// Otherwise, returns `(false, 0)`. + public fun index_of(v: &vector, e: &Element): (bool, u64) { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return (true, i); + i = i + 1; + }; + (false, 0) + } + + /// Remove the `i`th element of the vector `v`, shifting all subsequent elements. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun remove(v: &mut vector, mut i: u64): Element { + let mut len = v.length(); + // i out of bounds; abort + if (i >= len) abort EINDEX_OUT_OF_BOUNDS; + + len = len - 1; + while (i < len) v.swap(i, { i = i + 1; i }); + v.pop_back() + } + + /// Insert `e` at position `i` in the vector `v`. + /// If `i` is in bounds, this shifts the old `v[i]` and all subsequent elements to the right. + /// If `i == v.length()`, this adds `e` to the end of the vector. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i > v.length()` + public fun insert(v: &mut vector, e: Element, mut i: u64) { + let len = v.length(); + // i too big abort + if (i > len) abort EINDEX_OUT_OF_BOUNDS; + + v.push_back(e); + while (i < len) { + v.swap(i, len); + i = i + 1 + } + } + + /// Swap the `i`th element of the vector `v` with the last element and then pop the vector. + /// This is O(1), but does not preserve ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun swap_remove(v: &mut vector, i: u64): Element { + assert!(!v.is_empty(), EINDEX_OUT_OF_BOUNDS); + let last_idx = v.length() - 1; + v.swap(i, last_idx); + v.pop_back() + } + + // === Macros === + + /// Create a vector of length `n` by calling the function `f` on each index. + public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> { + let mut v = vector[]; + let n = $n; + n.do!(|i| v.push_back($f(i))); + v + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Does not preserve the order of elements in the vector (starts from the end of the vector). + public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Preserves the order of elements in the vector. + public macro fun do<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Perform an action `f` on each element of the vector `v`. The vector is not modified. + public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) { + let v = $v; + v.length().do!(|i| $f(&v[i])) + } + + /// Perform an action `f` on each element of the vector `v`. + /// The function `f` takes a mutable reference to the element. + public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) { + let v = $v; + v.length().do!(|i| $f(&mut v[i])) + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map<$T, $U>($v: vector<$T>, $f: |$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do!(|e| r.push_back($f(e))); + r + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map_ref<$T, $U>($v: &vector<$T>, $f: |&$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do_ref!(|e| r.push_back($f(e))); + r + } + + /// Filter the vector `v` by applying the function `f` to each element. + /// Return a new vector containing only the elements for which `f` returns `true`. + public macro fun filter<$T: drop>($v: vector<$T>, $f: |&$T| -> bool): vector<$T> { + let v = $v; + let mut r = vector[]; + v.do!(|e| if ($f(&e)) r.push_back(e)); + r + } + + /// Split the vector `v` into two vectors by applying the function `f` to each element. + /// Return a tuple containing two vectors: the first containing the elements for which `f` returns `true`, + /// and the second containing the elements for which `f` returns `false`. + public macro fun partition<$T>($v: vector<$T>, $f: |&$T| -> bool): (vector<$T>, vector<$T>) { + let v = $v; + let mut r1 = vector[]; + let mut r2 = vector[]; + v.do!(|e| if ($f(&e)) r1.push_back(e) else r2.push_back(e)); + (r1, r2) + } + + /// Finds the index of first element in the vector `v` that satisfies the predicate `f`. + /// Returns `some(index)` if such an element is found, otherwise `none()`. + public macro fun find_index<$T>($v: &vector<$T>, $f: |&$T| -> bool): Option { + let v = $v; + 'find_index: { + v.length().do!(|i| if ($f(&v[i])) return 'find_index option::some(i)); + option::none() + } + } + + /// Count how many elements in the vector `v` satisfy the predicate `f`. + public macro fun count<$T>($v: &vector<$T>, $f: |&$T| -> bool): u64 { + let v = $v; + let mut count = 0; + v.do_ref!(|e| if ($f(e)) count = count + 1); + count + } + + /// Reduce the vector `v` to a single value by applying the function `f` to each element. + /// Similar to `fold_left` in Rust and `reduce` in Python and JavaScript. + public macro fun fold<$T, $Acc>($v: vector<$T>, $init: $Acc, $f: |$Acc, $T| -> $Acc): $Acc { + let v = $v; + let mut acc = $init; + v.do!(|e| acc = $f(acc, e)); + acc + } + + /// Whether any element in the vector `v` satisfies the predicate `f`. + /// If the vector is empty, returns `false`. + public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'any: { + v.do_ref!(|e| if ($f(e)) return 'any true); + false + } + } + + /// Whether all elements in the vector `v` satisfy the predicate `f`. + /// If the vector is empty, returns `true`. + public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'all: { + v.do_ref!(|e| if (!$f(e)) return 'all false); + true + } + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + v2.reverse(); + let len = v1.length(); + assert!(len == v2.length()); + v1.do!(|el1| $f(el1, v2.pop_back())); + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// Starts from the end of the vectors. + public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + v1.destroy!(|el1| $f(el1, v2.pop_back())); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The vectors are not modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&v1[i], &v2[i])); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to mutable references of each pair + /// of elements. The vectors may be modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_mut<$T1, $T2>( + $v1: &mut vector<$T1>, + $v2: &mut vector<$T2>, + $f: |&mut $T1, &mut $T2|, + ) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&mut v1[i], &mut v2[i])); + } + + /// Destroys two vectors `v1` and `v2` by applying the function `f` to each pair of elements. + /// The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map<$T1, $T2, $U>( + $v1: vector<$T1>, + $v2: vector<$T2>, + $f: |$T1, $T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map_ref<$T1, $T2, $U>( + $v1: &vector<$T1>, + $v2: &vector<$T2>, + $f: |&$T1, &$T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do_ref!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/m.move new file mode 100644 index 00000000000..3b4c1e24e41 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/build/references/sources/m.move @@ -0,0 +1,45 @@ +// Test tracking reference values. +module references::m; + +public struct SomeStruct has drop { + struct_field: SimpleStruct, + simple_field: u64, + vec_simple_field: vector, +} + +public struct SimpleStruct has drop, copy { + field: u64, +} + +fun foo( + some_struct_ref: &mut SomeStruct, + vec_ref: &mut vector, + num_ref: &u64, +): u64 { + some_struct_ref.struct_field.field = 42; + some_struct_ref.simple_field = *num_ref; + + let e1 = vector::borrow_mut(&mut some_struct_ref.vec_simple_field, 0); + *e1 = 42; + + let e2 = vector::borrow_mut(vec_ref, 0); + *e2 = 42; + *num_ref + some_struct_ref.simple_field + vec_ref[0] +} + +fun some_struct(): SomeStruct { + SomeStruct { + struct_field: SimpleStruct { field: 0 }, + simple_field: 0, + vec_simple_field: vector::singleton(0), + } +} + +#[test] +fun test() { + let mut some_struct = some_struct(); + let mut vec = vector::singleton(0); + vector::push_back(&mut vec, 7); + let num = 42; + foo(&mut some_struct, &mut vec, &num); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/sources/m.move new file mode 100644 index 00000000000..3b4c1e24e41 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/sources/m.move @@ -0,0 +1,45 @@ +// Test tracking reference values. +module references::m; + +public struct SomeStruct has drop { + struct_field: SimpleStruct, + simple_field: u64, + vec_simple_field: vector, +} + +public struct SimpleStruct has drop, copy { + field: u64, +} + +fun foo( + some_struct_ref: &mut SomeStruct, + vec_ref: &mut vector, + num_ref: &u64, +): u64 { + some_struct_ref.struct_field.field = 42; + some_struct_ref.simple_field = *num_ref; + + let e1 = vector::borrow_mut(&mut some_struct_ref.vec_simple_field, 0); + *e1 = 42; + + let e2 = vector::borrow_mut(vec_ref, 0); + *e2 = 42; + *num_ref + some_struct_ref.simple_field + vec_ref[0] +} + +fun some_struct(): SomeStruct { + SomeStruct { + struct_field: SimpleStruct { field: 0 }, + simple_field: 0, + vec_simple_field: vector::singleton(0), + } +} + +#[test] +fun test() { + let mut some_struct = some_struct(); + let mut vec = vector::singleton(0); + vector::push_back(&mut vec, 7); + let num = 42; + foo(&mut some_struct, &mut vec, &num); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/test.exp new file mode 100644 index 00000000000..e61f1b9e9de --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/test.exp @@ -0,0 +1,90 @@ +current frame stack: + function: test (m.move:44) + scope 0 : + num : 42 + type: u64 + + some_struct : (0x0::m::SomeStruct) { + struct_field : (0x0::m::SimpleStruct) { + field : 0 + } + simple_field : 0 + vec_simple_field : [ + 0 : 0 + ] + } + type: 0x0::m::SomeStruct + + vec : [ + 0 : 0 + 1 : 7 + ] + type: vector + + function: foo (m.move:19) + scope 0 : + some_struct_ref : (0x0::m::SomeStruct) { + struct_field : (0x0::m::SimpleStruct) { + field : 0 + } + simple_field : 0 + vec_simple_field : [ + 0 : 0 + ] + } + type: &mut 0x0::m::SomeStruct + + vec_ref : [ + 0 : 0 + 1 : 7 + ] + type: &mut vector + + num_ref : 42 + type: &u64 + +current frame stack: + function: test (m.move:44) + scope 0 : + num : 42 + type: u64 + + some_struct : (0x0::m::SomeStruct) { + struct_field : (0x0::m::SimpleStruct) { + field : 42 + } + simple_field : 42 + vec_simple_field : [ + 0 : 42 + ] + } + type: 0x0::m::SomeStruct + + vec : [ + 0 : 42 + 1 : 7 + ] + type: vector + + function: foo (m.move:27) + scope 0 : + some_struct_ref : (0x0::m::SomeStruct) { + struct_field : (0x0::m::SimpleStruct) { + field : 42 + } + simple_field : 42 + vec_simple_field : [ + 0 : 42 + ] + } + type: &mut 0x0::m::SomeStruct + + vec_ref : [ + 0 : 42 + 1 : 7 + ] + type: &mut vector + + num_ref : 42 + type: &u64 + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/trace.spec.js new file mode 100644 index 00000000000..6963fb9aafe --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/trace.spec.js @@ -0,0 +1,21 @@ +let action = (runtime) => { + let res = ''; + // step over functions creating data to be referenced + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + // step into a function + runtime.step(false); + res += runtime.toString(); + // advance until all references are updated + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + runtime.step(true); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/traces/references__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/traces/references__m__test.json new file mode 100644 index 00000000000..15a2d2aade3 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references/traces/references__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":2,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[{"type_":"u64","ref_type":null},{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null},{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"some_struct","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null}],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999992,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999989,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999986,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999986,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":13,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":["u64"],"parameters":[{"RuntimeValue":{"value":0}}],"return_types":[{"type_":{"vector":"u64"},"ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":999999986}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999975,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999974,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[13,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999964,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[13,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[13,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999946,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[13,0]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999945,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[13,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[13,1]},"root_value_after_write":{"RuntimeValue":{"value":[0]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999935,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[13,1]},"root_value_read":{"RuntimeValue":{"value":[0]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[0]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999934,"instruction":"RET"}},{"CloseFrame":{"frame_id":13,"return_":[{"RuntimeValue":{"value":[0]}}],"gas_left":999999934}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999930,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[0]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SimpleStruct","fields":{"field":0}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999929,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}],"gas_left":999999929}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999928,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999925,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999925,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":47,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":["u64"],"parameters":[{"RuntimeValue":{"value":0}}],"return_types":[{"type_":{"vector":"u64"},"ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":999999925}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999914,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999913,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[47,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999903,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[47,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[47,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999885,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[47,0]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999884,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[47,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[47,1]},"root_value_after_write":{"RuntimeValue":{"value":[0]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999874,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[47,1]},"root_value_read":{"RuntimeValue":{"value":[0]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[0]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999873,"instruction":"RET"}},{"CloseFrame":{"frame_id":47,"return_":[{"RuntimeValue":{"value":[0]}}],"gas_left":999999873}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999872,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[0]}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":[0]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999862,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,2]},"root_value_read":{"RuntimeValue":{"value":[0]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999859,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999858,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0]}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":[0,7]}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999855,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999854,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":42}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999844,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,1]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999834,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,2]},"root_value_read":{"RuntimeValue":{"value":[0,7]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0,7]}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999824,"instruction":"IMM_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999824,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":95,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}},{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0,7]}},{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":"Mut"},{"type_":{"vector":"u64"},"ref_type":"Mut"},{"type_":"u64","ref_type":"Imm"},{"type_":"u64","ref_type":"Mut"},{"type_":"u64","ref_type":"Mut"}],"is_native":false},"gas_left":999999824}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999820,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999810,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999800,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,1]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999790,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,1]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999772,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":0}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},0]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":0,"vec_simple_field":[0]}}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999762,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,2]},"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}},"moved":false}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999744,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999734,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":0,"vec_simple_field":[0]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999724,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,1]},1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999706,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,1]},1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":0,"vec_simple_field":[0]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,1]},1]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999696,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999686,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,1]},2]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999683,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999673,"instruction":"VEC_MUT_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,1]},2]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999672,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Effect":{"Write":{"location":{"Local":[95,3]},"root_value_after_write":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999669,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999659,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,3]},"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999641,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[0]}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Indexed":[{"Local":[0,1]},2]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999631,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,1]},"root_value_read":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0,7]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0,7]}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999628,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999618,"instruction":"VEC_MUT_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[0,7]}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[0,7]}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999617,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[0,7]}}}},{"Effect":{"Write":{"location":{"Local":[95,4]},"root_value_after_write":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[0,7]}}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999614,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999604,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,4]},"root_value_read":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[0,7]}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[0,7]}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999586,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[0,7]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,2]},0]},"root_value_after_write":{"RuntimeValue":{"value":[42,7]}}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999576,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,2]},"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}},"moved":true}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999558,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":42}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999548,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999538,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,1]},1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999520,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,1]},1]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,1]},1]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::SimpleStruct","fields":{"field":42}},"simple_field":42,"vec_simple_field":[42]}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999517,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999507,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[95,1]},"root_value_read":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[42,7]}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[42,7]}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999497,"instruction":"FREEZE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[42,7]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[42,7]}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999494,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999484,"instruction":"VEC_IMM_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[42,7]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[42,7]}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999466,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[42,7]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,2]},0]},"root_value_read":{"RuntimeValue":{"value":[42,7]}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":36,"gas_left":999999463,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Push":{"RuntimeValue":{"value":126}}}},{"Instruction":{"type_parameters":[],"pc":37,"gas_left":999999462,"instruction":"RET"}},{"CloseFrame":{"frame_id":95,"return_":[{"RuntimeValue":{"value":126}}],"gas_left":999999462}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999461,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":126}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999460,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999460}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/Move.toml new file mode 100644 index 00000000000..f6707c49815 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "references_deep" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +references_deep = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/bytecode_modules/dependencies/MoveStdlib/vector.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/bytecode_modules/dependencies/MoveStdlib/vector.mv new file mode 100644 index 0000000000000000000000000000000000000000..79c6d2eb99157a351717e0a6c0cc80cc20a46ce2 GIT binary patch literal 1123 zcmaJ=%}(4f5T3CeCmCm#-35WvB9-mZ_SQ4UQbGF|(XwkGDkM=7{vN0IK1vTg_0(%m zeTmLE5J4qs$)BD1`DQ#b`MUeZSpY~7j5f9DOmw@Bf8h^IzUe*tT~qc`|2D7%Gq8XN zKuR;Bi5N2$0jQY0!KK8=QpSlB+#s)MxVdr~z` zbwmA;UtV>|sw%r>QMNBujbC;?Z;P|iH*J1eHF@XTt|-q&Yd)LmF87ypcNYarigN95 z^Xk;HuW!1fXnVE2@a0)|p43&HpDb5j()y}B4>#NR%j(+4jlbpqK5d!$!gp0^+M8wV z1oGY_y()_?M4t?|ysnD2D($sjbydUl``<#HaLalNR8k|Zj^e^9FuWt)mUqls+KTZ9 zdZ5d2gbt3#p-QD+ZwTHWQl?4E2!%B_j(e|$?@T#u**2`53`r3#%xmH?BK%BF4a#jc z#o>!hqp2{-c))ao2QbD1+%s7e6O8bfjwn)W;PBIs9}}=~cT7tDE&b}DKm64F2TlTqN7TQ5H}paO q+lOd_!>fr<>@bCt-A2@>6eu5M#np7^6jMmpDH;GXJZ(DTDf$cNL2%3f literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..2f61b892a81f73ab4b1d647d7430c13b0a2788a7 GIT binary patch literal 504 zcmbtRu};G<5PfGmPU1MUsel0(nHU%l10w=&9Mt+39;0yQ( zE@@Sah!f@{pjc80GX1e;>Q`7s(?mey2j^WY;-((%nD7#^Z-G*{ryXA}O3F*42!$2MH zQTgiY&Nu0stG1n*QSdE`@E;=xN)jSL*02shlpFNQ4t7tL^u_Ly(NTuWeeI48dkrD2 z!3ZNNkYS85{cSiFtT|+~&)r}`6NrA3$_inT4_qDZc0BMu75o}S3R3N9MMVAQ0l#vm BLYn{p literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/dependencies/MoveStdlib/vector.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/dependencies/MoveStdlib/vector.json new file mode 100644 index 00000000000..9d5a13fdd3b --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/dependencies/MoveStdlib/vector.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":261,"end":267},"module_name":["0000000000000000000000000000000000000000000000000000000000000001","vector"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1184,"end":1236},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1202,"end":1207},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1208,"end":1215}]],"parameters":[],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1220,"end":1235}],"locals":[],"nops":{},"code_map":{},"is_native":true},"1":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1311,"end":1371},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1329,"end":1335},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1336,"end":1343}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1345,"end":1346}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1367,"end":1370}],"locals":[],"nops":{},"code_map":{},"is_native":true},"2":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1545,"end":1618},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1563,"end":1569},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1570,"end":1577}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1579,"end":1580}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1600,"end":1601}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1609,"end":1617}],"locals":[],"nops":{},"code_map":{},"is_native":true},"3":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1706,"end":1780},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1724,"end":1733},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1734,"end":1741}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1743,"end":1744}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1768,"end":1769}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"4":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1950,"end":2035},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1968,"end":1978},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1979,"end":1986}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":1988,"end":1989}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2013,"end":2014}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2022,"end":2034}],"locals":[],"nops":{},"code_map":{},"is_native":true},"5":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2152,"end":2222},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2170,"end":2178},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2179,"end":2186}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2188,"end":2189}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2214,"end":2221}],"locals":[],"nops":{},"code_map":{},"is_native":true},"6":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2324,"end":2385},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2342,"end":2355},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2356,"end":2363}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2365,"end":2366}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"7":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2543,"end":2616},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2561,"end":2565},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2566,"end":2573}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2575,"end":2576}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2600,"end":2601}],["j#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2608,"end":2609}]],"returns":[],"locals":[],"nops":{},"code_map":{},"is_native":true},"8":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2683,"end":2812},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2694,"end":2703},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2704,"end":2711}]],"parameters":[["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2713,"end":2714}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2726,"end":2741}],"locals":[["v#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2760,"end":2761}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2764,"end":2771},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2756,"end":2761},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2782},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2793,"end":2794},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2781,"end":2795},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2805,"end":2806}},"is_native":false},"9":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2889,"end":3266},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2900,"end":2907},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2908,"end":2915}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2917,"end":2918}]],"returns":[],"locals":[["back_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3057,"end":3067}],["front_index#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3024,"end":3035}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2963},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2962,"end":2972},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2956,"end":2959},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2986,"end":2989},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2993,"end":2994},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2990,"end":2992},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2982,"end":3005},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":2996,"end":3005},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3038,"end":3039},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3020,"end":3035},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3070,"end":3073},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3076,"end":3077},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3074,"end":3075},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3053,"end":3067},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3094,"end":3105},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3108,"end":3118},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3106,"end":3107},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3135},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3141,"end":3152},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3154,"end":3164},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3134,"end":3165},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3193,"end":3204},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3207,"end":3208},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3205,"end":3206},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3179,"end":3190},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3235,"end":3245},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3248,"end":3249},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3246,"end":3247},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3222,"end":3232},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3087,"end":3260}},"is_native":false},"10":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3352,"end":3564},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3363,"end":3369},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3370,"end":3377}]],"parameters":[["lhs#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3379,"end":3382}],["other#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3410,"end":3415}]],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3449},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3444,"end":3459},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3482},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3477,"end":3493},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3476,"end":3477},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3498},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3514},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3509,"end":3525},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3495,"end":3526},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3469,"end":3526},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3541},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3536,"end":3557},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3557,"end":3558}},"is_native":false},"11":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3649,"end":3736},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3660,"end":3668},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3669,"end":3676}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3678,"end":3679}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3700,"end":3704}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3716},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3725},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3729,"end":3730},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3726,"end":3728},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3715,"end":3730}},"is_native":false},"12":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3825,"end":4069},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3836,"end":3844},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3845,"end":3852}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3854,"end":3855}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3875,"end":3876}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3889,"end":3893}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3912,"end":3913}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3916,"end":3917},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3908,"end":3913},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3938},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3937,"end":3947},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3931,"end":3934},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3964,"end":3965},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3968,"end":3971},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3966,"end":3967},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3992,"end":3993},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3994,"end":3995},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3991,"end":3996},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4000,"end":4001},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3997,"end":3999},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3987,"end":4014},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4010,"end":4014},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4003,"end":4014},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4032,"end":4033},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4036,"end":4037},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4034,"end":4035},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4028,"end":4029},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":3957,"end":4048},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4058,"end":4063}},"is_native":false},"13":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4185,"end":4446},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4196,"end":4204},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4205,"end":4212}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4214,"end":4215}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4235,"end":4236}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4250,"end":4254},{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4256,"end":4259}],"locals":[["i#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4279,"end":4280}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4283,"end":4284},"1":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4275,"end":4280},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4305},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4304,"end":4314},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4298,"end":4301},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4331,"end":4332},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4335,"end":4338},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4333,"end":4334},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4359,"end":4360},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4361,"end":4362},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4358,"end":4363},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4367,"end":4368},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4364,"end":4366},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4354,"end":4386},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4378,"end":4382},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4384,"end":4385},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4370,"end":4386},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4404,"end":4405},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4408,"end":4409},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4406,"end":4407},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4400,"end":4401},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4324,"end":4420},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4431,"end":4436},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4438,"end":4439},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4430,"end":4440}},"is_native":false},"14":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4649,"end":4945},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4660,"end":4666},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4667,"end":4674}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4676,"end":4677}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4705,"end":4706}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4714,"end":4721}],"locals":[["%#1",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898}],["%#2",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891}],["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4740,"end":4743}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4747},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4746,"end":4756},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4736,"end":4743},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4804,"end":4805},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4809,"end":4812},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4806,"end":4808},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4800,"end":4840},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4820,"end":4840},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4814,"end":4840},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4857,"end":4860},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4863,"end":4864},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4861,"end":4862},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4851,"end":4854},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4881,"end":4882},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4885,"end":4888},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4883,"end":4884},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4906,"end":4907},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4910,"end":4911},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4908,"end":4909},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4902,"end":4903},"28":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4891},"29":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4897,"end":4898},"30":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4913,"end":4914},"31":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4890,"end":4917},"32":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4874,"end":4917},"33":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4928},"34":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":4927,"end":4939}},"is_native":false},"15":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5279,"end":5579},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5290,"end":5296},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5297,"end":5304}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5306,"end":5307}],["e#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5331,"end":5332}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5347,"end":5348}]],"returns":[],"locals":[["len#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5376},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5375,"end":5385},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5369,"end":5372},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5426,"end":5427},"5":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5430,"end":5433},"6":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5428,"end":5429},"7":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5422,"end":5461},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5441,"end":5461},"11":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5435,"end":5461},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5473},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5484,"end":5485},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5472,"end":5486},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5503,"end":5504},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5507,"end":5510},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5505,"end":5506},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5527},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5533,"end":5534},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5536,"end":5539},"22":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5526,"end":5540},"23":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5558,"end":5559},"24":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5562,"end":5563},"25":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5560,"end":5561},"26":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5554,"end":5555},"27":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5496,"end":5573}},"is_native":false},"16":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5801,"end":6025},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5812,"end":5823},"type_parameters":[["Element",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5824,"end":5831}]],"parameters":[["v#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5833,"end":5834}],["i#0#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5858,"end":5859}]],"returns":[{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5867,"end":5874}],"locals":[["last_idx#1#0",{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951}]],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5895},"2":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5894,"end":5906},"3":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5893,"end":5894},"4":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"8":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5908,"end":5928},"9":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5885,"end":5929},"10":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5955},"12":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5954,"end":5964},"13":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5967,"end":5968},"14":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5965,"end":5966},"15":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5943,"end":5951},"16":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5979},"17":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5985,"end":5986},"18":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5988,"end":5996},"19":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":5978,"end":5997},"20":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6008},"21":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":6007,"end":6019}},"is_native":false},"17":{"location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"definition_location":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[42,57,43,60,190,49,164,194,57,126,218,170,200,152,239,244,35,144,147,120,5,88,201,108,231,168,248,67,118,176,80,79],"start":249,"end":13981}},"is_native":false}},"constant_map":{"EINDEX_OUT_OF_BOUNDS":0}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/m.json new file mode 100644 index 00000000000..bac91627986 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":107,"end":108},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{"0":{"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":125,"end":135},"type_parameters":[],"fields":[{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":151,"end":163}]},"1":{"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":193,"end":202},"type_parameters":[],"fields":[{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":224,"end":233}]}},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":251,"end":366},"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":255,"end":258},"type_parameters":[],"parameters":[["vec_ref#0#0",{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":259,"end":266}]],"returns":[{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":287,"end":290}],"locals":[["e#1#0",{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":301,"end":302}]],"nops":{},"code_map":{"0":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":324,"end":331},"1":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":333,"end":334},"2":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":305,"end":335},"3":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":301,"end":302},"4":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":346,"end":348},"5":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":342,"end":343},"6":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":341,"end":348},"7":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":354,"end":361},"9":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":362,"end":363},"10":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":354,"end":364}},"is_native":false},"1":{"location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":368,"end":534},"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":372,"end":375},"type_parameters":[],"parameters":[["some_struct_ref#0#0",{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":376,"end":391}]],"returns":[{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":411,"end":414}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":440,"end":455},"1":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":440,"end":478},"2":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":435,"end":478},"3":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":431,"end":479},"4":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":491,"end":506},"5":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":491,"end":532},"7":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":530,"end":531},"8":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":491,"end":532},"10":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":489,"end":490},"11":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":485,"end":532}},"is_native":false},"2":{"location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":536,"end":660},"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":540,"end":551},"type_parameters":[],"parameters":[],"returns":[{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":555,"end":565}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":648,"end":649},"1":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":630,"end":650},"2":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":607,"end":652},"3":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":572,"end":658}},"is_native":false},"3":{"location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":670,"end":805},"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":674,"end":678},"type_parameters":[],"parameters":[],"returns":[],"locals":[["some_struct#1#0",{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":695,"end":706}]],"nops":{},"code_map":{"0":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":709,"end":722},"1":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":691,"end":706},"2":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":728,"end":762},"5":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":773,"end":774},"6":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":728,"end":775},"7":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":785,"end":801},"8":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":781,"end":802},"10":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":802,"end":803}},"is_native":false},"4":{"location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":83,"end":805},"definition_location":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":83,"end":805},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[191,124,226,117,80,25,18,135,252,240,29,246,133,93,154,101,125,56,138,28,145,209,204,76,225,26,126,10,201,143,108,136],"start":83,"end":805}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/dependencies/MoveStdlib/vector.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/dependencies/MoveStdlib/vector.move new file mode 100644 index 00000000000..824d0aa1210 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/dependencies/MoveStdlib/vector.move @@ -0,0 +1,365 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#[defines_primitive(vector)] +/// A variable-sized container that can hold any type. Indexing is 0-based, and +/// vectors are growable. This module has many native functions. +module std::vector { + /// Allows calling `.to_string()` on a vector of `u8` to get a utf8 `String`. + public use fun std::string::utf8 as vector.to_string; + + /// Allows calling `.try_to_string()` on a vector of `u8` to get a utf8 `String`. + /// This will return `None` if the vector is not valid utf8. + public use fun std::string::try_utf8 as vector.try_to_string; + + /// Allows calling `.to_ascii_string()` on a vector of `u8` to get an `ascii::String`. + public use fun std::ascii::string as vector.to_ascii_string; + + /// Allows calling `.try_to_ascii_string()` on a vector of `u8` to get an + /// `ascii::String`. This will return `None` if the vector is not valid ascii. + public use fun std::ascii::try_string as vector.try_to_ascii_string; + + /// The index into the vector is out of bounds + const EINDEX_OUT_OF_BOUNDS: u64 = 0x20000; + + #[bytecode_instruction] + /// Create an empty vector. + public native fun empty(): vector; + + #[bytecode_instruction] + /// Return the length of the vector. + public native fun length(v: &vector): u64; + + #[syntax(index)] + #[bytecode_instruction] + /// Acquire an immutable reference to the `i`th element of the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow(v: &vector, i: u64): ∈ + + #[bytecode_instruction] + /// Add element `e` to the end of the vector `v`. + public native fun push_back(v: &mut vector, e: Element); + + #[syntax(index)] + #[bytecode_instruction] + /// Return a mutable reference to the `i`th element in the vector `v`. + /// Aborts if `i` is out of bounds. + public native fun borrow_mut(v: &mut vector, i: u64): &mut Element; + + #[bytecode_instruction] + /// Pop an element from the end of vector `v`. + /// Aborts if `v` is empty. + public native fun pop_back(v: &mut vector): Element; + + #[bytecode_instruction] + /// Destroy the vector `v`. + /// Aborts if `v` is not empty. + public native fun destroy_empty(v: vector); + + #[bytecode_instruction] + /// Swaps the elements at the `i`th and `j`th indices in the vector `v`. + /// Aborts if `i` or `j` is out of bounds. + public native fun swap(v: &mut vector, i: u64, j: u64); + + /// Return an vector of size one containing element `e`. + public fun singleton(e: Element): vector { + let mut v = empty(); + v.push_back(e); + v + } + + /// Reverses the order of the elements in the vector `v` in place. + public fun reverse(v: &mut vector) { + let len = v.length(); + if (len == 0) return (); + + let mut front_index = 0; + let mut back_index = len - 1; + while (front_index < back_index) { + v.swap(front_index, back_index); + front_index = front_index + 1; + back_index = back_index - 1; + } + } + + /// Pushes all of the elements of the `other` vector into the `lhs` vector. + public fun append(lhs: &mut vector, mut other: vector) { + other.reverse(); + while (!other.is_empty()) lhs.push_back(other.pop_back()); + other.destroy_empty(); + } + + /// Return `true` if the vector `v` has no elements and `false` otherwise. + public fun is_empty(v: &vector): bool { + v.length() == 0 + } + + /// Return true if `e` is in the vector `v`. + /// Otherwise, returns false. + public fun contains(v: &vector, e: &Element): bool { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return true; + i = i + 1; + }; + false + } + + /// Return `(true, i)` if `e` is in the vector `v` at index `i`. + /// Otherwise, returns `(false, 0)`. + public fun index_of(v: &vector, e: &Element): (bool, u64) { + let mut i = 0; + let len = v.length(); + while (i < len) { + if (&v[i] == e) return (true, i); + i = i + 1; + }; + (false, 0) + } + + /// Remove the `i`th element of the vector `v`, shifting all subsequent elements. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun remove(v: &mut vector, mut i: u64): Element { + let mut len = v.length(); + // i out of bounds; abort + if (i >= len) abort EINDEX_OUT_OF_BOUNDS; + + len = len - 1; + while (i < len) v.swap(i, { i = i + 1; i }); + v.pop_back() + } + + /// Insert `e` at position `i` in the vector `v`. + /// If `i` is in bounds, this shifts the old `v[i]` and all subsequent elements to the right. + /// If `i == v.length()`, this adds `e` to the end of the vector. + /// This is O(n) and preserves ordering of elements in the vector. + /// Aborts if `i > v.length()` + public fun insert(v: &mut vector, e: Element, mut i: u64) { + let len = v.length(); + // i too big abort + if (i > len) abort EINDEX_OUT_OF_BOUNDS; + + v.push_back(e); + while (i < len) { + v.swap(i, len); + i = i + 1 + } + } + + /// Swap the `i`th element of the vector `v` with the last element and then pop the vector. + /// This is O(1), but does not preserve ordering of elements in the vector. + /// Aborts if `i` is out of bounds. + public fun swap_remove(v: &mut vector, i: u64): Element { + assert!(!v.is_empty(), EINDEX_OUT_OF_BOUNDS); + let last_idx = v.length() - 1; + v.swap(i, last_idx); + v.pop_back() + } + + // === Macros === + + /// Create a vector of length `n` by calling the function `f` on each index. + public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> { + let mut v = vector[]; + let n = $n; + n.do!(|i| v.push_back($f(i))); + v + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Does not preserve the order of elements in the vector (starts from the end of the vector). + public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Destroy the vector `v` by calling `f` on each element and then destroying the vector. + /// Preserves the order of elements in the vector. + public macro fun do<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + while (!v.is_empty()) $f(v.pop_back()); + v.destroy_empty(); + } + + /// Perform an action `f` on each element of the vector `v`. The vector is not modified. + public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) { + let v = $v; + v.length().do!(|i| $f(&v[i])) + } + + /// Perform an action `f` on each element of the vector `v`. + /// The function `f` takes a mutable reference to the element. + public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) { + let v = $v; + v.length().do!(|i| $f(&mut v[i])) + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map<$T, $U>($v: vector<$T>, $f: |$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do!(|e| r.push_back($f(e))); + r + } + + /// Map the vector `v` to a new vector by applying the function `f` to each element. + /// Preserves the order of elements in the vector, first is called first. + public macro fun map_ref<$T, $U>($v: &vector<$T>, $f: |&$T| -> $U): vector<$U> { + let v = $v; + let mut r = vector[]; + v.do_ref!(|e| r.push_back($f(e))); + r + } + + /// Filter the vector `v` by applying the function `f` to each element. + /// Return a new vector containing only the elements for which `f` returns `true`. + public macro fun filter<$T: drop>($v: vector<$T>, $f: |&$T| -> bool): vector<$T> { + let v = $v; + let mut r = vector[]; + v.do!(|e| if ($f(&e)) r.push_back(e)); + r + } + + /// Split the vector `v` into two vectors by applying the function `f` to each element. + /// Return a tuple containing two vectors: the first containing the elements for which `f` returns `true`, + /// and the second containing the elements for which `f` returns `false`. + public macro fun partition<$T>($v: vector<$T>, $f: |&$T| -> bool): (vector<$T>, vector<$T>) { + let v = $v; + let mut r1 = vector[]; + let mut r2 = vector[]; + v.do!(|e| if ($f(&e)) r1.push_back(e) else r2.push_back(e)); + (r1, r2) + } + + /// Finds the index of first element in the vector `v` that satisfies the predicate `f`. + /// Returns `some(index)` if such an element is found, otherwise `none()`. + public macro fun find_index<$T>($v: &vector<$T>, $f: |&$T| -> bool): Option { + let v = $v; + 'find_index: { + v.length().do!(|i| if ($f(&v[i])) return 'find_index option::some(i)); + option::none() + } + } + + /// Count how many elements in the vector `v` satisfy the predicate `f`. + public macro fun count<$T>($v: &vector<$T>, $f: |&$T| -> bool): u64 { + let v = $v; + let mut count = 0; + v.do_ref!(|e| if ($f(e)) count = count + 1); + count + } + + /// Reduce the vector `v` to a single value by applying the function `f` to each element. + /// Similar to `fold_left` in Rust and `reduce` in Python and JavaScript. + public macro fun fold<$T, $Acc>($v: vector<$T>, $init: $Acc, $f: |$Acc, $T| -> $Acc): $Acc { + let v = $v; + let mut acc = $init; + v.do!(|e| acc = $f(acc, e)); + acc + } + + /// Whether any element in the vector `v` satisfies the predicate `f`. + /// If the vector is empty, returns `false`. + public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'any: { + v.do_ref!(|e| if ($f(e)) return 'any true); + false + } + } + + /// Whether all elements in the vector `v` satisfy the predicate `f`. + /// If the vector is empty, returns `true`. + public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool { + let v = $v; + 'all: { + v.do_ref!(|e| if (!$f(e)) return 'all false); + true + } + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + v2.reverse(); + let len = v1.length(); + assert!(len == v2.length()); + v1.do!(|el1| $f(el1, v2.pop_back())); + } + + /// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements. + /// Aborts if the vectors are not of the same length. + /// Starts from the end of the vectors. + public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) { + let v1 = $v1; + let mut v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + v1.destroy!(|el1| $f(el1, v2.pop_back())); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The vectors are not modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&v1[i], &v2[i])); + } + + /// Iterate through `v1` and `v2` and apply the function `f` to mutable references of each pair + /// of elements. The vectors may be modified. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_do_mut<$T1, $T2>( + $v1: &mut vector<$T1>, + $v2: &mut vector<$T2>, + $f: |&mut $T1, &mut $T2|, + ) { + let v1 = $v1; + let v2 = $v2; + let len = v1.length(); + assert!(len == v2.length()); + len.do!(|i| $f(&mut v1[i], &mut v2[i])); + } + + /// Destroys two vectors `v1` and `v2` by applying the function `f` to each pair of elements. + /// The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map<$T1, $T2, $U>( + $v1: vector<$T1>, + $v2: vector<$T2>, + $f: |$T1, $T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } + + /// Iterate through `v1` and `v2` and apply the function `f` to references of each pair of + /// elements. The returned values are collected into a new vector. + /// Aborts if the vectors are not of the same length. + /// The order of elements in the vectors is preserved. + public macro fun zip_map_ref<$T1, $T2, $U>( + $v1: &vector<$T1>, + $v2: &vector<$T2>, + $f: |&$T1, &$T2| -> $U, + ): vector<$U> { + let mut r = vector[]; + zip_do_ref!($v1, $v2, |el1, el2| r.push_back($f(el1, el2))); + r + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/m.move new file mode 100644 index 00000000000..f8e266674ec --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/build/references_deep/sources/m.move @@ -0,0 +1,34 @@ +// Test tracking reference values when multiple levels of references are involved. +module references_deep::m; + +public struct SomeStruct has drop { + struct_field: VecStruct, +} + +public struct VecStruct has drop, copy { + vec_field: vector, +} + +fun bar(vec_ref: &mut vector): u64 { + let e = vector::borrow_mut(vec_ref, 0); + *e = 42; + vec_ref[0] +} + +fun foo(some_struct_ref: &mut SomeStruct): u64 { + let res = bar(&mut some_struct_ref.struct_field.vec_field); + res + some_struct_ref.struct_field.vec_field[0] +} + +fun some_struct(): SomeStruct { + SomeStruct { + struct_field: VecStruct { vec_field: vector::singleton(0) } + } +} + +#[test] +fun test() { + let mut some_struct = some_struct(); + some_struct.struct_field.vec_field.push_back(7); + foo(&mut some_struct); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/sources/m.move new file mode 100644 index 00000000000..f8e266674ec --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/sources/m.move @@ -0,0 +1,34 @@ +// Test tracking reference values when multiple levels of references are involved. +module references_deep::m; + +public struct SomeStruct has drop { + struct_field: VecStruct, +} + +public struct VecStruct has drop, copy { + vec_field: vector, +} + +fun bar(vec_ref: &mut vector): u64 { + let e = vector::borrow_mut(vec_ref, 0); + *e = 42; + vec_ref[0] +} + +fun foo(some_struct_ref: &mut SomeStruct): u64 { + let res = bar(&mut some_struct_ref.struct_field.vec_field); + res + some_struct_ref.struct_field.vec_field[0] +} + +fun some_struct(): SomeStruct { + SomeStruct { + struct_field: VecStruct { vec_field: vector::singleton(0) } + } +} + +#[test] +fun test() { + let mut some_struct = some_struct(); + some_struct.struct_field.vec_field.push_back(7); + foo(&mut some_struct); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/test.exp new file mode 100644 index 00000000000..b3d38a0af80 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/test.exp @@ -0,0 +1,74 @@ +current frame stack: + function: test (m.move:33) + scope 0 : + some_struct : (0x0::m::SomeStruct) { + struct_field : (0x0::m::VecStruct) { + vec_field : [ + 0 : 0 + 1 : 7 + ] + } + } + type: 0x0::m::SomeStruct + + function: foo (m.move:19) + scope 0 : + some_struct_ref : (0x0::m::SomeStruct) { + struct_field : (0x0::m::VecStruct) { + vec_field : [ + 0 : 0 + 1 : 7 + ] + } + } + type: &mut 0x0::m::SomeStruct + + function: bar (m.move:13) + scope 0 : + vec_ref : (0x0::m::SomeStruct) { + struct_field : (0x0::m::VecStruct) { + vec_field : [ + 0 : 0 + 1 : 7 + ] + } + } + type: &mut vector + +current frame stack: + function: test (m.move:33) + scope 0 : + some_struct : (0x0::m::SomeStruct) { + struct_field : (0x0::m::VecStruct) { + vec_field : [ + 0 : 42 + 1 : 7 + ] + } + } + type: 0x0::m::SomeStruct + + function: foo (m.move:19) + scope 0 : + some_struct_ref : (0x0::m::SomeStruct) { + struct_field : (0x0::m::VecStruct) { + vec_field : [ + 0 : 42 + 1 : 7 + ] + } + } + type: &mut 0x0::m::SomeStruct + + function: bar (m.move:15) + scope 0 : + vec_ref : (0x0::m::SomeStruct) { + struct_field : (0x0::m::VecStruct) { + vec_field : [ + 0 : 42 + 1 : 7 + ] + } + } + type: &mut vector + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/trace.spec.js new file mode 100644 index 00000000000..88ef8e7c14f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/trace.spec.js @@ -0,0 +1,17 @@ +let action = (runtime) => { + let res = ''; + // step over functions creating data to be referenced + runtime.step(true); + runtime.step(true); + // step into a function taking a reference as an argument + runtime.step(false); + // step into another function taking a reference as an argument + runtime.step(false); + res += runtime.toString(); + // advance until all references are updated + runtime.step(true); + runtime.step(true); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/traces/references_deep__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/traces/references_deep__m__test.json new file mode 100644 index 00000000000..78359c58a39 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/references_deep/traces/references_deep__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":3,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":1000000000,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":2,"function_name":"some_struct","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":2,"type_instantiation":[],"parameters":[],"return_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":null}],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999996,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999996,"instruction":"CALL_GENERIC"}},{"OpenFrame":{"frame":{"frame_id":6,"function_name":"singleton","module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"vector"},"binary_member_index":8,"type_instantiation":["u64"],"parameters":[{"RuntimeValue":{"value":0}}],"return_types":[{"type_":{"vector":"u64"},"ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":{"vector":"u64"},"ref_type":null}],"is_native":false},"gas_left":999999996}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999985,"instruction":"VEC_PACK"}},{"Effect":{"Push":{"RuntimeValue":{"value":[]}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999984,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[]}}}},{"Effect":{"Write":{"location":{"Local":[6,1]},"root_value_after_write":{"RuntimeValue":{"value":[]}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999974,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[6,1]},"root_value_read":{"RuntimeValue":{"value":[]}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[6,1]},"snapshot":[]}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999956,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[6,0]},"root_value_read":{"RuntimeValue":{"value":0}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999955,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[6,1]},"snapshot":[]}}}},{"Effect":{"Write":{"location":{"Local":[6,1]},"root_value_after_write":{"RuntimeValue":{"value":[0]}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999945,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[6,1]},"root_value_read":{"RuntimeValue":{"value":[0]}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":[0]}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999944,"instruction":"RET"}},{"CloseFrame":{"frame_id":6,"return_":[{"RuntimeValue":{"value":[0]}}],"gas_left":999999944}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999940,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":[0]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999936,"instruction":"PACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999935,"instruction":"RET"}},{"CloseFrame":{"frame_id":2,"return_":[{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}],"gas_left":999999935}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999934,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999924,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999914,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999904,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999901,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999900,"instruction":"VEC_PUSH_BACK"}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0]}}}}}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999890,"instruction":"MUT_BORROW_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999890,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":57,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000000","module":"m","name":"SomeStruct","type_args":[]}},"ref_type":"Mut"}],"is_native":false},"gas_left":999999890}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999879,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[57,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999869,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999859,"instruction":"MUT_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999859,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":68,"function_name":"bar","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":{"vector":"u64"},"ref_type":"Mut"},{"type_":"u64","ref_type":"Mut"}],"is_native":false},"gas_left":999999859}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999848,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,0]},"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}},"moved":false}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999845,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999835,"instruction":"VEC_MUT_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999834,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Effect":{"Write":{"location":{"Local":[68,1]},"root_value_after_write":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999831,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999821,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,1]},"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999803,"instruction":"WRITE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[0,7]}}}}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999793,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[68,0]},"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999783,"instruction":"FREEZE_REF"}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999780,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999770,"instruction":"VEC_IMM_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999752,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999751,"instruction":"RET"}},{"CloseFrame":{"frame_id":68,"return_":[{"RuntimeValue":{"value":42}}],"gas_left":999999751}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999741,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[57,0]},"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}},"moved":true}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999731,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999721,"instruction":"IMM_BORROW_FIELD"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999718,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999708,"instruction":"VEC_IMM_BORROW"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999690,"instruction":"READ_REF"}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"snapshot":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},0]},0]},0]},"root_value_read":{"RuntimeValue":{"value":{"type":"0x0::m::SomeStruct","fields":{"struct_field":{"type":"0x0::m::VecStruct","fields":{"vec_field":[42,7]}}}}}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999687,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999686,"instruction":"RET"}},{"CloseFrame":{"frame_id":57,"return_":[{"RuntimeValue":{"value":84}}],"gas_left":999999686}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999685,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999684,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999684}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/run_spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/run_spec.js new file mode 100644 index 00000000000..978445b7568 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/run_spec.js @@ -0,0 +1,52 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +const assert = require('assert'); +const linediff = require('line-diff'); +const fs = require('fs'); +const path = require('path'); +const runtime = require('../out/runtime'); + +const UB = process.env['UB']; + +/** + * Testing harness, assuming that the tested function + * is the `test` function in the `m` module. It executes + * a given callback function and compares its result with + * the expected one stored in a file. + * + * @param dirname the directory where the test (its manifest file) is located + * @param action a function to be executed by the harness that + * takes DAP runtime as argument and returns a string representing + * test result + */ +global.run_spec = function (dirname, action) { + const test_dir = path.basename(dirname); + describe(test_dir, () => { + it(test_dir, () => { + const rt = new runtime.Runtime(); + // assume that the test is always in the `test` function + // of the `m` module + const traceInfo = test_dir + '::' + 'm::test'; + return rt.start(path.join(dirname, 'sources', `m.move`), traceInfo, true).then(() => { + const result = action(rt); + const exp_file = 'test.exp'; + const exp_path = path.join(dirname, exp_file); + if (UB === '1') { + // user asked to regenerate output + fs.writeFileSync(exp_path, result, 'utf8'); + return; + } + if (!fs.existsSync(exp_path)) { + assert.fail(`\n${result}\nNo expected output file`); + } + const exp_out = fs.readFileSync(exp_path, { encoding: 'utf8' }); + if (result !== exp_out) { + const out_diff = new linediff(exp_out, result).toString(); + assert.fail(`${out_diff}\nCurrent output does not match the expected one (run with UB=1 to save the current output)`); + } + }); + }); + }); +}; diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/Move.toml new file mode 100644 index 00000000000..2eb5111ce9d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "shadowing" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +shadowing = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/build/shadowing/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/build/shadowing/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..67ca2edde8a592a63123c84ac4e288ad8bb4a638 GIT binary patch literal 352 zcmbtQ+ls<45S?36Hwmb)6j^)_6a>FQzodv%w-4JaZT%VFeDmM@2`5sD;G;7zIp;8$ zImvZ?_Z9#wg0Os>**IJ8M!(x|!wUkT0BQmg0T?aH1O%BG8MHFG@N;O&eODH3b*jsz zEsn7%y0Y!6`ozZ=@lO)_I@eYA)F%Tf{$tg~TK9hv>Q5c6(leeB#Dgq6I?jV}#%_9j uDRWQG { + let res = ''; + // step into a function + runtime.step(false); + // advance until first shadowed variable is created + runtime.step(true); + runtime.step(true); + runtime.step(true); + res += runtime.toString(); + // advance until second shadowed variable is created + runtime.step(true); + runtime.step(true); + res += runtime.toString(); + // advance until second shadowed variable disappears + runtime.step(true); + runtime.step(true); + runtime.step(true); + res += runtime.toString(); + // advance until first shadowed variable disappears + runtime.step(true); + res += runtime.toString(); + + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/traces/shadowing__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/traces/shadowing__m__test.json new file mode 100644 index 00000000000..e7b4dad7670 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/shadowing/traces/shadowing__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_TRUE"}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999994,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999991,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999988,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999988,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":10,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":7}},{"RuntimeValue":{"value":7}},{"RuntimeValue":{"value":7}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"bool","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999988}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999984,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999983,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[10,4]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999965,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,0]},"root_value_read":{"RuntimeValue":{"value":true}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999964,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999946,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,1]},"root_value_read":{"RuntimeValue":{"value":7}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999928,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,3]},"root_value_read":{"RuntimeValue":{"value":7}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999925,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999924,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Write":{"location":{"Local":[10,5]},"root_value_after_write":{"RuntimeValue":{"value":14}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999906,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,5]},"root_value_read":{"RuntimeValue":{"value":14}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999903,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999900,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999899,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999881,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,2]},"root_value_read":{"RuntimeValue":{"value":7}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999863,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,5]},"root_value_read":{"RuntimeValue":{"value":14}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999860,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Push":{"RuntimeValue":{"value":21}}}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999859,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":21}}}},{"Effect":{"Write":{"location":{"Local":[10,6]},"root_value_after_write":{"RuntimeValue":{"value":21}}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999841,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,6]},"root_value_read":{"RuntimeValue":{"value":21}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":21}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999838,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999835,"instruction":"LT"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":21}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999834,"instruction":"BR_FALSE"}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999831,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999813,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,6]},"root_value_read":{"RuntimeValue":{"value":21}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":21}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999810,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":21}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":63}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999809,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":63}}}},{"Effect":{"Write":{"location":{"Local":[10,4]},"root_value_after_write":{"RuntimeValue":{"value":63}}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999791,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,4]},"root_value_read":{"RuntimeValue":{"value":63}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":63}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999773,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,6]},"root_value_read":{"RuntimeValue":{"value":21}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":21}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999770,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":21}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":63}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999769,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Write":{"location":{"Local":[10,4]},"root_value_after_write":{"RuntimeValue":{"value":84}}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999751,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,4]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":29,"gas_left":999999733,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,5]},"root_value_read":{"RuntimeValue":{"value":14}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":14}}}},{"Instruction":{"type_parameters":[],"pc":30,"gas_left":999999730,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":14}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Push":{"RuntimeValue":{"value":98}}}},{"Instruction":{"type_parameters":[],"pc":31,"gas_left":999999729,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":98}}}},{"Effect":{"Write":{"location":{"Local":[10,4]},"root_value_after_write":{"RuntimeValue":{"value":98}}}}},{"Instruction":{"type_parameters":[],"pc":32,"gas_left":999999711,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,4]},"root_value_read":{"RuntimeValue":{"value":98}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":98}}}},{"Instruction":{"type_parameters":[],"pc":33,"gas_left":999999693,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[10,3]},"root_value_read":{"RuntimeValue":{"value":7}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":7}}}},{"Instruction":{"type_parameters":[],"pc":34,"gas_left":999999690,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":7}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":98}}}},{"Effect":{"Push":{"RuntimeValue":{"value":105}}}},{"Instruction":{"type_parameters":[],"pc":35,"gas_left":999999689,"instruction":"RET"}},{"CloseFrame":{"frame_id":10,"return_":[{"RuntimeValue":{"value":105}}],"gas_left":999999689}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999688,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":105}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999687,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999687}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/Move.toml new file mode 100644 index 00000000000..7eccf6f05af --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "stepping" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +stepping = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..dcd6f02ab7588c8302b8d402f12d1d5bf2c77a92 GIT binary patch literal 256 zcmbtPK?=e!5S&fYsBIAoQbfcD_zDI85k%6GLla5jd&Kwo36miGfOFW{*@0o_efTsI zfFuYmw$)B9j+do6w=cSakpLwVoDx-OBw`>As@whD>s!<+n9*t<)Zn~|Iz(efJ~&5{ y$ZGYpCYJkV-qgdH;A{^51LZLiH5&A+h_yWZ@;bE0Mu&c0h?P1bw=L*6F?<1T*B+w) literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/source_maps/m.json new file mode 100644 index 00000000000..d082d5615bc --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":136,"end":137},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":140,"end":174},"definition_location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":144,"end":147},"type_parameters":[],"parameters":[["p#0#0",{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":148,"end":149}]],"returns":[{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":157,"end":160}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":167,"end":168},"1":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":171,"end":172},"2":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":169,"end":170},"3":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":167,"end":172}},"is_native":false},"1":{"location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":184,"end":343},"definition_location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":188,"end":192},"type_parameters":[],"parameters":[],"returns":[],"locals":[["_res#1#0",{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":209,"end":213}]],"nops":{},"code_map":{"0":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":220,"end":222},"1":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":216,"end":223},"2":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":205,"end":213},"3":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":236,"end":240},"4":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":247,"end":251},"5":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":243,"end":252},"6":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":241,"end":242},"7":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":229,"end":233},"8":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":265,"end":269},"9":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":276,"end":280},"10":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":272,"end":281},"11":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":270,"end":271},"12":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":258,"end":262},"13":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":281,"end":282}},"is_native":false},"2":{"location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":119,"end":343},"definition_location":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":119,"end":343},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[167,251,62,162,22,201,105,5,139,246,239,203,25,24,39,142,137,164,92,138,52,96,179,60,228,96,111,121,32,208,84,152],"start":119,"end":343}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/sources/m.move new file mode 100644 index 00000000000..55709169e56 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/build/stepping/sources/m.move @@ -0,0 +1,16 @@ +// Test simple stepping functionality: +// - step into a function +// - step out of a function +// - step over a function +module stepping::m; + +fun foo(p: u64): u64 { + p + p +} + +#[test] +fun test() { + let mut _res = foo(42); + _res = _res + foo(_res); + _res = _res + foo(_res); // to force another unoptimized read to keep `res` visible +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/sources/m.move new file mode 100644 index 00000000000..55709169e56 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/sources/m.move @@ -0,0 +1,16 @@ +// Test simple stepping functionality: +// - step into a function +// - step out of a function +// - step over a function +module stepping::m; + +fun foo(p: u64): u64 { + p + p +} + +#[test] +fun test() { + let mut _res = foo(42); + _res = _res + foo(_res); + _res = _res + foo(_res); // to force another unoptimized read to keep `res` visible +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/test.exp new file mode 100644 index 00000000000..d5ecf16565a --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/test.exp @@ -0,0 +1,20 @@ +current frame stack: + function: test (m.move:13) + scope 0 : + function: foo (m.move:8) + scope 0 : + p : 42 + type: u64 + +current frame stack: + function: test (m.move:14) + scope 0 : + _res : 84 + type: u64 + +current frame stack: + function: test (m.move:15) + scope 0 : + _res : 252 + type: u64 + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/trace.spec.js new file mode 100644 index 00000000000..f5296cd0198 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/trace.spec.js @@ -0,0 +1,14 @@ +let action = (runtime) => { + let res = ''; + // step into a function + runtime.step(false); + res += runtime.toString(); + // step out of a function + runtime.stepOut(false); + res += runtime.toString(); + // step over a function + runtime.step(true); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/traces/stepping__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/traces/stepping__m__test.json new file mode 100644 index 00000000000..028dbd2996d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping/traces/stepping__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999997,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999997}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999978,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999960,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999957,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999956,"instruction":"RET"}},{"CloseFrame":{"frame_id":4,"return_":[{"RuntimeValue":{"value":84}}],"gas_left":999999956}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999955,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":84}}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999937,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999919,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999919,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":27,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":84}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999919}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999900,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[27,0]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999882,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[27,0]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999879,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Push":{"RuntimeValue":{"value":168}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999878,"instruction":"RET"}},{"CloseFrame":{"frame_id":27,"return_":[{"RuntimeValue":{"value":168}}],"gas_left":999999878}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999875,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":168}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Push":{"RuntimeValue":{"value":252}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999874,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":252}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":252}}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999856,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":252}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":252}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999838,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[0,0]},"root_value_read":{"RuntimeValue":{"value":252}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":252}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999838,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":54,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":252}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999838}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999819,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[54,0]},"root_value_read":{"RuntimeValue":{"value":252}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":252}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999801,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[54,0]},"root_value_read":{"RuntimeValue":{"value":252}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":252}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999798,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":252}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":252}}}},{"Effect":{"Push":{"RuntimeValue":{"value":504}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999797,"instruction":"RET"}},{"CloseFrame":{"frame_id":54,"return_":[{"RuntimeValue":{"value":504}}],"gas_left":999999797}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999794,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":504}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":252}}}},{"Effect":{"Push":{"RuntimeValue":{"value":756}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999793,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":756}}}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999792,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999792}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/Move.toml b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/Move.toml new file mode 100644 index 00000000000..e79c6841d91 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "stepping_call" +edition = "2024.beta" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +stepping_call = "0x0" +std = "0x1" diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/bytecode_modules/m.mv b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/bytecode_modules/m.mv new file mode 100644 index 0000000000000000000000000000000000000000..d86d93f23837895b36dac9554296cb3ff0675788 GIT binary patch literal 321 zcmbV|I}(C05J2}6KobgSC>*u0bUcKur(n&)PwBD`Z_dqXew{J zz8QSgx}ge<54P{Pbq;STcFVE1Ve+dVRd;8->*ve4H_y9mlU6iDm~1T6ojNuMKv2J68VG=F6JWd literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/source_maps/m.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/source_maps/m.json new file mode 100644 index 00000000000..204e67d1a06 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/source_maps/m.json @@ -0,0 +1 @@ +{"definition_location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":334,"end":335},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":338,"end":368},"definition_location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":342,"end":345},"type_parameters":[],"parameters":[["p#0#0",{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":346,"end":347}]],"returns":[{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":355,"end":358}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":365,"end":366}},"is_native":false},"1":{"location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":370,"end":400},"definition_location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":374,"end":377},"type_parameters":[],"parameters":[["p#0#0",{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":378,"end":379}]],"returns":[{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":387,"end":390}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":397,"end":398}},"is_native":false},"2":{"location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":402,"end":540},"definition_location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":406,"end":409},"type_parameters":[],"parameters":[["p#0#0",{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":410,"end":411}]],"returns":[{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":419,"end":422}],"locals":[["v1#1#0",{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":433,"end":435}],["v2#1#0",{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":470,"end":472}],["v3#1#0",{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":500,"end":502}]],"nops":{},"code_map":{"0":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":438,"end":439},"1":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":442,"end":443},"2":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":440,"end":441},"3":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":450,"end":451},"4":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":446,"end":452},"5":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":444,"end":445},"6":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":455,"end":456},"7":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":453,"end":454},"8":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":459,"end":460},"9":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":457,"end":458},"10":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":433,"end":435},"11":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":479,"end":480},"12":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":475,"end":481},"13":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":488,"end":489},"14":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":484,"end":490},"15":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":482,"end":483},"16":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":470,"end":472},"17":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":509,"end":510},"18":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":505,"end":511},"19":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":518,"end":519},"20":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":514,"end":520},"21":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":512,"end":513},"22":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":500,"end":502},"23":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":526,"end":528},"24":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":531,"end":533},"25":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":529,"end":530},"26":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":536,"end":538},"27":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":534,"end":535},"28":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":526,"end":538}},"is_native":false},"3":{"location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":550,"end":577},"definition_location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":554,"end":558},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":571,"end":573},"1":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":567,"end":574},"3":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":574,"end":575}},"is_native":false},"4":{"location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":312,"end":577},"definition_location":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":312,"end":577},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[155,146,46,135,32,157,133,216,70,224,37,199,86,224,28,188,137,176,105,255,56,8,75,65,33,14,81,44,202,92,140,44],"start":312,"end":577}},"is_native":false}},"constant_map":{}} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/sources/m.move new file mode 100644 index 00000000000..d1e63ee566f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/build/stepping_call/sources/m.move @@ -0,0 +1,26 @@ +// Test stepping functionality in presence of function calls: +// - with other instructions on the same line a call, step over line in one go +// - with two calls on the same line, step over both in one go +// - with two calls on the same line, step into the first and +// after stepping out, step over the second +module stepping_call::m; + +fun baz(p: u64): u64 { + p +} + +fun bar(p: u64): u64 { + p +} + +fun foo(p: u64): u64 { + let v1 = p + p + bar(p) + p + p; + let v2 = baz(p) + bar(p); + let v3 = baz(p) + bar(p); + v1 + v2 + v3 +} + +#[test] +fun test() { + foo(42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/sources/m.move b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/sources/m.move new file mode 100644 index 00000000000..d1e63ee566f --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/sources/m.move @@ -0,0 +1,26 @@ +// Test stepping functionality in presence of function calls: +// - with other instructions on the same line a call, step over line in one go +// - with two calls on the same line, step over both in one go +// - with two calls on the same line, step into the first and +// after stepping out, step over the second +module stepping_call::m; + +fun baz(p: u64): u64 { + p +} + +fun bar(p: u64): u64 { + p +} + +fun foo(p: u64): u64 { + let v1 = p + p + bar(p) + p + p; + let v2 = baz(p) + bar(p); + let v3 = baz(p) + bar(p); + v1 + v2 + v3 +} + +#[test] +fun test() { + foo(42); +} diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/test.exp b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/test.exp new file mode 100644 index 00000000000..c4fbc820cb8 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/test.exp @@ -0,0 +1,58 @@ +current frame stack: + function: test (m.move:25) + scope 0 : + function: foo (m.move:17) + scope 0 : + p : 42 + type: u64 + +current frame stack: + function: test (m.move:25) + scope 0 : + function: foo (m.move:18) + scope 0 : + p : 42 + type: u64 + + v1 : 210 + type: u64 + +current frame stack: + function: test (m.move:25) + scope 0 : + function: foo (m.move:19) + scope 0 : + p : 42 + type: u64 + + v1 : 210 + type: u64 + + v2 : 84 + type: u64 + +current frame stack: + function: test (m.move:25) + scope 0 : + function: foo (m.move:19) + scope 0 : + v1 : 210 + type: u64 + + v2 : 84 + type: u64 + +current frame stack: + function: test (m.move:25) + scope 0 : + function: foo (m.move:20) + scope 0 : + v1 : 210 + type: u64 + + v2 : 84 + type: u64 + + v3 : 84 + type: u64 + diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/trace.spec.js b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/trace.spec.js new file mode 100644 index 00000000000..80eb43a64fb --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/trace.spec.js @@ -0,0 +1,27 @@ +let action = (runtime) => { + let res = ''; + // step into the main test function + runtime.step(false); + res += runtime.toString(); + + // step over a function to the next line + runtime.step(true); + res += runtime.toString(); + + // step over two functions to the next line + runtime.step(true); + res += runtime.toString(); + + // step into a function + runtime.step(false); + // step out of the function to the same line + runtime.stepOut(false); + res += runtime.toString(); + // step into a function + runtime.step(false); + // step out of the function to the next line + runtime.stepOut(false); + res += runtime.toString(); + return res; +}; +run_spec(__dirname, action); diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/traces/stepping_call__m__test.json b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/traces/stepping_call__m__test.json new file mode 100644 index 00000000000..568616f2003 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tests/stepping_call/traces/stepping_call__m__test.json @@ -0,0 +1 @@ +{"version":1,"events":[{"OpenFrame":{"frame":{"frame_id":0,"function_name":"test","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":3,"type_instantiation":[],"parameters":[],"return_types":[],"locals_types":[],"is_native":false},"gas_left":1000000000}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999997,"instruction":"LD_U64"}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999997,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":4,"function_name":"foo","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":2,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null},{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999997}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999978,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999960,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999957,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999939,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":4,"gas_left":999999939,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":19,"function_name":"bar","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999939}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999920,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[19,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999919,"instruction":"RET"}},{"CloseFrame":{"frame_id":19,"return_":[{"RuntimeValue":{"value":42}}],"gas_left":999999919}},{"Instruction":{"type_parameters":[],"pc":5,"gas_left":999999916,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Push":{"RuntimeValue":{"value":126}}}},{"Instruction":{"type_parameters":[],"pc":6,"gas_left":999999898,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":7,"gas_left":999999895,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":126}}}},{"Effect":{"Push":{"RuntimeValue":{"value":168}}}},{"Instruction":{"type_parameters":[],"pc":8,"gas_left":999999877,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":9,"gas_left":999999874,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":168}}}},{"Effect":{"Push":{"RuntimeValue":{"value":210}}}},{"Instruction":{"type_parameters":[],"pc":10,"gas_left":999999873,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":210}}}},{"Effect":{"Write":{"location":{"Local":[4,1]},"root_value_after_write":{"RuntimeValue":{"value":210}}}}},{"Instruction":{"type_parameters":[],"pc":11,"gas_left":999999855,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":12,"gas_left":999999855,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":50,"function_name":"baz","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999855}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999836,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[50,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999835,"instruction":"RET"}},{"CloseFrame":{"frame_id":50,"return_":[{"RuntimeValue":{"value":42}}],"gas_left":999999835}},{"Instruction":{"type_parameters":[],"pc":13,"gas_left":999999817,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":14,"gas_left":999999817,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":60,"function_name":"bar","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999817}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999798,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[60,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999797,"instruction":"RET"}},{"CloseFrame":{"frame_id":60,"return_":[{"RuntimeValue":{"value":42}}],"gas_left":999999797}},{"Instruction":{"type_parameters":[],"pc":15,"gas_left":999999794,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":16,"gas_left":999999793,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Write":{"location":{"Local":[4,2]},"root_value_after_write":{"RuntimeValue":{"value":84}}}}},{"Instruction":{"type_parameters":[],"pc":17,"gas_left":999999775,"instruction":"COPY_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":false}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":18,"gas_left":999999775,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":77,"function_name":"baz","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":0,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999775}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999756,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[77,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999755,"instruction":"RET"}},{"CloseFrame":{"frame_id":77,"return_":[{"RuntimeValue":{"value":42}}],"gas_left":999999755}},{"Instruction":{"type_parameters":[],"pc":19,"gas_left":999999737,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":20,"gas_left":999999737,"instruction":"CALL"}},{"OpenFrame":{"frame":{"frame_id":87,"function_name":"bar","module":{"address":"0000000000000000000000000000000000000000000000000000000000000000","name":"m"},"binary_member_index":1,"type_instantiation":[],"parameters":[{"RuntimeValue":{"value":42}}],"return_types":[{"type_":"u64","ref_type":null}],"locals_types":[{"type_":"u64","ref_type":null}],"is_native":false},"gas_left":999999737}},{"Instruction":{"type_parameters":[],"pc":0,"gas_left":999999718,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[87,0]},"root_value_read":{"RuntimeValue":{"value":42}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":42}}}},{"Instruction":{"type_parameters":[],"pc":1,"gas_left":999999717,"instruction":"RET"}},{"CloseFrame":{"frame_id":87,"return_":[{"RuntimeValue":{"value":42}}],"gas_left":999999717}},{"Instruction":{"type_parameters":[],"pc":21,"gas_left":999999714,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":42}}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":22,"gas_left":999999713,"instruction":"ST_LOC"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Write":{"location":{"Local":[4,3]},"root_value_after_write":{"RuntimeValue":{"value":84}}}}},{"Instruction":{"type_parameters":[],"pc":23,"gas_left":999999695,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,1]},"root_value_read":{"RuntimeValue":{"value":210}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":210}}}},{"Instruction":{"type_parameters":[],"pc":24,"gas_left":999999677,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,2]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":25,"gas_left":999999674,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":210}}}},{"Effect":{"Push":{"RuntimeValue":{"value":294}}}},{"Instruction":{"type_parameters":[],"pc":26,"gas_left":999999656,"instruction":"MOVE_LOC"}},{"Effect":{"Read":{"location":{"Local":[4,3]},"root_value_read":{"RuntimeValue":{"value":84}},"moved":true}}},{"Effect":{"Push":{"RuntimeValue":{"value":84}}}},{"Instruction":{"type_parameters":[],"pc":27,"gas_left":999999653,"instruction":"ADD"}},{"Effect":{"Pop":{"RuntimeValue":{"value":84}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":294}}}},{"Effect":{"Push":{"RuntimeValue":{"value":378}}}},{"Instruction":{"type_parameters":[],"pc":28,"gas_left":999999652,"instruction":"RET"}},{"CloseFrame":{"frame_id":4,"return_":[{"RuntimeValue":{"value":378}}],"gas_left":999999652}},{"Instruction":{"type_parameters":[],"pc":2,"gas_left":999999651,"instruction":"POP"}},{"Effect":{"Pop":{"RuntimeValue":{"value":378}}}},{"Instruction":{"type_parameters":[],"pc":3,"gas_left":999999650,"instruction":"RET"}},{"CloseFrame":{"frame_id":0,"return_":[],"gas_left":999999650}}]} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-adapter/tsconfig.json b/external-crates/move/crates/move-analyzer/trace-adapter/tsconfig.json new file mode 100644 index 00000000000..d3363635c41 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-adapter/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "module": "Node16", + "target": "ES2022", + "outDir": "out", + "lib": [ + "ES2022" + ], + "sourceMap": true, + "rootDir": "src", + "esModuleInterop": true, + "resolveJsonModule": true, + "strict": true /* enable all strict type-checking options */ + }, + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-debug/.eslintrc.json b/external-crates/move/crates/move-analyzer/trace-debug/.eslintrc.json new file mode 100644 index 00000000000..9156c7ead3d --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/naming-convention": [ + "warn", + { + "selector": "import", + "format": [ + "camelCase", + "PascalCase" + ] + } + ], + "@typescript-eslint/semi": "warn", + "curly": "warn", + "eqeqeq": "warn", + "no-throw-literal": "warn", + "semi": "off" + }, + "ignorePatterns": [ + "out", + "dist", + "**/*.d.ts" + ] +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-debug/.vscode/launch.json b/external-crates/move/crates/move-analyzer/trace-debug/.vscode/launch.json new file mode 100644 index 00000000000..4f243877694 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/.vscode/launch.json @@ -0,0 +1,37 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ], + "preLaunchTask": "npm: prestart" + }, + { + "name": "Server", + "type": "node", + "request": "launch", + "cwd": "${workspaceFolder}", + "program": "./out/server.js", + "args": [], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ] + } + ], + "compounds": [ + { + "name": "Extension + Server", + "configurations": [ + "Extension", + "Server" + ] + } + ] +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-debug/.vscodeignore b/external-crates/move/crates/move-analyzer/trace-debug/.vscodeignore new file mode 100644 index 00000000000..8907b0d7a22 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/.vscodeignore @@ -0,0 +1,12 @@ +# Rather than listing out what files are *not* included in the extension, +# list out the small subset of files that *are* included. +# For more information on `.vscodeignore` files, see: +# https://code.visualstudio.com/api/working-with-extensions/publishing-extension#.vscodeignore +**/* +!node_modules/**/* +!out/** +!package-lock.json +!package.json +!LICENSE +!README.md +!images/move.png diff --git a/external-crates/move/crates/move-analyzer/trace-debug/LICENSE b/external-crates/move/crates/move-analyzer/trace-debug/LICENSE new file mode 100644 index 00000000000..7eb403e0798 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/LICENSE @@ -0,0 +1,230 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------------------------- + +Portions of the code in this project are derived from the vscode-mock-debug sample +(https://github.com/microsoft/vscode-mock-debug/) under the following license. + +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-debug/README.md b/external-crates/move/crates/move-analyzer/trace-debug/README.md new file mode 100644 index 00000000000..4b74bbeff63 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/README.md @@ -0,0 +1,49 @@ +# Move Trace Debugging + +Provides the ability to visualize Move trace files, which can be generated for a given package when running Move tests. These trace files contain information about which Move instructions are executed during a given test run. This extension leverages an implementation of the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) (DAP) that analyzes Move execution traces and presents them to the IDE client (in this case a VSCode extension) in a format that the client understands and can visualize using a familiar debugging interface. + +## Supported features + +Currently we support trace-debugging of Move unit tests only. and the following trace-debugging features are supported: + +- stepping forward through the trace (step, next, step out, and continue commands) +- tracking local variable values (including enums/structs and references) +- line breakpoints + +Note that support for trace-debugging macros and enums is limited at this point - stepping through macros or code related to enums may result in somewhat unexpected results due to how these constructs are handled internally by the Move execution framework. In particular, variable value tracking may be affected when trace-debugging these constructs. Work is ongoing to improve state-of-the-art - improvement suggestions and bug reports files as issues agains Iota's GitHub [repository](https://github.com/iotaledger/iota) are greatly appreciated. + +# How to Install + +1. Open a new window in any Visual Studio Code application version 1.61.0 or greater. +2. Open the command palette (`⇧` + `⌘` + `P` on macOS, `^` + `⇧` + `P` on Windows and GNU/Linux, + or use the menu item _View > Command Palette..._) and + type **Extensions: Install Extensions**. This will open a panel named _Extensions_ in the + sidebar of your Visual Studio Code window. +3. In the search bar labeled _Search Extensions in Marketplace_, type **Move Trace Debugger**. The Move Trace debugger extension + should appear as one of the option in the list below the search bar. Click **Install**. + +# How to trace-debug a Move unit test + +Debugging a Move unit tests consists of two steps: generating a Move trace and actually trace-debugging it. + +## Generating a Move trace + +If you have [IOTA Foundation's Move extension](https://marketplace.visualstudio.com/items?itemName=iota.move) installed you can generate a Move trace for tests defined in a given file by navigating to this file in VSCode and running `Move: Trace Move test execution` from the command palette. See the description of [IOTA Foundation's Move extension](https://marketplace.visualstudio.com/items?itemName=iota.move) for pre-requisites needed to run this command. + +If you plan to use the the Trace Debugging Extension by itself, you need to generate the traces using command-line interface of `iota` binary. See [here](https://docs.iota.org/guides/developer/getting-started/iota-install) for instructions on how to install `iota` binary. Note that the `iota` binary must be built with the `tracing` feature flag. If your version of the `iota` binary was not built with this feature flag, an attempt to trace test execution will fail. In this case you may have to build the `iota` binary from source following these [instructions](https://docs.iota.org/guides/developer/getting-started/iota-install#install-iota-binaries-from-source). + +Once the `iota` binary is installed, you generate traces for all test files in a given package by running the following command in the package's root directory: + +```shell +iota move test --trace-execution +``` + +You can limit trace generation to the tests whose name contains a filter string by passing this string as an additional argument to the trace generation command: + +```shell +iota move test FILTER_STRING --trace-execution +``` + +## Trace-debugging a test + +Once traces are generated, open a Move file containing the test you want to trace-debug and execute `Run->Start Debug` command. The first time you execute this command, you will have to choose the debugging configuration for Move files, of which there should be only one available. Then you will have to choose a test to trace-debug if there is more than one test in a file (otherwise a trace-debugging session for a single test will start automatically). diff --git a/external-crates/move/crates/move-analyzer/trace-debug/images/move.png b/external-crates/move/crates/move-analyzer/trace-debug/images/move.png new file mode 100644 index 0000000000000000000000000000000000000000..c6bfb341aefabd117af3a2081d29495f5d540b1a GIT binary patch literal 256463 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

<8iM-}q91e5BrX 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 SSN*Hh;jWH>cKPimVgC;zBo*QS literal 0 HcmV?d00001 diff --git a/external-crates/move/crates/move-analyzer/trace-debug/package-lock.json b/external-crates/move/crates/move-analyzer/trace-debug/package-lock.json new file mode 100644 index 00000000000..b18242b53b6 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/package-lock.json @@ -0,0 +1,1685 @@ +{ + "name": "move-trace-debug", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "move-trace-debug", + "version": "0.0.1", + "license": "Apache-2.0", + "dependencies": { + "@vscode/debugadapter": "^1.56.0", + "@vscode/debugadapter-testsupport": "^1.56.0", + "@vscode/debugprotocol": "1.66.0", + "toml": "^3.0.0" + }, + "devDependencies": { + "@types/node": "20.x", + "@types/vscode": "^1.92.0", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.11.0", + "eslint": "^8.57.0", + "typescript": "^5.4.5" + }, + "engines": { + "vscode": "^1.92.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/node": { + "version": "20.14.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", + "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/vscode": { + "version": "1.92.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.92.0.tgz", + "integrity": "sha512-DcZoCj17RXlzB4XJ7IfKdPTcTGDLYvTOcTNkvtjXWF+K2TlKzHHkBEXNWQRpBIXixNEUgx39cQeTFunY0E2msw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vscode/debugadapter": { + "version": "1.66.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter/-/debugadapter-1.66.0.tgz", + "integrity": "sha512-U/m5l6igHtQ8rSMSKW9oWeco9ySPqGYjqW9NECGPGWZ/xnoYicpqUoXhGx3xUNsafrinzWvUWrSUL/Cdgj2V+w==", + "dependencies": { + "@vscode/debugprotocol": "1.66.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugadapter-testsupport": { + "version": "1.66.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter-testsupport/-/debugadapter-testsupport-1.66.0.tgz", + "integrity": "sha512-MxXBv4wwPDml+0R3aU3d8lbH3fyRktEyIX4xDv5sArUrp1ONpN1f5vakQYfyKlRlySgu0O9NLnA+3Ylh90/RVw==", + "dependencies": { + "@vscode/debugprotocol": "1.66.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugprotocol": { + "version": "1.66.0", + "resolved": "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.66.0.tgz", + "integrity": "sha512-VGcRBLNL8QwHzwerSWOb60fy1FO7bdseZv6OkTS4opoP3xeyDX58i4/wAwakL2Y4P9NafN4VGrvlXSWIratmWA==" + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/external-crates/move/crates/move-analyzer/trace-debug/package.json b/external-crates/move/crates/move-analyzer/trace-debug/package.json new file mode 100644 index 00000000000..8bc91364cde --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/package.json @@ -0,0 +1,100 @@ +{ + "name": "move-trace-debug", + "displayName": "Move Trace Debugger", + "description": "An extension to visualize Move VM traces DAP-style", + "publisher": "IOTA Foundation", + "icon": "images/move.png", + "license": "Apache-2.0", + "version": "0.0.1", + "preview": true, + "repository": { + "url": "https://github.com/iotaledger/iota.git", + "type": "git" + }, + "engines": { + "vscode": "^1.92.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "onDebugDynamicConfigurations:move-debug", + "onDebugResolve:move-debug" + ], + "main": "./out/extension.js", + "contributes": { + "breakpoints": [{ "language": "move" }], + "debuggers": [ + { + "type": "move-debug", + "label": "Move Debug", + "program": "./out/server.js", + "runtime": "node", + "runtimeArgs": [ + "--nolazy" + ], + "languages": [ + "move" + ], + "configurationAttributes": { + "launch": { + "required": [ + "source", + "trace" + ], + "properties": { + "source": { + "type": "string", + "description": "Absolute path to the Move source file whose traces are to be viewed.", + "default": "${file}" + }, + "traceInfo": { + "type": "string", + "description": "Trace selected for viewing." + }, + "stopOnEntry": { + "type": "boolean", + "description": "Automatically stop after launch.", + "default": true + }, + "logLevel": { + "type": "string", + "description": "Logging level for the Debug Adapter Protocol.", + "enum": [ + "none", + "log", + "verbose" + ], + "default": "log" + } + } + } + } + } + ] + }, + "scripts": { + "vscode:prepublish": "npm run compile; tsc -p ../trace-adapter; cp ../trace-adapter/out/*.* ./out/", + "vscode:prepackage": "npm run compile; tsc -p ../trace-adapter; cp ../trace-adapter/out/*.* ./out/", + "compile": "tsc -p ./", + "watch": "tsc -watch -p ./", + "pretest": "npm run compile && npm run lint", + "lint": "eslint src --ext ts", + "test": "vscode-test", + "prestart": "npm run compile; tsc -p ../trace-adapter; cp ../trace-adapter/out/*.* ./out/" + }, + "dependencies": { + "@vscode/debugadapter": "^1.56.0", + "@vscode/debugadapter-testsupport": "^1.56.0", + "@vscode/debugprotocol": "1.66.0", + "toml": "^3.0.0" + }, + "devDependencies": { + "@types/vscode": "^1.92.0", + "@types/node": "20.x", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.11.0", + "eslint": "^8.57.0", + "typescript": "^5.4.5" + } +} \ No newline at end of file diff --git a/external-crates/move/crates/move-analyzer/trace-debug/src/extension.ts b/external-crates/move/crates/move-analyzer/trace-debug/src/extension.ts new file mode 100644 index 00000000000..e1a83441c35 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/src/extension.ts @@ -0,0 +1,325 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import * as fs from 'fs'; +import * as vscode from 'vscode'; +import * as path from 'path'; +import { StackFrame } from '@vscode/debugadapter'; +import { + WorkspaceFolder, + DebugConfiguration, + CancellationToken, + TextDocument, + Position +} from 'vscode'; + +/** + * Log level for the debug adapter. + */ +const LOG_LEVEL = 'log'; + +/** + * Describes debugger configuration name defined in package.json + */ +const DEBUGGER_TYPE = 'move-debug'; + +/** + * Provider of on-hover information during debug session. + */ +class MoveEvaluatableExpressionProvider { + // TODO: implement a more sophisticated provider that actually provides correct on-hover information, + // at least for variable definitions whose locations are readily available in the source map + // (user can always use go-to-def to see the definition and the value) + provideEvaluatableExpression(_document: TextDocument, _position: Position, _token: CancellationToken) { + // suppress debug-time on hover information for now + return null; + } +} + +/** + * Called when the extension is activated. +*/ +export function activate(context: vscode.ExtensionContext) { + + // register a configuration provider for 'move-debug' debug type + const provider = new MoveConfigurationProvider(); + context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('move-debug', provider)); + context.subscriptions.push( + vscode.debug.registerDebugAdapterDescriptorFactory(DEBUGGER_TYPE, { + createDebugAdapterDescriptor: (session: vscode.DebugSession) => { + return new vscode.DebugAdapterExecutable( + process.execPath, // This uses the Node.js executable that runs VS Code itself + [path.join(context.extensionPath, './out/server.js')] + ); + } + }) + ); + + let previousSourcePath: string | undefined; + const decorationType = vscode.window.createTextEditorDecorationType({ + color: 'grey', + backgroundColor: 'rgba(220, 220, 220, 0.5)' // grey with 50% opacity + }); + context.subscriptions.push( + vscode.debug.onDidChangeActiveStackItem(async stackItem => { + if (stackItem instanceof vscode.DebugStackFrame) { + const session = vscode.debug.activeDebugSession; + if (session) { + // Request the stack frame details from the debug adapter + const stackTraceResponse = await session.customRequest('stackTrace', { + threadId: stackItem.threadId, + startFrame: stackItem.frameId, + levels: 1 + }); + + const stackFrame: StackFrame = stackTraceResponse.stackFrames[0]; + if (stackFrame && stackFrame.source && stackFrame.source.path !== previousSourcePath) { + previousSourcePath = stackFrame.source.path; + const source = stackFrame.source; + const line = stackFrame.line; + console.log(`Frame details: ${source?.name} at line ${line}`); + + const editor = vscode.window.activeTextEditor; + if (editor) { + const optimized_lines = stackTraceResponse.optimized_lines; + const document = editor.document; + let decorationsArray: vscode.DecorationOptions[] = []; + + optimized_lines.forEach((lineNumber: number) => { + const line = document.lineAt(lineNumber); + const lineLength = line.text.length; + const lineText = line.text.trim(); + if (lineText.length !== 0 // ignore empty lines + && !lineText.startsWith("const") // ignore constant declarations (not in the source map) + && !lineText.startsWith("}")) { // ignore closing braces with nothing else on the same line + const decoration = { + range: new vscode.Range(lineNumber, 0, lineNumber, lineLength), + }; + decorationsArray.push(decoration); + } + }); + + editor.setDecorations(decorationType, decorationsArray); + } + } + } + } + }) + ); + + // register a provider of on-hover information during debug session + const langSelector = { scheme: 'file', language: 'move' }; + context.subscriptions.push( + vscode.languages.registerEvaluatableExpressionProvider( + langSelector, + new MoveEvaluatableExpressionProvider() + ) + ); + + context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(() => { + // reset all decorations when the debug session is terminated + // to avoid showing lines for code that was optimized away + const editor = vscode.window.activeTextEditor; + if (editor) { + editor.setDecorations(decorationType, []); + } + })); +} + +/** + * Called when the extension is deactivated. + */ +export function deactivate() { } + +/** + * Custom configuration provider for Move debug configurations. + */ +class MoveConfigurationProvider implements vscode.DebugConfigurationProvider { + + /** + * Massage a debug configuration just before a debug session is being launched, + * e.g. add all missing attributes to the debug configuration. + */ + async resolveDebugConfiguration(folder: WorkspaceFolder | undefined, config: DebugConfiguration, token?: CancellationToken): Promise { + + // if launch.json is missing or empty + if (!config.type && !config.request && !config.name) { + const editor = vscode.window.activeTextEditor; + if (editor && editor.document.languageId === 'move') { + + try { + let traceInfo = await findTraceInfo(editor); + config.type = DEBUGGER_TYPE; + config.name = 'Launch'; + config.request = 'launch'; + config.source = '${file}'; + config.traceInfo = traceInfo; + config.stopOnEntry = true; + config.logLevel = LOG_LEVEL; + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + return vscode.window.showErrorMessage(msg).then(_ => { + return undefined; // abort launch + }); + } + } + } + + if (!config.source) { + const msg = "Unknown error when trying to start the trace viewer"; + return vscode.window.showErrorMessage(msg).then(_ => { + return undefined; // abort launch + }); + } + + return config; + } +} + +/** + * Finds the trace information for the current active editor. + * + * @param editor active text editor. + * @returns trace information of the form `::::`. + * @throws Error with a descriptive error message if the trace information cannot be found. + */ +async function findTraceInfo(editor: vscode.TextEditor): Promise { + const pkgRoot = await findPkgRoot(editor.document.uri.fsPath); + if (!pkgRoot) { + throw new Error(`Cannot find package root for file '${editor.document.uri.fsPath}'`); + } + + const pkgModules = findModules(editor.document.getText()); + if (pkgModules.length === 0) { + throw new Error(`Cannot find any modules in file '${editor.document.uri.fsPath}'`); + } + + const tracedFunctions = findTracedFunctions(pkgRoot, pkgModules); + + if (tracedFunctions.length === 0) { + throw new Error(`No traced functions found for package at '${pkgRoot}'`); + } + + const fun = tracedFunctions.length === 1 + ? tracedFunctions[0] + : await pickFunctionToDebug(tracedFunctions); + + if (!fun) { + throw new Error(`No function to be trace-debugged selected from\n` + tracedFunctions.join('\n')); + } + + return fun; +} + +/** + * Finds the root directory of the package containing the active file. + * TODO: once `trace-adapter` is in npm registry, we can use the implementation of this function + * from `trace-adapter`. + * + * @param active_file_path path to a file active in the editor. + * @returns root directory of the package containing the active file. + */ +async function findPkgRoot(active_file_path: string): Promise { + const containsManifest = (dir: string): boolean => { + const filesInDir = fs.readdirSync(dir); + return filesInDir.includes('Move.toml'); + }; + + const activeFileDir = path.dirname(active_file_path); + let currentDir = activeFileDir; + while (currentDir !== path.parse(currentDir).root) { + if (containsManifest(currentDir)) { + return currentDir; + } + currentDir = path.resolve(currentDir, '..'); + } + + if (containsManifest(currentDir)) { + return currentDir; + } + + return undefined; +} + +/** + * Finds modules by searching the content of the file to look for + * module declarations of the form `module ::`. + * We cannot rely on the directory structure to find modules because + * trace info is generated based on module names in the source files. + * + * @param file_content content of the file. + * @returns modules in the file content of the form `::`. + */ +function findModules(file_content: string): string[] { + const modulePattern = /\bmodule\s+\w+::\w+\b/g; + const moduleSequences = file_content.match(modulePattern); + return moduleSequences + ? moduleSequences.map(str => str.substring('module'.length).trim()) + : []; +} + +/** + * Find all functions that have a corresponding trace file. + * + * @param pkgRoot root directory of the package. + * @param pkgModules modules in the package of the form `::`. + * @returns list of functions of the form `::::`. + * @throws Error (containing a descriptive message) if no trace files are found for the package. + */ +function findTracedFunctions(pkgRoot: string, pkgModules: string[]): string[] { + + function getFiles(tracesDir: string): string[] { + try { + return fs.readdirSync(tracesDir); + } catch (err) { + throw new Error(`Error accessing 'traces' directory for package at '${pkgRoot}'`); + } + } + const tracesDir = path.join(pkgRoot, 'traces'); + + const filePaths = getFiles(tracesDir); + if (filePaths.length === 0) { + throw new Error(`No trace files for package at ${pkgRoot}`); + } + const result: [string, string[]][] = []; + + pkgModules.forEach((module) => { + const prefix = module.replace(/:/g, '_') + '__'; + const prefixFiles = filePaths.filter((filePath) => filePath.startsWith(prefix)); + const suffixes = prefixFiles.map((file) => { + const suffix = file.substring(module.length); + if (suffix.startsWith('__') && suffix.endsWith('.json')) { + return suffix.substring(2, suffix.length - 5); + } + return suffix; + }); + result.push([module, suffixes]); + }); + + return result.map(([module, functionName]) => { + return functionName.map((func) => module + "::" + func); + }).flat(); +} + +/** + * Prompts the user to select a function to debug from a list of traced functions. + * + * @param tracedFunctions list of traced functions of the form `::::`. + * @returns single function to debug of the form `::::`. + */ +async function pickFunctionToDebug(tracedFunctions: string[]): Promise { + const selectedFunction = await vscode.window.showQuickPick(tracedFunctions.map(pkgFun => { + const [pkg, mod, fun] = pkgFun.split('::'); + const modFun = mod + '::' + fun; + return { + label: modFun, + pkg: pkg + }; + }), { + canPickMany: false, + placeHolder: 'Select a function to debug' + }); + + return selectedFunction ? selectedFunction.pkg + '::' + selectedFunction.label : undefined; +} diff --git a/external-crates/move/crates/move-analyzer/trace-debug/tsconfig.json b/external-crates/move/crates/move-analyzer/trace-debug/tsconfig.json new file mode 100644 index 00000000000..ee5e3883e53 --- /dev/null +++ b/external-crates/move/crates/move-analyzer/trace-debug/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "Node16", + "target": "ES2022", + "outDir": "out", + "lib": [ + "ES2022" + ], + "sourceMap": true, + "rootDir": "src", + "strict": true /* enable all strict type-checking options */ + } +} \ No newline at end of file diff --git a/external-crates/move/crates/move-binary-format/src/compatibility.rs b/external-crates/move/crates/move-binary-format/src/compatibility.rs index 3cd0945a1b0..ddd11e22267 100644 --- a/external-crates/move/crates/move-binary-format/src/compatibility.rs +++ b/external-crates/move/crates/move-binary-format/src/compatibility.rs @@ -3,26 +3,23 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::collections::BTreeSet; - use move_core_types::vm_status::StatusCode; use crate::{ + compatibility_mode::{CompatibilityMode, ExecutionCompatibilityMode}, errors::{PartialVMError, PartialVMResult}, - file_format::{AbilitySet, DatatypeTyParameter, Visibility}, + file_format::{Ability, AbilitySet, DatatypeTyParameter, Visibility}, file_format_common::VERSION_5, normalized::Module, }; - // *************************************************************************** // ******************* IMPORTANT NOTE ON COMPATIBILITY *********************** // *************************************************************************** // -// If `check_datatype_layout` and/or `check_datatype_and_pub_function_linking` -// is false, type safety over a series of upgrades cannot be guaranteed for -// either structs or enums. This is because the type could first be removed, and -// then re-introduced with a different layout and/or additional variants in a -// later upgrade. E.g., +// If `check_datatype_layout` is false, type safety over a series of upgrades +// cannot be guaranteed for either structs or enums. +// This is because the type could first be removed, and then re-introduced with +// a diferent layout and/or additional variants in a later upgrade. E.g., // * For enums you could add a new variant even if `disallow_new_variants` is // true, by first removing the enum in an upgrade, and then reintroducing it // with a new variant in a later upgrade. @@ -33,65 +30,31 @@ use crate::{ /// The result of a linking and layout compatibility check. /// /// Here is what the different combinations of the compatibility flags mean: -/// `{ check_datatype_and_pub_function_linking: true, check_datatype_layout: -/// true, check_friend_linking: true, check_private_entry_linking: true }`: -/// fully backward compatible `{ check_datatype_and_pub_function_linking: true, -/// check_datatype_layout: true, check_friend_linking: true, +/// `{ check_datatype_layout: true, check_private_entry_linking: true }`: fully +/// backward compatible `{ check_datatype_layout: true, /// check_private_entry_linking: false }`: Backwards compatible, private entry -/// function signatures can change `{ check_datatype_and_pub_function_linking: -/// true, check_datatype_layout: true, check_friend_linking: false, +/// function signatures can change `{ check_datatype_layout: true, /// check_private_entry_linking: true }`: Backward compatible, exclude the -/// friend module declare and friend functions -/// `{ check_datatype_and_pub_function_linking: true, check_datatype_layout: -/// true, check_friend_linking: false, check_private_entry_linking: false }`: -/// Backward compatible, exclude the friend module declarations, friend -/// functions, and private and friend entry function -/// `{ check_datatype_and_pub_function_linking: false, check_datatype_layout: -/// true, check_friend_linking: false, check_private_entry_linking: _ }`: -/// Dependent modules that reference functions or types in this module may not -/// link. However, fixing, recompiling, and redeploying all dependent modules -/// will work--no data migration needed. -/// `{ check_datatype_and_pub_function_linking: true, check_datatype_layout: -/// false, check_friend_linking: true, check_private_entry_linking: _ }`: -/// Attempting to read structs published by this module will now fail at -/// runtime. However, dependent modules will continue to link. Requires data -/// migration, but no changes to dependent modules. -/// `{ check_datatype_and_pub_function_linking: false, check_datatype_layout: -/// false, check_friend_linking: false, check_private_entry_linking: _ }`: -/// Everything is broken. Need both a data migration and changes to dependent -/// modules. +/// friend module declare and friend functions `{ check_datatype_layout: true, +/// check_private_entry_linking: false }`: Backward compatible, exclude the +/// friend module declarations, friend functions, and private and friend entry +/// function #[derive(PartialEq, Eq, Debug, Clone, Copy)] pub struct Compatibility { - /// if false, do not ensure the dependent modules that reference public - /// functions or structs in this module can link - pub check_datatype_and_pub_function_linking: bool, /// if false, do not ensure the struct layout capability pub check_datatype_layout: bool, - /// if false, treat `friend` as `private` when - /// `check_datatype_and_pub_function_linking`. - pub check_friend_linking: bool, - /// if false, treat `entry` as `private` when - /// `check_datatype_and_pub_function_linking`. + /// if false, treat `entry` as `private` pub check_private_entry_linking: bool, /// The set of abilities that cannot be added to an already exisiting type. pub disallowed_new_abilities: AbilitySet, - /// Don't allow generic type parameters in structs to change their abilities - /// or constraints. - pub disallow_change_datatype_type_params: bool, - /// Don't allow adding new variants at the end of an enum. - pub disallow_new_variants: bool, } impl Default for Compatibility { fn default() -> Self { Self { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: true, - disallow_new_variants: true, } } } @@ -103,13 +66,37 @@ impl Compatibility { pub fn no_check() -> Self { Self { - check_datatype_and_pub_function_linking: false, check_datatype_layout: false, - check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, + } + } + + /// Check compatibility for userspace module upgrades + pub fn upgrade_check() -> Self { + Self { + check_datatype_layout: true, + check_private_entry_linking: false, + disallowed_new_abilities: AbilitySet::ALL, + } + } + + /// Check compatibility for system module upgrades + pub fn framework_upgrade_check() -> Self { + Self { + check_datatype_layout: true, + // Checking `entry` linkage is required because system packages are updated in-place, + // and a transaction that was rolled back to make way for reconfiguration + // should still be runnable after a reconfiguration that upgraded the + // framework. + // + // A transaction that calls a system function that was previously `entry` and is now + // private will fail because its entrypoint became no longer callable. A + // transaction that calls a system function that was previously `public + // entry` and is now just `public` could also fail if one of its mutable + // inputs was being used in another private `entry` function. + check_private_entry_linking: true, + disallowed_new_abilities: AbilitySet::singleton(Ability::Key), } } @@ -120,15 +107,25 @@ impl Compatibility { /// Check compatibility for `new_module` relative to old module /// `old_module`. pub fn check(&self, old_module: &Module, new_module: &Module) -> PartialVMResult<()> { - let mut datatype_and_function_linking = true; - let mut datatype_layout = true; - let mut friend_linking = true; - let mut entry_linking = true; - let mut no_new_variants = true; + self.check_with_mode::(old_module, new_module) + .map_err(|_| PartialVMError::new(StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE)) + } + + pub fn check_with_mode( + &self, + old_module: &Module, + new_module: &Module, + ) -> Result<(), M::Error> { + let mut context = M::default(); // module's name and address are unchanged if old_module.address != new_module.address || old_module.name != new_module.name { - datatype_and_function_linking = false; + context.module_id_mismatch( + &old_module.address, + &old_module.name, + &new_module.address, + &new_module.name, + ); } // old module's structs are a subset of the new module's structs @@ -138,21 +135,24 @@ impl Compatibility { // fail to link with the new version of the module. Also, struct // layout cannot be guaranteed transitively, because after // removing the struct, it could be re-added later with a different layout. - datatype_and_function_linking = false; - datatype_layout = false; - break; + context.struct_missing(name, old_struct); + continue; }; if !datatype_abilities_compatible( self.disallowed_new_abilities, old_struct.abilities, new_struct.abilities, - ) || !datatype_type_parameters_compatible( - self.disallow_change_datatype_type_params, + ) { + context.struct_ability_mismatch(name, old_struct, new_struct); + } + + if !datatype_type_parameters_compatible( + self.check_datatype_layout, &old_struct.type_parameters, &new_struct.type_parameters, ) { - datatype_and_function_linking = false; + context.struct_type_param_mismatch(name, old_struct, new_struct); } if new_struct.fields != old_struct.fields { // Fields changed. Code in this module will fail at runtime if it tries to @@ -161,7 +161,8 @@ impl Compatibility { // choose that changing the name (but not position or type) of a field is // compatible. The VM does not care about the name of a field // (it's purely informational), but clients presumably do. - datatype_layout = false + + context.struct_field_mismatch(name, old_struct, new_struct); } } @@ -171,37 +172,37 @@ impl Compatibility { // to link with the new version of the module. Also, enum layout // cannot be guaranteed transitively, because after removing the // enum, it could be re-added later with a different layout. - datatype_and_function_linking = false; - datatype_layout = false; - break; + + context.enum_missing(name, old_enum); + continue; }; if !datatype_abilities_compatible( self.disallowed_new_abilities, old_enum.abilities, new_enum.abilities, - ) || !datatype_type_parameters_compatible( - self.disallow_change_datatype_type_params, + ) { + context.enum_ability_mismatch(name, old_enum, new_enum); + } + + if !datatype_type_parameters_compatible( + self.check_datatype_layout, &old_enum.type_parameters, &new_enum.type_parameters, ) { - datatype_and_function_linking = false; + context.enum_type_param_mismatch(name, old_enum, new_enum); } if new_enum.variants.len() > old_enum.variants.len() { - no_new_variants = false; - } - - if new_enum.variants.len() < old_enum.variants.len() { - datatype_layout = false; + context.enum_new_variant(name, old_enum, new_enum); } for (tag, old_variant) in old_enum.variants.iter().enumerate() { // If the new enum has fewer variants than the old one, datatype_layout is false // and we don't need to check the rest of the variants. let Some(new_variant) = new_enum.variants.get(tag) else { - datatype_layout = false; - break; + context.enum_variant_missing(name, old_enum, tag); + continue; }; if new_variant.name != old_variant.name { // TODO: Variant renamed. This is a stricter definition than required. @@ -209,7 +210,7 @@ impl Compatibility { // type) of a variant is compatible. The VM does not care about the name of a // variant if it's non-public (it's purely informational), but clients // presumably would. - datatype_layout = false; + context.enum_variant_mismatch(name, old_enum, new_enum, tag); } if new_variant.fields != old_variant.fields { // Fields changed. Code in this module will fail at runtime if it tries to @@ -218,7 +219,7 @@ impl Compatibility { // choose that changing the name (but not position or type) of a field is // compatible. The VM does not care about the name of a field // (it's purely informational), but clients presumably do. - datatype_layout = false + context.enum_variant_mismatch(name, old_enum, new_enum, tag); } } } @@ -230,47 +231,36 @@ impl Compatibility { // functions (i.e. we cannot remove or change public functions) // - old module's script functions are a subset of the new module's script // functions (i.e. we cannot remove or change script functions) - // - for any friend function that is removed or changed in the old module - // - if the function visibility is upgraded to public, it is OK - // - otherwise, it is considered as incompatible. - // - // NOTE: it is possible to relax the compatibility checking for a friend - // function, i.e., we can remove/change a friend function if the - // function is not used by any module in the friend list. But for - // simplicity, we decided to go to the more restrictive form now and - // we may revisit this in the future. for (name, old_func) in &old_module.functions { + // Check for removed public functions let Some(new_func) = new_module.functions.get(name) else { - if old_func.visibility == Visibility::Friend { - friend_linking = false; - } else if old_func.visibility != Visibility::Private { - datatype_and_function_linking = false; + if old_func.visibility == Visibility::Public { + context.function_missing_public(name, old_func); } else if old_func.is_entry && self.check_private_entry_linking { // This must be a private entry function. So set the link breakage if we're // checking for that. - entry_linking = false; + context.function_missing_entry(name, old_func); } continue; }; // Check visibility compatibility - match (old_func.visibility, new_func.visibility) { - (Visibility::Public, Visibility::Private | Visibility::Friend) => { - datatype_and_function_linking = false - } - (Visibility::Friend, Visibility::Private) => friend_linking = false, - _ => (), + if old_func.visibility == Visibility::Public + && new_func.visibility != Visibility::Public + { + context.function_lost_public_visibility(name, old_func); } // Check entry compatibility + #[allow(clippy::if_same_then_else)] if old_module.file_format_version < VERSION_5 && new_module.file_format_version < VERSION_5 && old_func.visibility != Visibility::Private && old_func.is_entry != new_func.is_entry { - entry_linking = false + context.function_entry_compatibility(name, old_func, new_func); } else if old_func.is_entry && !new_func.is_entry { - entry_linking = false; + context.function_entry_compatibility(name, old_func, new_func); } // Check signature compatibility @@ -281,55 +271,11 @@ impl Compatibility { &new_func.type_parameters, ) { - match old_func.visibility { - Visibility::Friend => friend_linking = false, - Visibility::Public => datatype_and_function_linking = false, - Visibility::Private => (), - } - - if old_func.is_entry { - entry_linking = false; - } + context.function_signature_mismatch(name, old_func, new_func); } } - // check friend declarations compatibility - // - // - additions to the list are allowed - // - removals are not allowed - // - let old_friend_module_ids: BTreeSet<_> = old_module.friends.iter().cloned().collect(); - let new_friend_module_ids: BTreeSet<_> = new_module.friends.iter().cloned().collect(); - if !old_friend_module_ids.is_subset(&new_friend_module_ids) { - friend_linking = false; - } - - if self.check_datatype_and_pub_function_linking && !datatype_and_function_linking { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - )); - } - if self.check_datatype_layout && !datatype_layout { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - )); - } - if self.check_friend_linking && !friend_linking { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - )); - } - if self.check_private_entry_linking && !entry_linking { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - )); - } - if self.disallow_new_variants && !no_new_variants { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - )); - } - Ok(()) + context.finish(self) } } diff --git a/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs b/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs new file mode 100644 index 00000000000..d273f5a3d39 --- /dev/null +++ b/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs @@ -0,0 +1,259 @@ +use crate::compatibility::Compatibility; +use crate::file_format::Visibility; +use crate::normalized::{Enum, Function, Struct}; +use move_core_types::account_address::AccountAddress; +use move_core_types::identifier::{IdentStr, Identifier}; + +/// A trait which will allow accumulating the information necessary for checking upgrade compatibility between two modules, +/// while allowing flexibility in the error type that is returned. +/// Gathers the errors and accumulates them into a single error. +/// The [`Compatibility`] struct's flags are used to determine the compatibility checks that are needed. +pub trait CompatibilityMode: Default { + /// The error type that will be returned when [`CompatibilityMode::finish`] is called, returning the accumulated result. + type Error; + + /// The module id mismatch error occurs when the module id of the old and new modules do not match. + fn module_id_mismatch( + &mut self, + old_addr: &AccountAddress, + old_name: &IdentStr, + new_addr: &AccountAddress, + new_name: &IdentStr, + ); + + /// The struct missing error occurs when a struct is present in the old module but not in the new module. + fn struct_missing(&mut self, name: &Identifier, old_struct: &Struct); + + /// The struct ability mismatch error occurs when the abilities of a struct are outside of the + /// allowed new abilities. Adding an ability is fine as long as it's not in the disallowed_new_abilities set. + fn struct_ability_mismatch( + &mut self, + name: &Identifier, + old_struct: &Struct, + new_struct: &Struct, + ); + + /// Struct type parameters mismatch error occurs when the type parameters of a struct are not the same. + fn struct_type_param_mismatch( + &mut self, + name: &Identifier, + old_struct: &Struct, + new_struct: &Struct, + ); + + /// Struct field mismatch error occurs when the fields of a struct are not the same. + fn struct_field_mismatch( + &mut self, + name: &Identifier, + old_struct: &Struct, + new_struct: &Struct, + ); + + /// Enum missing error occurs when an enum is present in the old module but not in the new module. + fn enum_missing(&mut self, name: &Identifier, old_enum: &Enum); + + /// Enum ability mismatch error occurs when the abilities of an enum are outside of the + /// allowed new abilities. Adding an ability is fine as long as it's not in the disallowed_new_abilities set. + fn enum_ability_mismatch(&mut self, name: &Identifier, old_enum: &Enum, new_enum: &Enum); + + /// Enum type parameters mismatch error occurs when the type parameters of an enum are not the same. + fn enum_type_param_mismatch(&mut self, name: &Identifier, old_enum: &Enum, new_enum: &Enum); + + /// Enum new variant error occurs when a new variant is added to an enum. + fn enum_new_variant(&mut self, name: &Identifier, old_enum: &Enum, new_enum: &Enum); + + /// Enum variant missing error occurs when a variant is present in the old enum but not in the new enum. + fn enum_variant_missing(&mut self, name: &Identifier, old_enum: &Enum, tag: usize); + + /// Enum variant mismatch error occurs when a variant is present in the old enum but not in the new enum. + fn enum_variant_mismatch( + &mut self, + name: &Identifier, + old_enum: &Enum, + new_enum: &Enum, + tag: usize, + ); + + /// Function missing public error occurs when a public function is present in the old module but not in the new module. + fn function_missing_public(&mut self, name: &Identifier, old_func: &Function); + + /// Function missing entry error occurs when an entry function is present in the old module but not in the new module. + fn function_missing_entry(&mut self, name: &Identifier, old_func: &Function); + + /// Function signature mismatch error occurs when the signature of a function changes. + fn function_signature_mismatch( + &mut self, + name: &Identifier, + old_func: &Function, + new_func: &Function, + ); + + /// Function lost public visibility error occurs when a function loses its public visibility. + fn function_lost_public_visibility(&mut self, name: &Identifier, old_func: &Function); + + /// Function entry compatibility error occurs when an entry function is not compatible. + fn function_entry_compatibility( + &mut self, + name: &Identifier, + old_func: &Function, + new_func: &Function, + ); + + /// Finish the compatibility check and return the error if one has been accumulated from individual errors. + fn finish(self, _: &Compatibility) -> Result<(), Self::Error>; +} + +/// Compatibility mode impl for execution compatibility checks. +/// These flags are set when a type safety check is violated. see [`Compatibility`] for more information. +pub struct ExecutionCompatibilityMode { + /// This can never be overridden with a flag, and thus has no associated [`Compatibility`] flag. + /// In other words public linking can never be broken. all other flags + datatype_and_function_linking: bool, + datatype_layout: bool, + entry_linking: bool, + no_new_variants: bool, +} + +impl Default for ExecutionCompatibilityMode { + fn default() -> Self { + Self { + datatype_and_function_linking: true, + datatype_layout: true, + entry_linking: true, + no_new_variants: true, + } + } +} + +impl CompatibilityMode for ExecutionCompatibilityMode { + /// Unit error type for execution compatibility mode. + /// We only need to know if an error has occurred. + type Error = (); + + fn module_id_mismatch( + &mut self, + _old_addr: &AccountAddress, + _old_name: &IdentStr, + _new_addr: &AccountAddress, + _new_name: &IdentStr, + ) { + self.datatype_and_function_linking = false; + } + + fn struct_missing(&mut self, _name: &Identifier, _old_struct: &Struct) { + self.datatype_and_function_linking = false; + self.datatype_layout = false; + } + + fn struct_ability_mismatch( + &mut self, + _name: &Identifier, + _old_struct: &Struct, + _new_struct: &Struct, + ) { + self.datatype_and_function_linking = false; + } + + fn struct_type_param_mismatch( + &mut self, + _name: &Identifier, + _old_struct: &Struct, + _new_struct: &Struct, + ) { + self.datatype_and_function_linking = false; + } + + fn struct_field_mismatch( + &mut self, + _name: &Identifier, + _old_struct: &Struct, + _new_struct: &Struct, + ) { + self.datatype_layout = false; + } + + fn enum_missing(&mut self, _name: &Identifier, _old_enum: &Enum) { + self.datatype_and_function_linking = false; + self.datatype_layout = false; + } + + fn enum_ability_mismatch(&mut self, _name: &Identifier, _old_enum: &Enum, _new_enum: &Enum) { + self.datatype_and_function_linking = false; + } + + fn enum_type_param_mismatch(&mut self, _name: &Identifier, _old_enum: &Enum, _new_enum: &Enum) { + self.datatype_and_function_linking = false; + } + + fn enum_new_variant(&mut self, _name: &Identifier, _old_enum: &Enum, _new_enum: &Enum) { + self.no_new_variants = false; + } + + fn enum_variant_missing(&mut self, _name: &Identifier, _old_enum: &Enum, _tag: usize) { + self.datatype_layout = false; + } + + fn enum_variant_mismatch( + &mut self, + _name: &Identifier, + _old_enum: &Enum, + _new_enum: &Enum, + _tag: usize, + ) { + self.datatype_layout = false; + } + + fn function_missing_public(&mut self, _name: &Identifier, _old_func: &Function) { + self.datatype_and_function_linking = false; + } + + fn function_missing_entry(&mut self, _name: &Identifier, _old_func: &Function) { + self.entry_linking = false; + } + + fn function_signature_mismatch( + &mut self, + _name: &Identifier, + old_func: &Function, + _new_func: &Function, + ) { + if old_func.visibility == Visibility::Public { + self.datatype_and_function_linking = false; + } + + if old_func.is_entry { + self.entry_linking = false; + } + } + + fn function_lost_public_visibility(&mut self, _name: &Identifier, _old_func: &Function) { + self.datatype_and_function_linking = false; + } + + fn function_entry_compatibility( + &mut self, + _name: &Identifier, + _old_func: &Function, + _new_func: &Function, + ) { + self.entry_linking = false; + } + + /// Finish by comparing against the compatibility flags. + fn finish(self, compatability: &Compatibility) -> Result<(), ()> { + if !self.datatype_and_function_linking { + return Err(()); + } + if compatability.check_datatype_layout && !self.datatype_layout { + return Err(()); + } + if compatability.check_private_entry_linking && !self.entry_linking { + return Err(()); + } + if compatability.check_datatype_layout && !self.no_new_variants { + return Err(()); + } + + Ok(()) + } +} diff --git a/external-crates/move/crates/move-binary-format/src/file_format.rs b/external-crates/move/crates/move-binary-format/src/file_format.rs index 8421597b99d..0feda8789bf 100644 --- a/external-crates/move/crates/move-binary-format/src/file_format.rs +++ b/external-crates/move/crates/move-binary-format/src/file_format.rs @@ -32,12 +32,11 @@ //! binary of the form described. Vectors in those structs translate to tables //! and table specifications. -use crate::{ - errors::{PartialVMError, PartialVMResult}, - file_format_common, - internals::ModuleIndex, - IndexKind, SignatureTokenKind, +use std::{ + fmt::{Display, Formatter}, + ops::BitOr, }; + use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, @@ -49,9 +48,15 @@ use move_core_types::{ use proptest::{collection::vec, prelude::*, strategy::BoxedStrategy}; use ref_cast::RefCast; use serde::{Deserialize, Serialize}; -use std::ops::BitOr; use variant_count::VariantCount; +use crate::{ + IndexKind, SignatureTokenKind, + errors::{PartialVMError, PartialVMResult}, + file_format_common, + internals::ModuleIndex, +}; + /// Generic index into one of the tables in the binary format. pub type TableIndex = u16; @@ -821,6 +826,17 @@ impl Ability { } } +impl Display for Ability { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + match self { + Ability::Copy => write!(f, "copy"), + Ability::Drop => write!(f, "drop"), + Ability::Store => write!(f, "store"), + Ability::Key => write!(f, "key"), + } + } +} + /// A set of `Ability`s #[derive(Clone, Eq, Copy, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] #[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))] @@ -876,7 +892,7 @@ impl AbilitySet { } pub fn remove(self, ability: Ability) -> Self { - Self(self.0 & (!(ability as u8))) + self.difference(Self::singleton(ability)) } pub fn intersect(self, other: Self) -> Self { @@ -887,6 +903,10 @@ impl AbilitySet { Self(self.0 | other.0) } + pub fn difference(self, other: Self) -> Self { + Self(self.0 & !other.0) + } + #[inline] fn is_subset_bits(sub: u8, sup: u8) -> bool { (sub & sup) == sub @@ -2776,11 +2796,9 @@ impl CompiledModule { Reference(_) | MutableReference(_) => Ok(AbilitySet::REFERENCES), Signer => Ok(AbilitySet::SIGNER), TypeParameter(idx) => Ok(constraints[*idx as usize]), - Vector(ty) => AbilitySet::polymorphic_abilities( - AbilitySet::VECTOR, - vec![false], - vec![self.abilities(ty, constraints)?], - ), + Vector(ty) => AbilitySet::polymorphic_abilities(AbilitySet::VECTOR, vec![false], vec![ + self.abilities(ty, constraints)?, + ]), Datatype(idx) => { let sh = self.datatype_handle_at(*idx); Ok(sh.abilities) diff --git a/external-crates/move/crates/move-binary-format/src/file_format_common.rs b/external-crates/move/crates/move-binary-format/src/file_format_common.rs index 281a4759de8..e3601195a85 100644 --- a/external-crates/move/crates/move-binary-format/src/file_format_common.rs +++ b/external-crates/move/crates/move-binary-format/src/file_format_common.rs @@ -17,7 +17,7 @@ use std::{ mem::size_of, }; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use move_core_types as MVT; use crate::file_format::Bytecode; @@ -535,11 +535,10 @@ pub const VERSION_MAX: u32 = VERSION_7; // TODO(#145): finish v4 compatibility; as of now, only metadata is implemented pub const VERSION_MIN: u32 = VERSION_5; -/// The encoding of the instruction is the serialized form of it, but -/// disregarding the serialization of the instruction's argument(s). -pub fn instruction_key(instruction: &Bytecode) -> u8 { +/// The corresponding opcode for each bytecode (disregards the argument). +pub fn instruction_opcode(instruction: &Bytecode) -> Opcodes { use Bytecode::*; - let opcode = match instruction { + match instruction { Pop => Opcodes::POP, Ret => Opcodes::RET, BrTrue(_) => Opcodes::BR_TRUE, @@ -627,6 +626,11 @@ pub fn instruction_key(instruction: &Bytecode) -> u8 { MutBorrowGlobalGenericDeprecated(_) => Opcodes::MUT_BORROW_GLOBAL_GENERIC_DEPRECATED, ImmBorrowGlobalDeprecated(_) => Opcodes::IMM_BORROW_GLOBAL_DEPRECATED, ImmBorrowGlobalGenericDeprecated(_) => Opcodes::IMM_BORROW_GLOBAL_GENERIC_DEPRECATED, - }; - opcode as u8 + } +} + +/// The encoding of the instruction is the serialized form of it, but +/// disregarding the serialization of the instruction's argument(s). +pub fn instruction_key(instruction: &Bytecode) -> u8 { + instruction_opcode(instruction) as u8 } diff --git a/external-crates/move/crates/move-binary-format/src/lib.rs b/external-crates/move/crates/move-binary-format/src/lib.rs index ca24dba3769..e14767cec47 100644 --- a/external-crates/move/crates/move-binary-format/src/lib.rs +++ b/external-crates/move/crates/move-binary-format/src/lib.rs @@ -10,6 +10,7 @@ use std::fmt; pub mod binary_config; pub mod check_bounds; pub mod compatibility; +pub mod compatibility_mode; #[macro_use] pub mod errors; pub mod constant; diff --git a/external-crates/move/crates/move-binary-format/src/proptest_types/types.rs b/external-crates/move/crates/move-binary-format/src/proptest_types/types.rs index 3c3aca6c64a..9f6df8d5f4e 100644 --- a/external-crates/move/crates/move-binary-format/src/proptest_types/types.rs +++ b/external-crates/move/crates/move-binary-format/src/proptest_types/types.rs @@ -6,7 +6,7 @@ use std::collections::BTreeSet; use proptest::{ - collection::{vec, SizeRange}, + collection::{SizeRange, vec}, option, prelude::*, sample::Index as PropIndex, diff --git a/external-crates/move/crates/move-binary-format/src/unit_tests/compatibility_tests.rs b/external-crates/move/crates/move-binary-format/src/unit_tests/compatibility_tests.rs index 658dcb0711d..a5ca74b9c69 100644 --- a/external-crates/move/crates/move-binary-format/src/unit_tests/compatibility_tests.rs +++ b/external-crates/move/crates/move-binary-format/src/unit_tests/compatibility_tests.rs @@ -648,13 +648,9 @@ fn private_entry_signature_change_allowed() { // allow updating signatures of private entry functions assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&module, &updated_module) .is_ok() @@ -663,13 +659,9 @@ fn private_entry_signature_change_allowed() { // allow updating signatures of private entry functions assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&updated_module, &module) .is_ok() @@ -728,9 +720,6 @@ fn entry_fun_compat_tests() { (&public_entry_fun, &friend_entry_fun), (&public_entry_fun, &friend_fun), (&public_entry_fun, &no_fun), - (&friend_entry_fun, &no_fun), - (&friend_entry_fun, &private_fun), - (&friend_entry_fun, &entry_fun), ]; let invalid_private_entry_breakages = vec![ @@ -756,13 +745,9 @@ fn entry_fun_compat_tests() { for (prev, new) in valid_combos.into_iter() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(prev, new) .is_ok() @@ -778,43 +763,21 @@ fn entry_fun_compat_tests() { for (prev, new) in valid_entry_fun_changes_with_friend_api_breakage.into_iter() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(prev, new) .is_ok() ); - - assert!( - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: true, - check_private_entry_linking: false, - disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, - } - .check(prev, new) - .is_err() - ); } for (prev, new) in invalid_combos.into_iter() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(prev, new) .is_err() @@ -836,13 +799,9 @@ fn public_entry_signature_change_disallowed() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&module, &updated_module) .is_err() @@ -850,13 +809,9 @@ fn public_entry_signature_change_disallowed() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&updated_module, &module) .is_err() @@ -864,13 +819,9 @@ fn public_entry_signature_change_disallowed() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&module, &updated_module) .is_err() @@ -890,13 +841,9 @@ fn friend_entry_signature_change_allowed() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&module, &updated_module) .is_ok() @@ -904,41 +851,9 @@ fn friend_entry_signature_change_allowed() { assert!( Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: true, - check_friend_linking: true, - check_private_entry_linking: false, - disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, - } - .check(&module, &updated_module) - .is_err() - ); - - assert!( - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, - } - .check(&module, &updated_module) - .is_err() - ); - - assert!( - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: true, - check_private_entry_linking: true, - disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, } .check(&module, &updated_module) .is_err() @@ -959,10 +874,10 @@ fn check_exact_and_unchange_same_module() { assert!(InclusionCheck::Equal.check(&m2, &m1).is_err()); // m1 + a change in the bytecode of fn - let m3 = max_version(mk_module_plus_code( - Visibility::Private as u8, - vec![Bytecode::LdU8(0), Bytecode::Ret], - )); + let m3 = max_version(mk_module_plus_code(Visibility::Private as u8, vec![ + Bytecode::LdU8(0), + Bytecode::Ret, + ])); assert!(InclusionCheck::Subset.check(&m2, &m3).is_err()); // fn1 is not in m1 so the changed bytecode doesn't matter. assert!(InclusionCheck::Subset.check(&m1, &m3).is_ok()); diff --git a/external-crates/move/crates/move-bytecode-source-map/Cargo.toml b/external-crates/move/crates/move-bytecode-source-map/Cargo.toml index 2a7b04af277..99935dd0eac 100644 --- a/external-crates/move/crates/move-bytecode-source-map/Cargo.toml +++ b/external-crates/move/crates/move-bytecode-source-map/Cargo.toml @@ -17,6 +17,7 @@ move-symbol-pool.workspace = true bcs.workspace = true serde.workspace = true +serde_json.workspace = true [features] default = [] diff --git a/external-crates/move/crates/move-bytecode-source-map/src/source_map.rs b/external-crates/move/crates/move-bytecode-source-map/src/source_map.rs index 75886989f84..5801d1dbcf6 100644 --- a/external-crates/move/crates/move-bytecode-source-map/src/source_map.rs +++ b/external-crates/move/crates/move-bytecode-source-map/src/source_map.rs @@ -5,14 +5,14 @@ use std::{collections::BTreeMap, ops::Bound}; -use anyhow::{format_err, Result}; +use anyhow::{Result, format_err}; use move_binary_format::{ + CompiledModule, file_format::{ AbilitySet, CodeOffset, CodeUnit, ConstantPoolIndex, EnumDefinition, EnumDefinitionIndex, FunctionDefinitionIndex, LocalIndex, MemberCount, ModuleHandleIndex, SignatureIndex, StructDefinition, StructDefinitionIndex, TableIndex, VariantTag, }, - CompiledModule, }; use move_command_line_common::files::FileHash; use move_core_types::{account_address::AccountAddress, identifier::Identifier}; @@ -63,6 +63,11 @@ pub struct FunctionSourceMap { /// that in certain instances this will have no valid source location /// e.g. the "main" function for modules that are treated as programs /// are synthesized and therefore have no valid source location. + pub location: Loc, + /// The source location for the name under which this functin is defined. + /// Note that in certain instances this will have no valid source + /// location e.g. the "main" function for modules that are treated as + /// programs are synthesized and therefore have no valid source location. pub definition_location: Loc, /// The names of the type parameters to the function. @@ -73,6 +78,9 @@ pub struct FunctionSourceMap { /// The names of the parameters to the function. pub parameters: Vec, + /// The locations of the return values + pub returns: Vec, + /// The index into the vector is the local's index. The corresponding /// `(Identifier, Location)` tuple is the name and location of the /// local. @@ -210,11 +218,13 @@ impl EnumSourceMap { } impl FunctionSourceMap { - pub fn new(definition_location: Loc, is_native: bool) -> Self { + pub fn new(location: Loc, definition_location: Loc, is_native: bool) -> Self { Self { + location, definition_location, type_parameters: Vec::new(), parameters: Vec::new(), + returns: Vec::new(), locals: Vec::new(), code_map: BTreeMap::new(), is_native, @@ -262,6 +272,10 @@ impl FunctionSourceMap { self.parameters.push(name) } + /// add the locations of return values + pub fn add_return_mapping(&mut self, loc: Loc) { + self.returns.push(loc); + } /// Recall that we are using a segment tree. We therefore lookup the /// location for the code offset by performing a range query for the /// largest number less than or equal to the code offset passed in. @@ -363,9 +377,10 @@ impl SourceMap { &mut self, fdef_idx: FunctionDefinitionIndex, location: Loc, + definition_location: Loc, is_native: bool, ) -> Result<()> { - self.function_map.insert(fdef_idx.0, FunctionSourceMap::new(location, is_native)).map_or(Ok(()), |_| { Err(format_err!( + self.function_map.insert(fdef_idx.0, FunctionSourceMap::new(location, definition_location, is_native)).map_or(Ok(()), |_| { Err(format_err!( "Multiple functions at same function definition index encountered when constructing source map" )) }) } @@ -462,6 +477,18 @@ impl SourceMap { Ok(()) } + pub fn add_return_mapping( + &mut self, + fdef_idx: FunctionDefinitionIndex, + loc: Loc, + ) -> Result<()> { + let func_entry = self.function_map.get_mut(&fdef_idx.0).ok_or_else(|| { + format_err!("Tried to add return mapping to undefined function index") + })?; + func_entry.add_return_mapping(loc); + Ok(()) + } + pub fn get_parameter_or_local_name( &self, fdef_idx: FunctionDefinitionIndex, @@ -648,6 +675,7 @@ impl SourceMap { empty_source_map.add_top_level_function_mapping( FunctionDefinitionIndex(function_idx as TableIndex), default_loc, + default_loc, false, )?; let function_handle = module.function_handle_at(function_def.function); diff --git a/external-crates/move/crates/move-bytecode-source-map/src/utils.rs b/external-crates/move/crates/move-bytecode-source-map/src/utils.rs index c9ca8510f20..e52c9271519 100644 --- a/external-crates/move/crates/move-bytecode-source-map/src/utils.rs +++ b/external-crates/move/crates/move-bytecode-source-map/src/utils.rs @@ -3,9 +3,13 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::{fs::File, io::Read, path::Path}; +use std::{ + fs::File, + io::{Read, Write}, + path::Path, +}; -use anyhow::{format_err, Result}; +use anyhow::{Result, format_err}; use move_ir_types::location::Loc; use crate::source_map::SourceMap; @@ -14,6 +18,9 @@ pub type Error = (Loc, String); pub type Errors = Vec; pub fn source_map_from_file(file_path: &Path) -> Result { + if file_path.extension().is_some_and(|ext| ext == "json") { + return deserialize_from_json(file_path); + } let mut bytes = Vec::new(); File::open(file_path) .ok() @@ -22,3 +29,31 @@ pub fn source_map_from_file(file_path: &Path) -> Result { bcs::from_bytes::(&bytes) .map_err(|_| format_err!("Error deserializing into source map")) } + +pub fn serialize_to_json(map: &SourceMap) -> Result> { + serde_json::to_vec(map).map_err(|e| format_err!("Error serializing to json: {}", e)) +} + +pub fn serialize_to_json_file(map: &SourceMap, file_path: &Path) -> Result<()> { + let json = serde_json::to_string_pretty(map) + .map_err(|e| format_err!("Error serializing to json: {}", e))?; + let mut f = + std::fs::File::create(file_path).map_err(|e| format_err!("Error creating file: {}", e))?; + f.write_all(json.as_bytes()) + .map_err(|e| format_err!("Error writing to file: {}", e))?; + Ok(()) +} + +pub fn deserialize_from_json(file_path: &Path) -> Result { + let mut file = File::open(file_path).map_err(|e| format_err!("Error opening file: {}", e))?; + let mut json = String::new(); + file.read_to_string(&mut json) + .map_err(|e| format_err!("Error reading file: {}", e))?; + serde_json::from_str(&json).map_err(|e| format_err!("Error deserializing from json: {}", e)) +} + +pub fn convert_to_json(file_path: &Path) -> Result<()> { + let map = source_map_from_file(file_path)?; + let json_file_path = file_path.with_extension("json"); + serialize_to_json_file(&map, &json_file_path) +} diff --git a/external-crates/move/crates/move-bytecode-utils/Cargo.toml b/external-crates/move/crates/move-bytecode-utils/Cargo.toml index 67c7089e7ce..b89386d0bba 100644 --- a/external-crates/move/crates/move-bytecode-utils/Cargo.toml +++ b/external-crates/move/crates/move-bytecode-utils/Cargo.toml @@ -9,6 +9,7 @@ description = "Libraries for working with sets of Move bytecode modules" [dependencies] anyhow.workspace = true +indexmap.workspace = true move-binary-format.workspace = true move-core-types.workspace = true petgraph.workspace = true diff --git a/external-crates/move/crates/move-bytecode-utils/src/dependency_graph.rs b/external-crates/move/crates/move-bytecode-utils/src/dependency_graph.rs deleted file mode 100644 index 0ee3ca78dcf..00000000000 --- a/external-crates/move/crates/move-bytecode-utils/src/dependency_graph.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::CompiledModule; -use petgraph::graphmap::DiGraphMap; - -use anyhow::{bail, Result}; -use std::collections::BTreeMap; - -/// Directed graph capturing dependencies between modules -pub struct DependencyGraph<'a> { - /// Set of modules guaranteed to be closed under dependencies - modules: Vec<&'a CompiledModule>, - graph: DiGraphMap, -} - -#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, PartialOrd, Ord)] -struct ModuleIndex(usize); - -impl<'a> DependencyGraph<'a> { - /// Construct a dependency graph from a set of `modules`. - /// Panics if `modules` contains duplicates or is not closed under the - /// dependency relation - pub fn new(module_iter: impl IntoIterator) -> Self { - let mut modules = vec![]; - let mut reverse_modules = BTreeMap::new(); - for (i, m) in module_iter.into_iter().enumerate() { - modules.push(m); - assert!( - reverse_modules - .insert(m.self_id(), ModuleIndex(i)) - .is_none(), - "Duplicate module found" - ); - } - let mut graph = DiGraphMap::new(); - for module in &modules { - let module_idx: ModuleIndex = *reverse_modules.get(&module.self_id()).unwrap(); - let deps = module.immediate_dependencies(); - if deps.is_empty() { - graph.add_node(module_idx); - } else { - for dep in deps { - let dep_idx = *reverse_modules - .get(&dep) - .unwrap_or_else(|| panic!("Missing dependency {}", dep)); - graph.add_edge(dep_idx, module_idx, ()); - } - } - } - DependencyGraph { modules, graph } - } - - /// Return an iterator over the modules in `self` in topological - /// order--modules with least deps first. Fails with an error if `self` - /// contains circular dependencies - pub fn compute_topological_order(&self) -> Result> { - match petgraph::algo::toposort(&self.graph, None) { - Err(_) => bail!("Circular dependency detected"), - Ok(ordered_idxs) => Ok(ordered_idxs.into_iter().map(move |idx| self.modules[idx.0])), - } - } -} diff --git a/external-crates/move/crates/move-bytecode-utils/src/layout.rs b/external-crates/move/crates/move-bytecode-utils/src/layout.rs index 0cae4c2c6f1..d3ba59c048a 100644 --- a/external-crates/move/crates/move-bytecode-utils/src/layout.rs +++ b/external-crates/move/crates/move-bytecode-utils/src/layout.rs @@ -227,8 +227,8 @@ impl<'a, T: GetModule> SerdeLayoutBuilder<'a, T> { (None, Some(enum_def)) => { Container::Enum(Enum::new(declaring_module.borrow(), enum_def).1) } - (Some(_), Some(_)) => panic!("Found both struct and enum with name {}", name), - (None, None) => panic!( + (Some(_), Some(_)) => bail!("Found both struct and enum with name {}", name), + (None, None) => bail!( "Could not find datatype named {} in module {}", name, declaring_module.borrow().name() @@ -288,7 +288,7 @@ impl<'a, T: GetModule> SerdeLayoutBuilder<'a, T> { if old_datatype.clone() != self.generate_serde_container(def, type_arguments, depth)? { - panic!( + bail!( "Name conflict: multiple structs with name {}, but different addresses", type_key ) @@ -588,7 +588,10 @@ impl DatatypeLayoutBuilder { .zip(layouts) .map(|(name, layout)| A::MoveFieldLayout::new(name, layout)) .collect(); - Ok(A::MoveStructLayout { type_, fields }) + Ok(A::MoveStructLayout { + type_, + fields: Box::new(fields), + }) } } } @@ -609,7 +612,7 @@ impl DatatypeLayoutBuilder { module.borrow().find_struct_def_by_name(name), module.borrow().find_enum_def_by_name(name), ) { - (Some(struct_def), None) => Ok(A::MoveDatatypeLayout::Struct( + (Some(struct_def), None) => Ok(A::MoveDatatypeLayout::Struct(Box::new( Self::build_from_struct_definition( module.borrow(), struct_def, @@ -617,8 +620,8 @@ impl DatatypeLayoutBuilder { resolver, depth, )?, - )), - (None, Some(enum_def)) => Ok(A::MoveDatatypeLayout::Enum( + ))), + (None, Some(enum_def)) => Ok(A::MoveDatatypeLayout::Enum(Box::new( Self::build_from_enum_definition( module.borrow(), enum_def, @@ -626,9 +629,9 @@ impl DatatypeLayoutBuilder { resolver, depth, )?, - )), - (Some(_), Some(_)) => panic!("Found both struct and enum with name {}", name), - (None, None) => panic!( + ))), + (Some(_), Some(_)) => bail!("Found both struct and enum with name {}", name), + (None, None) => bail!( "Could not find struct/enum named {} in module {}", name, module.borrow().name() @@ -646,13 +649,13 @@ impl DatatypeLayoutBuilder { check_depth!(depth); if let Some(def) = m.find_struct_def(s) { // declared internally - Ok(A::MoveDatatypeLayout::Struct( + Ok(A::MoveDatatypeLayout::Struct(Box::new( Self::build_from_struct_definition(m, def, type_arguments, resolver, depth)?, - )) + ))) } else if let Some(def) = m.find_enum_def(s) { - Ok(A::MoveDatatypeLayout::Enum( + Ok(A::MoveDatatypeLayout::Enum(Box::new( Self::build_from_enum_definition(m, def, type_arguments, resolver, depth)?, - )) + ))) } else { let handle = m.datatype_handle_at(s); let name = m.identifier_at(handle.name); diff --git a/external-crates/move/crates/move-bytecode-utils/src/lib.rs b/external-crates/move/crates/move-bytecode-utils/src/lib.rs index 2d48315cfe8..13861361bb6 100644 --- a/external-crates/move/crates/move-bytecode-utils/src/lib.rs +++ b/external-crates/move/crates/move-bytecode-utils/src/lib.rs @@ -3,17 +3,17 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -pub mod dependency_graph; pub mod layout; pub mod module_cache; -use crate::dependency_graph::DependencyGraph; use move_binary_format::file_format::{CompiledModule, DatatypeHandleIndex, SignatureToken}; use move_core_types::{ account_address::AccountAddress, identifier::IdentStr, language_storage::ModuleId, }; use anyhow::{anyhow, Result}; +use indexmap::IndexMap; +use petgraph::graphmap::DiGraphMap; use std::collections::BTreeMap; /// Set of Move modules indexed by module Id @@ -44,9 +44,37 @@ impl<'a> Modules<'a> { self.iter_modules().into_iter().cloned().collect() } - /// Compute a dependency graph for `self` - pub fn compute_dependency_graph(&self) -> DependencyGraph { - DependencyGraph::new(self.0.values().copied()) + /// Return an iterator over the modules in `self` in topological order--modules with least deps first. + /// Fails with an error if `self` contains circular dependencies. + /// Tolerates missing dependencies. + pub fn compute_topological_order(&self) -> Result> { + let mut module_map = IndexMap::new(); + for m in self.iter_modules() { + if module_map.insert(m.self_id(), m).is_some() { + panic!("Duplicate module found") + } + } + + let mut graph: DiGraphMap = DiGraphMap::new(); + for i in 0..module_map.len() { + graph.add_node(i); + } + + for (i, (_, m)) in module_map.iter().enumerate() { + for dep in m.immediate_dependencies() { + if let Some(j) = module_map.get_index_of(&dep) { + graph.add_edge(i, j, 0); + } + } + } + + match petgraph::algo::toposort(&graph, None) { + Err(_) => panic!("Circular dependency detected"), + Ok(ordered_idxs) => Ok(ordered_idxs + .into_iter() + .map(move |idx| *module_map.get_index(idx).unwrap().1) + .rev()), + } } /// Return the backing map of `self` diff --git a/external-crates/move/crates/move-bytecode-verifier/src/script_signature.rs b/external-crates/move/crates/move-bytecode-verifier/src/script_signature.rs index 43d114faaf8..20d46f225e4 100644 --- a/external-crates/move/crates/move-bytecode-verifier/src/script_signature.rs +++ b/external-crates/move/crates/move-bytecode-verifier/src/script_signature.rs @@ -17,12 +17,12 @@ //! custom signature rules for entrypoints use move_binary_format::{ + IndexKind, errors::{Location, PartialVMError, PartialVMResult, VMResult}, file_format::{ CompiledModule, FunctionDefinitionIndex, SignatureIndex, SignatureToken, TableIndex, }, file_format_common::{VERSION_1, VERSION_5}, - IndexKind, }; use move_core_types::{identifier::IdentStr, vm_status::StatusCode}; diff --git a/external-crates/move/crates/move-cli/Cargo.toml b/external-crates/move/crates/move-cli/Cargo.toml index 1a9adfd1a7f..f08ad78499f 100644 --- a/external-crates/move/crates/move-cli/Cargo.toml +++ b/external-crates/move/crates/move-cli/Cargo.toml @@ -54,5 +54,10 @@ harness = false name = "build_testsuite" harness = false +[[test]] +name = "tracing_testsuite" +harness = false + [features] tiered-gas = ["move-vm-test-utils/tiered-gas"] +tracing = ["move-vm-runtime/tracing"] diff --git a/external-crates/move/crates/move-cli/src/base/new.rs b/external-crates/move/crates/move-cli/src/base/new.rs index 7e46a0ae34e..24fc9d89922 100644 --- a/external-crates/move/crates/move-cli/src/base/new.rs +++ b/external-crates/move/crates/move-cli/src/base/new.rs @@ -2,19 +2,18 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::{fmt::Display, fs::create_dir_all, io::Write, path::Path}; - -use anyhow::anyhow; +use std::{ + fmt::Display, + fs::create_dir_all, + io::{BufRead, BufReader, Write}, + path::Path, +}; + +use anyhow::{self, Context, ensure}; use clap::*; use move_core_types::identifier::Identifier; use move_package::source_package::layout::SourcePackageLayout; -// TODO get a stable path to this stdlib -// pub const MOVE_STDLIB_PACKAGE_NAME: &str = "MoveStdlib"; -// pub const MOVE_STDLIB_PACKAGE_PATH: &str = "{ \ -// git = \"https://github.com/move-language/move.git\", \ -// subdir = \"language/move-stdlib\", rev = \"main\" \ -// }"; pub const MOVE_STDLIB_ADDR_NAME: &str = "std"; pub const MOVE_STDLIB_ADDR_VALUE: &str = "0x1"; @@ -45,17 +44,53 @@ impl New { custom: &str, // anything else that needs to end up being in Move.toml (or empty string) ) -> anyhow::Result<()> { // TODO warn on build config flags - let Self { name } = self; - if !Identifier::is_valid(&name) { - return Err(anyhow!( - "Invalid package name. Package name must start with a lowercase letter \ - and consist only of lowercase letters, numbers, and underscores." - )); - } + ensure!( + Identifier::is_valid(&self.name), + "Invalid package name. Package name must start with a lowercase letter \ + and consist only of lowercase letters, numbers, and underscores." + ); - let path = path.unwrap_or_else(|| Path::new(&name)); + let path = path.unwrap_or_else(|| Path::new(&self.name)); create_dir_all(path.join(SourcePackageLayout::Sources.path()))?; + + self.write_move_toml(path, deps, addrs, custom)?; + self.write_gitignore(path)?; + Ok(()) + } + + /// add `build/*` to `{path}/.gitignore` if it doesn't already have it + fn write_gitignore(&self, path: &Path) -> anyhow::Result<()> { + let gitignore_entry = "build/*"; + + let mut file = std::fs::OpenOptions::new() + .create(true) + .truncate(false) + .read(true) + .write(true) + .open(path.join(".gitignore")) + .context("Unexpected error creating .gitignore")?; + + for line in BufReader::new(&file).lines().map_while(Result::ok) { + if line == gitignore_entry { + return Ok(()); + } + } + + writeln!(file, "{gitignore_entry}")?; + Ok(()) + } + + /// create default `Move.toml` + fn write_move_toml( + &self, + path: &Path, + deps: impl IntoIterator, + addrs: impl IntoIterator, + custom: &str, // anything else that needs to end up being in Move.toml (or empty string) + ) -> anyhow::Result<()> { + let Self { name } = self; + let mut w = std::fs::File::create(path.join(SourcePackageLayout::Manifest.path()))?; writeln!( w, diff --git a/external-crates/move/crates/move-cli/src/base/test.rs b/external-crates/move/crates/move-cli/src/base/test.rs index 98f9f92f94c..5b12a5ff89e 100644 --- a/external-crates/move/crates/move-cli/src/base/test.rs +++ b/external-crates/move/crates/move-cli/src/base/test.rs @@ -2,28 +2,31 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use super::reroot_path; -use crate::NativeFunctionRecord; +// if unix +#[cfg(target_family = "unix")] +use std::os::unix::prelude::ExitStatusExt; +// if windows +#[cfg(target_family = "windows")] +use std::os::windows::process::ExitStatusExt; +use std::{io::Write, path::Path, process::ExitStatus}; + use anyhow::Result; use clap::*; +use move_binary_format::CompiledModule; use move_command_line_common::files::MOVE_COVERAGE_MAP_EXTENSION; use move_compiler::{ + PASS_CFGIR, diagnostics::{self, Diagnostics}, shared::{NumberFormat, NumericalAddress}, - unit_test::{plan_builder::construct_test_plan, TestPlan}, - PASS_CFGIR, + unit_test::{TestPlan, plan_builder::construct_test_plan}, }; -use move_coverage::coverage_map::{output_map_to_file, CoverageMap}; -use move_package::{compilation::build_plan::BuildPlan, BuildConfig}; +use move_coverage::coverage_map::{CoverageMap, output_map_to_file}; +use move_package::{BuildConfig, compilation::build_plan::BuildPlan}; use move_unit_test::UnitTestingConfig; use move_vm_test_utils::gas_schedule::CostTable; -use std::{io::Write, path::Path, process::ExitStatus}; -// if windows -#[cfg(target_family = "windows")] -use std::os::windows::process::ExitStatusExt; -// if unix -#[cfg(target_family = "unix")] -use std::os::unix::prelude::ExitStatusExt; + +use super::reroot_path; +use crate::NativeFunctionRecord; // if not windows nor unix #[cfg(not(any(target_family = "windows", target_family = "unix")))] compile_error!("Unsupported OS, currently we only support windows and unix family"); @@ -72,6 +75,10 @@ pub struct Test { /// (only used with #[random_test]). #[clap(name = "rand-num-iters", long = "rand-num-iters")] pub rand_num_iters: Option, + + // Enable tracing for tests + #[clap(long = "trace-execution", value_name = "PATH")] + pub trace_execution: Option>, } impl Test { @@ -112,6 +119,7 @@ impl Test { compute_coverage: _, seed, rand_num_iters, + trace_execution, } = self; UnitTestingConfig { gas_limit, @@ -122,6 +130,7 @@ impl Test { verbose: verbose_mode, seed, rand_num_iters, + trace_execution, ..UnitTestingConfig::default_with_bound(None) } } @@ -165,8 +174,27 @@ pub fn run_move_unit_tests( }) .collect(); + // Collect all the bytecode modules that are dependencies of the package. We + // need to do this because they're not returned by the compilation result, + // but we need to add them in the VM storage. + let mut bytecode_deps_modules = vec![]; + for pkg in resolution_graph.package_table.values() { + let source_available = !pkg + .get_sources(&resolution_graph.build_options) + .unwrap() + .is_empty(); + if source_available { + continue; + } + for bytes in pkg.get_bytecodes_bytes()? { + let module = CompiledModule::deserialize_with_defaults(&bytes)?; + bytecode_deps_modules.push(module); + } + } + let root_package = resolution_graph.root_package(); let build_plan = BuildPlan::create(resolution_graph)?; + // Compile the package. We need to intercede in the compilation, process being // performed by the Move package system, to first grab the compilation env, // construct the test plan from it, and then save it, before resuming the @@ -177,7 +205,7 @@ pub fn run_move_unit_tests( let (files, comments_and_compiler_res) = compiler.run::().unwrap(); let (_, compiler) = diagnostics::unwrap_or_report_pass_diagnostics(&files, comments_and_compiler_res); - let (mut compiler, cfgir) = compiler.into_ast(); + let (compiler, cfgir) = compiler.into_ast(); let compilation_env = compiler.compilation_env(); let built_test_plan = construct_test_plan(compilation_env, Some(root_package), &cfgir); let mapped_files = compilation_env.mapped_files().clone(); @@ -199,7 +227,7 @@ pub fn run_move_unit_tests( let (test_plan, mapped_files, units) = test_plan.unwrap(); let test_plan = test_plan.unwrap(); let no_tests = test_plan.is_empty(); - let test_plan = TestPlan::new(test_plan, mapped_files, units); + let test_plan = TestPlan::new(test_plan, mapped_files, units, bytecode_deps_modules); let trace_path = pkg_path.join(".trace"); let coverage_map_path = pkg_path diff --git a/external-crates/move/crates/move-cli/src/sandbox/cli.rs b/external-crates/move/crates/move-cli/src/sandbox/cli.rs index 6fe6127eca1..4662cb5ce8c 100644 --- a/external-crates/move/crates/move-cli/src/sandbox/cli.rs +++ b/external-crates/move/crates/move-cli/src/sandbox/cli.rs @@ -11,19 +11,26 @@ use std::{ use anyhow::Result; use clap::Parser; use move_core_types::{ - language_storage::TypeTag, parser, transaction_argument::TransactionArgument, + language_storage::TypeTag, parsing::values::ParsedValue, + transaction_argument::TransactionArgument, }; use move_package::compilation::package_layout::CompiledPackageLayout; use move_vm_test_utils::gas_schedule::CostTable; use crate::{ + DEFAULT_BUILD_DIR, Move, NativeFunctionRecord, sandbox::{ self, - utils::{on_disk_state_view::OnDiskStateView, PackageContext}, + utils::{PackageContext, on_disk_state_view::OnDiskStateView}, }, - Move, NativeFunctionRecord, DEFAULT_BUILD_DIR, }; +fn parse_transaction_argument(s: &str) -> Result { + let x: ParsedValue<()> = ParsedValue::parse(s)?; + let move_value = x.into_concrete_value(&|_| None)?; + TransactionArgument::try_from(move_value) +} + #[derive(Parser)] pub enum SandboxCommand { /// Compile the modules in this package and its dependencies and publish the @@ -82,7 +89,7 @@ pub enum SandboxCommand { /// as the `vector` value [68, 69]). #[clap( long = "args", - value_parser = parser::parse_transaction_argument, + value_parser = parse_transaction_argument, num_args(1..), action = clap::ArgAction::Append, )] @@ -92,7 +99,6 @@ pub enum SandboxCommand { /// kinds expected by `script_file`. #[clap( long = "type-args", - value_parser = parser::parse_type_tag, num_args(1..), action = clap::ArgAction::Append, )] @@ -170,7 +176,6 @@ pub struct StructLayoutOptions { /// Generate layout bindings for `struct` bound to these type arguments. #[clap( long = "type-args", - value_parser = parser::parse_type_tag, requires="struct", action = clap::ArgAction::Append, num_args(1..), diff --git a/external-crates/move/crates/move-cli/src/sandbox/commands/run.rs b/external-crates/move/crates/move-cli/src/sandbox/commands/run.rs index cad066d151f..e3d2f1921f0 100644 --- a/external-crates/move/crates/move-cli/src/sandbox/commands/run.rs +++ b/external-crates/move/crates/move-cli/src/sandbox/commands/run.rs @@ -87,7 +87,7 @@ pub fn run( // script fun. parse module, extract script ID to pass to VM let module = CompiledModule::deserialize_with_defaults(&bytecode) .map_err(|e| anyhow!("Error deserializing module: {:?}", e))?; - move_vm_profiler::gas_profiler_feature_enabled! { + move_vm_profiler::tracing_feature_enabled! { use move_vm_profiler::GasProfiler; use move_vm_types::gas::GasMeter; diff --git a/external-crates/move/crates/move-cli/src/sandbox/utils/mod.rs b/external-crates/move/crates/move-cli/src/sandbox/utils/mod.rs index 7cd75ecdb80..79981af743f 100644 --- a/external-crates/move/crates/move-cli/src/sandbox/utils/mod.rs +++ b/external-crates/move/crates/move-cli/src/sandbox/utils/mod.rs @@ -169,13 +169,9 @@ pub(crate) fn explain_publish_error( let new_api = normalized::Module::new(module); if (Compatibility { - check_datatype_and_pub_function_linking: false, check_datatype_layout: true, - check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, }) .check(&old_api, &new_api) .is_err() @@ -188,13 +184,9 @@ pub(crate) fn explain_publish_error( module_id ) } else if (Compatibility { - check_datatype_and_pub_function_linking: true, check_datatype_layout: false, - check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: AbilitySet::EMPTY, - disallow_change_datatype_type_params: false, - disallow_new_variants: false, }) .check(&old_api, &new_api) .is_err() diff --git a/external-crates/move/crates/move-cli/tests/build_tests/build_with_dep_warnings/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/build_with_dep_warnings/args.exp index df911284b5b..34931c7f3eb 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/build_with_dep_warnings/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/build_with_dep_warnings/args.exp @@ -5,16 +5,14 @@ Command `disassemble --package Test --name m`: // Move bytecode v6 module 43.m { - - - public aborts() { B0: 0: LdU64(42) 1: Abort - } + } + Command `build -p dep`: BUILDING SomeDep warning[W09002]: unused variable diff --git a/external-crates/move/crates/move-cli/tests/build_tests/build_with_warnings/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/build_with_warnings/args.exp index 290e95807fe..062efbcca3c 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/build_with_warnings/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/build_with_warnings/args.exp @@ -12,16 +12,14 @@ Command `disassemble --package Test --name m`: // Move bytecode v6 module 42.m { - - - public foo(x#0#0: u64): u64 { B0: 0: LdU64(2) 1: Ret - } + } + warning[W09002]: unused variable ┌─ ./sources/m.move:2:16 │ diff --git a/external-crates/move/crates/move-cli/tests/build_tests/canonicalize_module/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/canonicalize_module/args.exp index 6dcffcce259..664f6ad4328 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/canonicalize_module/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/canonicalize_module/args.exp @@ -6,16 +6,14 @@ use 0000000000000000000000000000000000000000000000000000000000000003::d; use 0000000000000000000000000000000000000000000000000000000000000001::a; use 0000000000000000000000000000000000000000000000000000000000000004::e; - struct B { x: u64 } + struct A { b: vector } - - public g(): u64 { B0: 0: Call a::f(): u64 @@ -25,8 +23,8 @@ B0: 4: Call e::g(B): u64 5: Add 6: Ret - } + public f(): u64 { B0: 0: Call d::f(): u64 @@ -34,10 +32,11 @@ B0: 2: Call e::f(A): u64 3: Add 4: Ret - } + } + CompiledModule { version: 6, self_module_handle_idx: ModuleHandleIndex(0), diff --git a/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/bar/sources/Bar.move b/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/bar/sources/Bar.move index 7905cb39170..c228f2fc352 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/bar/sources/Bar.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/bar/sources/Bar.move @@ -1,5 +1,5 @@ -module 0x1::Bar { - use 0x1::Foo; +module 0x6::Bar { + use 0x6::Foo; public bar() { Foo::foo(); diff --git a/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/sources/Foo.move index c094de36af5..e83504b5706 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/circular_dependencies/sources/Foo.move @@ -1,5 +1,5 @@ -module 0x1::Foo { - use 0x1::Bar; +module 0x6::Foo { + use 0x6::Bar; public foo() { Bar::bar(); diff --git a/external-crates/move/crates/move-cli/tests/build_tests/disassemble_module/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/disassemble_module/args.exp index 236f9bd53fc..f94c133be93 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/disassemble_module/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/disassemble_module/args.exp @@ -3,38 +3,37 @@ BUILDING Test Command `disassemble --package Test --name m`: // Move bytecode v6 module 42.m { + struct Zs { dummy_field: bool } + struct As { dummy_field: bool } - - public zf(): u64 { B0: 0: LdConst[0](u64: 1) 1: Ret - } + public af(): u32 { B0: 0: LdConst[1](u32: 0) 1: Ret - } + public sf(): vector { B0: 0: LdConst[2](vector: "Thi..) 1: Ret - } + public nf(): vector { B0: 0: LdConst[3](vector: 0401..) 1: Ret - } Constants [ @@ -44,3 +43,4 @@ Constants [ 3 => vector: 040100020003000400 ] } + diff --git a/external-crates/move/crates/move-cli/tests/build_tests/empty_module_no_deps/sources/A.move b/external-crates/move/crates/move-cli/tests/build_tests/empty_module_no_deps/sources/A.move index edb25f3d737..c98e8a41e7d 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/empty_module_no_deps/sources/A.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/empty_module_no_deps/sources/A.move @@ -1 +1 @@ -module 0x1::M {} +module 0x6::M {} diff --git a/external-crates/move/crates/move-cli/tests/build_tests/include_exclude_stdlib/sources/UseSigner.move b/external-crates/move/crates/move-cli/tests/build_tests/include_exclude_stdlib/sources/UseSigner.move index 471e9ac62e9..d6a4b951a63 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/include_exclude_stdlib/sources/UseSigner.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/include_exclude_stdlib/sources/UseSigner.move @@ -1,4 +1,4 @@ -module 0x1::Example { +module 0x6::Example { use std::address; public fun f(): u64 { diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration/Move.toml.expected b/external-crates/move/crates/move-cli/tests/build_tests/migration/Move.toml.expected index 763008694ba..bc66fe9c1c6 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration/Move.toml.expected +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration/Move.toml.expected @@ -2,7 +2,7 @@ [package] name = "A" -edition = "2024.beta" +edition = "2024" # this is a comment [addresses] diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration/args.exp index b773c33d7a6..0321e10538a 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/Move.toml.expected b/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/Move.toml.expected index 763008694ba..bc66fe9c1c6 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/Move.toml.expected +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/Move.toml.expected @@ -2,7 +2,7 @@ [package] name = "A" -edition = "2024.beta" +edition = "2024" # this is a comment [addresses] diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/args.exp index 84fce9e643b..5889f6db437 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_address_block/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_edition_not_allowed/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_edition_not_allowed/args.exp index ec55e65281c..44e0a0302cb 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_edition_not_allowed/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_edition_not_allowed/args.exp @@ -2,4 +2,4 @@ Command `build`: Error: Error parsing '[package]' section of manifest Caused by: - Invalid 'edition'. Unsupported edition "2024.migration". Current supported editions include: "legacy", "2024.alpha", and "2024.beta" + Invalid 'edition'. Unsupported edition "2024.migration". Current supported editions include: "legacy", "2024.alpha", "2024.beta", and "2024" diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/Move.toml.expected b/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/Move.toml.expected index 763008694ba..bc66fe9c1c6 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/Move.toml.expected +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/Move.toml.expected @@ -2,7 +2,7 @@ [package] name = "A" -edition = "2024.beta" +edition = "2024" # this is a comment [addresses] diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/args.exp index a43b2424021..66b6ffd31ff 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_multiline/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_names/Move.toml.expected b/external-crates/move/crates/move-cli/tests/build_tests/migration_names/Move.toml.expected index 763008694ba..bc66fe9c1c6 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_names/Move.toml.expected +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_names/Move.toml.expected @@ -2,7 +2,7 @@ [package] name = "A" -edition = "2024.beta" +edition = "2024" # this is a comment [addresses] diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_names/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_names/args.exp index d338c406bd2..97f0031fbd0 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_names/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_names/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/Move.toml.expected b/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/Move.toml.expected index 763008694ba..bc66fe9c1c6 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/Move.toml.expected +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/Move.toml.expected @@ -2,7 +2,7 @@ [package] name = "A" -edition = "2024.beta" +edition = "2024" # this is a comment [addresses] diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/args.exp index 86ab1811025..84c621a6763 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_names_mut_allowed/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/Move.toml.expected b/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/Move.toml.expected index c64e0b3b7f0..e474f7dbce4 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/Move.toml.expected +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/Move.toml.expected @@ -2,7 +2,7 @@ [package] name = "migration" -edition = "2024.beta" +edition = "2024" # this is a comment [addresses] diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/args.exp index 902574c1132..47b694771c8 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_paths/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/migration_with_blocking_errors/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/migration_with_blocking_errors/args.exp index 9815d2ae1c8..c0cb4b373d7 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/migration_with_blocking_errors/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/migration_with_blocking_errors/args.exp @@ -3,7 +3,7 @@ Package toml does not specify an edition. As of 2024, Move requires all packages Please select one of the following editions: -1) 2024.beta +1) 2024 2) legacy Selection (default=1): diff --git a/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.exp new file mode 100644 index 00000000000..d8d7505e487 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.exp @@ -0,0 +1,8 @@ +Command `new -p package example`: +External Command `cat package/.gitignore`: +existing_ignore +build/* +External Command `ls -A package`: +.gitignore +Move.toml +sources diff --git a/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.txt b/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.txt new file mode 100644 index 00000000000..4f78cafe683 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/args.txt @@ -0,0 +1,4 @@ +# if `.gitignore` exists, everything should be created and .gitignore should be extended +new -p package example +>cat package/.gitignore +>ls -A package diff --git a/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/package/.gitignore b/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/package/.gitignore new file mode 100644 index 00000000000..69817b3665c --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/build_tests/new_clobber/gitignore_exists/package/.gitignore @@ -0,0 +1 @@ +existing_ignore diff --git a/external-crates/move/crates/move-cli/tests/build_tests/simple_new/args.exp b/external-crates/move/crates/move-cli/tests/build_tests/new_simple/args.exp similarity index 96% rename from external-crates/move/crates/move-cli/tests/build_tests/simple_new/args.exp rename to external-crates/move/crates/move-cli/tests/build_tests/new_simple/args.exp index d46c9a32f08..5e3954b528e 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/simple_new/args.exp +++ b/external-crates/move/crates/move-cli/tests/build_tests/new_simple/args.exp @@ -35,6 +35,8 @@ edition = "2024.beta" # edition = "legacy" to use legacy (pre-2024) Move # and `--dev` modes. # alice = "0xB0B" +External Command `cat P1/.gitignore`: +build/* Command `new P2 -p other_dir`: External Command `cat other_dir/Move.toml`: [package] @@ -72,3 +74,5 @@ edition = "2024.beta" # edition = "legacy" to use legacy (pre-2024) Move # and `--dev` modes. # alice = "0xB0B" +External Command `cat other_dir/.gitignore`: +build/* diff --git a/external-crates/move/crates/move-cli/tests/build_tests/simple_new/args.txt b/external-crates/move/crates/move-cli/tests/build_tests/new_simple/args.txt similarity index 60% rename from external-crates/move/crates/move-cli/tests/build_tests/simple_new/args.txt rename to external-crates/move/crates/move-cli/tests/build_tests/new_simple/args.txt index f7b7ec18ae0..045be5bf2a4 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/simple_new/args.txt +++ b/external-crates/move/crates/move-cli/tests/build_tests/new_simple/args.txt @@ -1,5 +1,7 @@ new P1 > cat P1/Move.toml +> cat P1/.gitignore new P2 -p other_dir > cat other_dir/Move.toml +> cat other_dir/.gitignore diff --git a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_adding_new_source/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_adding_new_source/sources/Foo.move index f358fe72bea..20084ca68a2 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_adding_new_source/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_adding_new_source/sources/Foo.move @@ -1 +1 @@ -module 0x1::Foo {} +module 0x6::Foo {} diff --git a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_deleting_output_artifact/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_deleting_output_artifact/sources/Foo.move index f358fe72bea..20084ca68a2 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_deleting_output_artifact/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_deleting_output_artifact/sources/Foo.move @@ -1 +1 @@ -module 0x1::Foo {} +module 0x6::Foo {} diff --git a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_manifest/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_manifest/sources/Foo.move index f358fe72bea..20084ca68a2 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_manifest/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_manifest/sources/Foo.move @@ -1 +1 @@ -module 0x1::Foo {} +module 0x6::Foo {} diff --git a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_source/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_source/sources/Foo.move index f358fe72bea..20084ca68a2 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_source/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_after_touching_source/sources/Foo.move @@ -1 +1 @@ -module 0x1::Foo {} +module 0x6::Foo {} diff --git a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_no_modification/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_no_modification/sources/Foo.move index f358fe72bea..20084ca68a2 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/rebuild_no_modification/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/rebuild_no_modification/sources/Foo.move @@ -1 +1 @@ -module 0x1::Foo {} +module 0x6::Foo {} diff --git a/external-crates/move/crates/move-cli/tests/build_tests/simple_build_with_docs/sources/Foo.move b/external-crates/move/crates/move-cli/tests/build_tests/simple_build_with_docs/sources/Foo.move index 6af36548434..534279a5f05 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/simple_build_with_docs/sources/Foo.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/simple_build_with_docs/sources/Foo.move @@ -1,4 +1,4 @@ -module 0x1::Foo { +module 0x6::Foo { /// Test documentation comment public fun foo() { } diff --git a/external-crates/move/crates/move-cli/tests/build_tests/unbound_dependency/sources/A.move b/external-crates/move/crates/move-cli/tests/build_tests/unbound_dependency/sources/A.move index 4fe8b348357..aec3bb0d6ca 100644 --- a/external-crates/move/crates/move-cli/tests/build_tests/unbound_dependency/sources/A.move +++ b/external-crates/move/crates/move-cli/tests/build_tests/unbound_dependency/sources/A.move @@ -1 +1 @@ -module 0x1::A {} +module 0x6::A {} diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/Move.toml b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/Move.toml new file mode 100644 index 00000000000..a6ad126c763 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/Move.toml @@ -0,0 +1,8 @@ +[package] +name = "Bar" + +[addresses] +B = "0x2" + +[dependencies] +Foo = { local = "../C" } diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/sources/Bar.move b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/sources/Bar.move new file mode 100644 index 00000000000..5074f2e1b44 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/B/sources/Bar.move @@ -0,0 +1,8 @@ +module B::Bar { + use C::Foo; + + public fun foo(): u64 { + Foo::bar() + } + +} diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/Move.toml b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/Move.toml new file mode 100644 index 00000000000..db95e4a84a7 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/Move.toml @@ -0,0 +1,5 @@ +[package] +name = "Foo" + +[addresses] +C = "0x3" diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/sources/Foo.move b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/sources/Foo.move new file mode 100644 index 00000000000..4313b3ed6a1 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/C/sources/Foo.move @@ -0,0 +1,5 @@ +module C::Foo { + public fun bar(): u64 { + 1 + } +} diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/Move.toml b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/Move.toml new file mode 100644 index 00000000000..156d5498096 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/Move.toml @@ -0,0 +1,15 @@ +[package] +name = "A" + +[addresses] +A = "0x2" + +[dependencies] +Bar = { local = "./B" } +Foo = { local = "./C" } + +[dev-addresses] +std = "0x1" + +[dev-dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.exp b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.exp new file mode 100644 index 00000000000..612ce6d4f66 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.exp @@ -0,0 +1,17 @@ +Command `build -v -p ./C`: +BUILDING Foo +External Command `mv ./C/sources/Foo.move ./C/sources/Foo.move_old`: +External Command `rm -rf ./C/build/Foo/sources`: +Command `build -v -p ./B`: +INCLUDING DEPENDENCY Foo +BUILDING Bar +External Command `mv ./B/sources/Bar.move ./B/sources/Bar.move_old`: +External Command `rm -rf ./B/build/Bar/sources`: +Command `test`: +INCLUDING DEPENDENCY Bar +INCLUDING DEPENDENCY Foo +INCLUDING DEPENDENCY MoveStdlib +BUILDING A +Running Move unit tests +[ PASS ] 0x2::A::foo_test +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.txt b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.txt new file mode 100644 index 00000000000..09998befbcf --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/args.txt @@ -0,0 +1,7 @@ +build -v -p ./C +> mv ./C/sources/Foo.move ./C/sources/Foo.move_old +> rm -rf ./C/build/Foo/sources +build -v -p ./B +> mv ./B/sources/Bar.move ./B/sources/Bar.move_old +> rm -rf ./B/build/Bar/sources +test diff --git a/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/sources/A.move b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/sources/A.move new file mode 100644 index 00000000000..63e2dec3673 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/move_unit_tests/bytecode_deps/sources/A.move @@ -0,0 +1,13 @@ +module A::A { + use B::Bar; + use C::Foo; + + public fun foo(): u64 { + Bar::foo() + Foo::bar() + } + + #[test] + fun foo_test() { + Bar::foo() + Foo::bar(); + } +} diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.exp b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.exp index 7c4520eea83..a2733f9fabd 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.exp +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.exp @@ -1,7 +1,7 @@ Command `sandbox publish`: -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args u64`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args u64`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M2::C": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C": STRUCT: - t: U64 - b: BOOL @@ -16,9 +16,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args address`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args address`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M2::C": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C": STRUCT: - t: TYPENAME: AccountAddress @@ -34,9 +34,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args vector`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args vector`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M2::C>": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C>": STRUCT: - t: BYTES - b: BOOL @@ -51,16 +51,16 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct B --type-args bool`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct B --type-args bool`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M1::B": +"0000000000000000000000000000000000000000000000000000000000000006::M1::B": STRUCT: - a: TYPENAME: AccountAddress - c: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M2::C" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M2::C" - t: BOOL -"0000000000000000000000000000000000000000000000000000000000000001::M2::C": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C": STRUCT: - t: BOOL - b: BOOL @@ -75,7 +75,7 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct B --type-args bool --shallow`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct B --type-args bool --shallow`: --- AccountAddress: NEWTYPESTRUCT: @@ -88,29 +88,29 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args 0x1::M1::S`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args 0x6::M1::S`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M1::A<0000000000000000000000000000000000000000000000000000000000000001::M1::S>": +"0000000000000000000000000000000000000000000000000000000000000006::M1::A<0000000000000000000000000000000000000000000000000000000000000006::M1::S>": STRUCT: - f: U64 - v: BYTES - b: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::B<0000000000000000000000000000000000000000000000000000000000000001::M1::S>" -"0000000000000000000000000000000000000000000000000000000000000001::M1::B<0000000000000000000000000000000000000000000000000000000000000001::M1::S>": + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::B<0000000000000000000000000000000000000000000000000000000000000006::M1::S>" +"0000000000000000000000000000000000000000000000000000000000000006::M1::B<0000000000000000000000000000000000000000000000000000000000000006::M1::S>": STRUCT: - a: TYPENAME: AccountAddress - c: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M2::C<0000000000000000000000000000000000000000000000000000000000000001::M1::S>" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M2::C<0000000000000000000000000000000000000000000000000000000000000006::M1::S>" - t: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::S" -"0000000000000000000000000000000000000000000000000000000000000001::M1::S": + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::S" +"0000000000000000000000000000000000000000000000000000000000000006::M1::S": STRUCT: - t: U64 -"0000000000000000000000000000000000000000000000000000000000000001::M2::C<0000000000000000000000000000000000000000000000000000000000000001::M1::S>": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C<0000000000000000000000000000000000000000000000000000000000000006::M1::S>": STRUCT: - t: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::S" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::S" - b: BOOL AccountAddress: NEWTYPESTRUCT: @@ -123,31 +123,31 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args vector<0x1::M1::S>`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args vector<0x6::M1::S>`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M1::A>>": +"0000000000000000000000000000000000000000000000000000000000000006::M1::A>>": STRUCT: - f: U64 - v: BYTES - b: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::B>>" -"0000000000000000000000000000000000000000000000000000000000000001::M1::B>>": + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::B>>" +"0000000000000000000000000000000000000000000000000000000000000006::M1::B>>": STRUCT: - a: TYPENAME: AccountAddress - c: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M2::C>>" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M2::C>>" - t: SEQ: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::S" -"0000000000000000000000000000000000000000000000000000000000000001::M1::S": + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::S" +"0000000000000000000000000000000000000000000000000000000000000006::M1::S": STRUCT: - t: U64 -"0000000000000000000000000000000000000000000000000000000000000001::M2::C>>": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C>>": STRUCT: - t: SEQ: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::S" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::S" - b: BOOL AccountAddress: NEWTYPESTRUCT: @@ -160,7 +160,7 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args 0x1::M1::S --shallow`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args 0x6::M1::S --shallow`: --- AccountAddress: NEWTYPESTRUCT: @@ -173,7 +173,7 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args vector<0x1::M1::S> --shallow`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args vector<0x6::M1::S> --shallow`: --- AccountAddress: NEWTYPESTRUCT: @@ -186,14 +186,14 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args 0x1::M2::C`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args 0x6::M2::C`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M2::C<0000000000000000000000000000000000000000000000000000000000000001::M2::C>": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C<0000000000000000000000000000000000000000000000000000000000000006::M2::C>": STRUCT: - t: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M2::C" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M2::C" - b: BOOL -"0000000000000000000000000000000000000000000000000000000000000001::M2::C": +"0000000000000000000000000000000000000000000000000000000000000006::M2::C": STRUCT: - t: U64 - b: BOOL @@ -208,14 +208,14 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct G`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct G`: --- -"0000000000000000000000000000000000000000000000000000000000000001::M1::G": +"0000000000000000000000000000000000000000000000000000000000000006::M1::G": STRUCT: - x: U64 - s: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::M1::S" -"0000000000000000000000000000000000000000000000000000000000000001::M1::S": + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::M1::S" +"0000000000000000000000000000000000000000000000000000000000000006::M1::S": STRUCT: - t: BOOL AccountAddress: @@ -229,9 +229,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct A --type-args bool --ignore-phantom-types`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct A --type-args bool --ignore-phantom-types`: --- -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::A": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::A": STRUCT: - dummy_field: BOOL AccountAddress: @@ -245,9 +245,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct A --type-args u64 --ignore-phantom-types`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct A --type-args u64 --ignore-phantom-types`: --- -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::A": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::A": STRUCT: - dummy_field: BOOL AccountAddress: @@ -261,9 +261,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct B --type-args bool u8 --ignore-phantom-types`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct B --type-args bool u8 --ignore-phantom-types`: --- -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::B": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::B": STRUCT: - dummy_field: BOOL AccountAddress: @@ -277,20 +277,20 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct C --type-args u8 u64 u128 --ignore-phantom-types`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct C --type-args u8 u64 u128 --ignore-phantom-types`: --- -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::A": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::A": STRUCT: - dummy_field: BOOL -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::B": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::B": STRUCT: - dummy_field: BOOL -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::C": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::C": STRUCT: - a: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::phantoms::A" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::phantoms::A" - b: - TYPENAME: "0000000000000000000000000000000000000000000000000000000000000001::phantoms::B" + TYPENAME: "0000000000000000000000000000000000000000000000000000000000000006::phantoms::B" AccountAddress: NEWTYPESTRUCT: TUPLEARRAY: @@ -302,9 +302,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct D --type-args bool u64 --ignore-phantom-types`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct D --type-args bool u64 --ignore-phantom-types`: --- -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::D": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::D": STRUCT: - v: SEQ: U64 @@ -319,9 +319,9 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --ignore-phantom-types`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --ignore-phantom-types`: --- -"0000000000000000000000000000000000000000000000000000000000000001::phantoms::E": +"0000000000000000000000000000000000000000000000000000000000000006::phantoms::E": STRUCT: - v1: SEQ: BOOL @@ -338,7 +338,7 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses`: --- AccountAddress: NEWTYPESTRUCT: @@ -357,9 +357,9 @@ Signer: - v2: SEQ: U128 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --separator __`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --separator __`: --- -0000000000000000000000000000000000000000000000000000000000000001__phantoms__E__bool__u64__u128__: +0000000000000000000000000000000000000000000000000000000000000006__phantoms__E__bool__u64__u128__: STRUCT: - v1: SEQ: BOOL @@ -376,7 +376,7 @@ Signer: CONTENT: U8 SIZE: 32 -Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses --separator __`: +Command `sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses --separator __`: --- AccountAddress: NEWTYPESTRUCT: diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.txt b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.txt index 454f5ad6cc9..d66ce0bf87b 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.txt +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/args.txt @@ -1,39 +1,39 @@ sandbox publish # basics -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args u64 -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args address -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args vector +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args u64 +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args address +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args vector # across modules deep -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct B --type-args bool +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct B --type-args bool # across modules shallow -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct B --type-args bool --shallow +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct B --type-args bool --shallow # with fancy type parameters -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args 0x1::M1::S -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args vector<0x1::M1::S> +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args 0x6::M1::S +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args vector<0x6::M1::S> # same thing, but shallow -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args 0x1::M1::S --shallow -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct A --type-args vector<0x1::M1::S> --shallow +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args 0x6::M1::S --shallow +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct A --type-args vector<0x6::M1::S> --shallow # recursive type definition -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M2.mv --struct C --type-args 0x1::M2::C +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M2.mv --struct C --type-args 0x6::M2::C # without --type-args -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/M1.mv --struct G +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/M1.mv --struct G # phantom type arguments should not appear in struct keys when --ignore-phantom-types is set -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct A --type-args bool --ignore-phantom-types -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct A --type-args u64 --ignore-phantom-types -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct B --type-args bool u8 --ignore-phantom-types -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct C --type-args u8 u64 u128 --ignore-phantom-types -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct D --type-args bool u64 --ignore-phantom-types -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --ignore-phantom-types +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct A --type-args bool --ignore-phantom-types +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct A --type-args u64 --ignore-phantom-types +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct B --type-args bool u8 --ignore-phantom-types +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct C --type-args u8 u64 u128 --ignore-phantom-types +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct D --type-args bool u64 --ignore-phantom-types +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --ignore-phantom-types # test config options: address omission + separators -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --separator __ +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --separator __ -sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000001/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses --separator __ +sandbox generate struct-layouts --module storage/0x0000000000000000000000000000000000000000000000000000000000000006/modules/phantoms.mv --struct E --type-args bool u64 u128 --omit-addresses --separator __ diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M1.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M1.move index c171a80fb3c..85d0f874856 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M1.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M1.move @@ -1,6 +1,6 @@ #[allow(unused_field)] -module 0x1::M1 { - use 0x1::M2::C; +module 0x6::M1 { + use 0x6::M2::C; public struct A { f: u64, v: vector, b: B } diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M2.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M2.move index f3cc297417d..ad9a4b73a1f 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M2.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/M2.move @@ -1,4 +1,4 @@ -module 0x1::M2 { +module 0x6::M2 { #[allow(unused_field)] public struct C { t: T, b: bool } diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/phantoms.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/phantoms.move index 6c177ab6c64..84ddd1b45ca 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/phantoms.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/generate_struct_layout/sources/phantoms.move @@ -1,5 +1,5 @@ #[allow(unused_field)] -module 0x1::phantoms { +module 0x6::phantoms { public struct A {} public struct B {} diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/module_disassemble/args.exp b/external-crates/move/crates/move-cli/tests/sandbox_tests/module_disassemble/args.exp index e25ac29fb24..8d13230e4b9 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/module_disassemble/args.exp +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/module_disassemble/args.exp @@ -8,13 +8,10 @@ Command `sandbox view storage/0x000000000000000000000000000000000000000000000000 module a.M1 { use 0000000000000000000000000000000000000000000000000000000000000001::vector; - struct S { i: u64 } - - public foo(Arg0: u64): vector { B0: 0: Call bar(): u64 @@ -24,15 +21,16 @@ B0: 4: Add 5: Call vector::singleton(u64): vector 6: Ret - } + public bar(): u64 { B0: 0: LdU64(7) 1: Ret - } + } + Command `sandbox view storage/0x000000000000000000000000000000000000000000000000000000000000000c/modules/M.mv`: // Move bytecode v6 module c.M { @@ -41,23 +39,18 @@ use 000000000000000000000000000000000000000000000000000000000000000a::M as 1M; use 000000000000000000000000000000000000000000000000000000000000000b::B; use 000000000000000000000000000000000000000000000000000000000000000b::M as 2M; - - - - - public f(): u64 { B0: 0: LdU64(7) 1: Ret - } + public g(): u64 { B0: 0: LdU64(12) 1: Ret - } + public call_f(): u64 { B0: 0: Call f(): u64 @@ -66,8 +59,8 @@ B0: 3: Call 2M::f(): u64 4: Add 5: Ret - } + public call_g(): u64 { B0: 0: Call g(): u64 @@ -76,6 +69,7 @@ B0: 3: Call B::g(): u64 4: Add 5: Ret - } + } + diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/module_publish_view/args.exp b/external-crates/move/crates/move-cli/tests/sandbox_tests/module_publish_view/args.exp index 1dc0911f02f..2cb5997ce66 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/module_publish_view/args.exp +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/module_publish_view/args.exp @@ -5,17 +5,17 @@ Wrote 152 bytes of module ID's and code Command `sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000042/modules/Module.mv`: // Move bytecode v6 module 42.Module { + struct S { i: u64 } - - public foo(Arg0: u64): S { B0: 0: MoveLoc[0](Arg0: u64) 1: Pack[0](S) 2: Ret - } + } + diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.exp b/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.exp index becab0ef703..e15b263456e 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.exp +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.exp @@ -1,41 +1,35 @@ Command `sandbox publish --bundle --override-ordering B -v`: Found 2 modules -Invalid multi-module publishing: VMError with status LINKER_ERROR at location UNDEFINED and message Cannot find ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000002, name: Identifier("A") } in data cache +Invalid multi-module publishing: VMError with status LINKER_ERROR at location UNDEFINED and message Cannot find ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000007, name: Identifier("A") } in data cache Command `sandbox publish --bundle --override-ordering B --override-ordering A -v`: Found 2 modules -Invalid multi-module publishing: VMError with status LINKER_ERROR at location UNDEFINED and message Cannot find ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000002, name: Identifier("A") } in data cache +Invalid multi-module publishing: VMError with status LINKER_ERROR at location UNDEFINED and message Cannot find ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000007, name: Identifier("A") } in data cache Command `sandbox publish --bundle --override-ordering A --override-ordering B -v`: Found 2 modules -Publishing a new module 0000000000000000000000000000000000000000000000000000000000000002::A (wrote 121 bytes) -Publishing a new module 0000000000000000000000000000000000000000000000000000000000000002::B (wrote 129 bytes) +Publishing a new module 0000000000000000000000000000000000000000000000000000000000000007::A (wrote 121 bytes) +Publishing a new module 0000000000000000000000000000000000000000000000000000000000000007::B (wrote 129 bytes) Wrote 250 bytes of module ID's and code -Command `sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000002/modules/A.mv`: +Command `sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000007/modules/A.mv`: // Move bytecode v6 -module 2.A { - - - +module 7.A { public(friend) foo() { B0: 0: Ret - } -} -Command `sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000002/modules/B.mv`: -// Move bytecode v6 -module 2.B { -use 0000000000000000000000000000000000000000000000000000000000000002::A; - - - +} +Command `sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000007/modules/B.mv`: +// Move bytecode v6 +module 7.B { +use 0000000000000000000000000000000000000000000000000000000000000007::A; bar() { B0: 0: Call A::foo() 1: Ret - } + } + diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.txt b/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.txt index d4efa790725..4f3882e513e 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.txt +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/args.txt @@ -7,5 +7,5 @@ sandbox publish --bundle --override-ordering B --override-ordering A -v # expect success: this is the correct order of publishing A and B # with friend relationship sandbox publish --bundle --override-ordering A --override-ordering B -v -sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000002/modules/A.mv -sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000002/modules/B.mv +sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000007/modules/A.mv +sandbox view storage/0x0000000000000000000000000000000000000000000000000000000000000007/modules/B.mv diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/sources/GoodFriends.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/sources/GoodFriends.move index 74c3ff22d4e..d85292a141d 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/sources/GoodFriends.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/multi_module_publish/sources/GoodFriends.move @@ -1,8 +1,8 @@ -module 0x2::A { +module 0x7::A { public(package) fun foo() {} } -module 0x2::B { +module 0x7::B { #[allow(unused_function)] - fun bar() { 0x2::A::foo() } + fun bar() { 0x7::A::foo() } } diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/package_basics/args.exp b/external-crates/move/crates/move-cli/tests/sandbox_tests/package_basics/args.exp index f036924fe82..5c1a00a7345 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/package_basics/args.exp +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/package_basics/args.exp @@ -51,46 +51,41 @@ Command `coverage bytecode --module AModule`: // Move bytecode v6 module 1.AModule { - - - public double_except_three(x#0#0: u64): u64 { B0: -[6] 0: CopyLoc[0](x#0#0: u64) -[6] 1: LdU64(3) -[6] 2: Neq -[6] 3: BrFalse(5) +[6] 0: CopyLoc[0](x#0#0: u64) +[6] 1: LdU64(3) +[6] 2: Neq +[6] 3: BrFalse(5) B1: -[4] 4: Branch(7) +[4] 4: Branch(7) B2: -[2] 5: LdConst[0](u64: 0) -[2] 6: Abort +[2] 5: LdConst[0](u64: 0) +[2] 6: Abort B3: -[4] 7: CopyLoc[0](x#0#0: u64) -[4] 8: MoveLoc[0](x#0#0: u64) -[4] 9: Mul -[4] 10: Ret - +[4] 7: CopyLoc[0](x#0#0: u64) +[4] 8: MoveLoc[0](x#0#0: u64) +[4] 9: Mul +[4] 10: Ret } Constants [ 0 => u64: 0 ] } + Command `disassemble --package MoveStdlib --name address`: // Move bytecode v6 module 1.address { - - - public length(): u64 { B0: 0: LdU64(32) 1: Ret - } + } + Command `info`: PackageBasics ├── std:0x1 diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/args.exp b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/args.exp index a298edc54f5..2c5f4a883d8 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/args.exp +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/args.exp @@ -18,7 +18,7 @@ Call Stack: [2] - - [1] 0000000000000000000000000000000000000000000000000000000000000002::N::foo + [1] 0000000000000000000000000000000000000000000000000000000000000007::N::foo Code: [2] MutBorrowLoc(0) @@ -35,7 +35,7 @@ Call Stack: [2] - - [2] 0000000000000000000000000000000000000000000000000000000000000002::M::sum + [2] 0000000000000000000000000000000000000000000000000000000000000007::M::sum Code: [9] MoveLoc(0) @@ -51,7 +51,7 @@ Call Stack: [1] - - [3] 0000000000000000000000000000000000000000000000000000000000000002::M::sum + [3] 0000000000000000000000000000000000000000000000000000000000000007::M::sum Code: [9] MoveLoc(0) @@ -67,7 +67,7 @@ Call Stack: [1] - - [4] 0000000000000000000000000000000000000000000000000000000000000002::M::sum + [4] 0000000000000000000000000000000000000000000000000000000000000007::M::sum Code: [9] MoveLoc(0) @@ -106,7 +106,7 @@ Call Stack: [2] 10 - [1] 0000000000000000000000000000000000000000000000000000000000000002::N::foo + [1] 0000000000000000000000000000000000000000000000000000000000000007::N::foo Code: [2] MutBorrowLoc(0) @@ -123,7 +123,7 @@ Call Stack: [2] - - [2] 0000000000000000000000000000000000000000000000000000000000000002::M::sum + [2] 0000000000000000000000000000000000000000000000000000000000000007::M::sum Code: [9] MoveLoc(0) @@ -139,7 +139,7 @@ Call Stack: [1] - - [3] 0000000000000000000000000000000000000000000000000000000000000002::M::sum + [3] 0000000000000000000000000000000000000000000000000000000000000007::M::sum Code: [9] MoveLoc(0) @@ -155,7 +155,7 @@ Call Stack: [1] - - [4] 0000000000000000000000000000000000000000000000000000000000000002::M::sum + [4] 0000000000000000000000000000000000000000000000000000000000000007::M::sum Code: [9] MoveLoc(0) diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/M.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/M.move index 978efd65b36..9978b965a73 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/M.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/M.move @@ -1,4 +1,4 @@ -module 0x2::M { +module 0x7::M { use std::debug; public fun sum(n: u64): u64 { diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/N.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/N.move index 08e2467602b..ca19dbab422 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/N.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/N.move @@ -1,6 +1,6 @@ #[allow(unused_type_parameter, unused_mut_ref)] -module 0x2::N { - use 0x2::M; +module 0x7::N { + use 0x7::M; public fun foo(): u64 { let mut x = 3; diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/print_stack_trace.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/print_stack_trace.move index cda19d634c1..435891160af 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/print_stack_trace.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/print_stack_trace/sources/print_stack_trace.move @@ -1,6 +1,6 @@ module 0x42::print_stack_trace { use std::debug; - use 0x2::N; + use 0x7::N; #[allow(unused_mut_ref)] entry fun print_stack_trace() { diff --git a/external-crates/move/crates/move-cli/tests/sandbox_tests/random_test_flag_correctness/sources/m.move b/external-crates/move/crates/move-cli/tests/sandbox_tests/random_test_flag_correctness/sources/m.move index 56aa8549c35..8e3b42fcd79 100644 --- a/external-crates/move/crates/move-cli/tests/sandbox_tests/random_test_flag_correctness/sources/m.move +++ b/external-crates/move/crates/move-cli/tests/sandbox_tests/random_test_flag_correctness/sources/m.move @@ -1 +1 @@ -module 0x2::m { } +module 0x7::m { } diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/Move.toml b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/Move.toml new file mode 100644 index 00000000000..a22d8056e33 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "tracing_unit_tests" +edition = "2024.beta" # edition = "legacy" to use legacy (pre-2024) Move + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } + +[addresses] +std = "0x1" diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/NO_TEMPDIR b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/NO_TEMPDIR new file mode 100644 index 00000000000..e69de29bb2d diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.exp b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.exp new file mode 100644 index 00000000000..9b81b9c66d1 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.exp @@ -0,0 +1,29 @@ +Command `test -t 1 --trace-execution new_traces`: +INCLUDING DEPENDENCY MoveStdlib +BUILDING tracing_unit_tests +Running Move unit tests +[ PASS ] 0x1::calls::test_call_order +[ PASS ] 0x1::calls::test_call_return_order +[ PASS ] 0x1::calls::test_complex_nested_calls +[ PASS ] 0x1::calls::test_return_order +[ PASS ] 0x1::errors::aborter +[ PASS ] 0x1::errors::bad_cast +[ PASS ] 0x1::errors::div_0 +[ PASS ] 0x1::errors::fail_during_abort +[ PASS ] 0x1::errors::fail_in_native +[ PASS ] 0x1::errors::overshift_l +[ PASS ] 0x1::errors::overshift_r +[ PASS ] 0x1::errors::underflow +[ PASS ] 0x1::natives::get_orig_type_name_test +[ PASS ] 0x1::natives::get_type_name_test +[ PASS ] 0x1::packs::test_gen_pack_order +[ PASS ] 0x1::packs::test_gen_unpack_order +[ PASS ] 0x1::packs::test_pack_order +[ PASS ] 0x1::packs::test_unpack_order +[ PASS ] 0x1::references::nested_struct_reference_mutation +[ PASS ] 0x1::references::pass_mut_assign_in_other_fn +[ PASS ] 0x1::references::test_struct_borrow +[ PASS ] 0x1::references::test_vector_mut_borrow +[ PASS ] 0x1::references::test_vector_mut_borrow_pop +Test result: OK. Total tests: 23; passed: 23; failed: 0 +External Command `diff -qr new_traces saved_traces`: diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.txt b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.txt new file mode 100644 index 00000000000..9a232bf403f --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/args.txt @@ -0,0 +1,2 @@ +test -t 1 --trace-execution new_traces +> diff -qr new_traces saved_traces diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_order.json new file mode 100644 index 00000000000..925a0e8a072 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"test_call_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999994,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":8,"function_name":"f_test_call_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":1}}],"return_types":[],"type_instantiation":[]},"gas_left":999999994}},{"Instruction":{"gas_left":999994823,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":8,"gas_left":999994823,"return_":[]}},{"Instruction":{"gas_left":999994184,"instruction":"RET","pc":4,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999994184,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_return_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_return_order.json new file mode 100644 index 00000000000..7a997c124db --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_call_return_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":4,"frame_id":0,"function_name":"test_call_return_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":2,"function_name":"f_test_return_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999998865,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999998863,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998861,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998222,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":2,"gas_left":999998222,"return_":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":0}}]}},{"Instruction":{"gas_left":999998222,"instruction":"CALL","pc":1,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":12,"function_name":"f_test_call_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":0}}],"return_types":[],"type_instantiation":[]},"gas_left":999998222}},{"Instruction":{"gas_left":999993051,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":12,"gas_left":999993051,"return_":[]}},{"Instruction":{"gas_left":999992412,"instruction":"RET","pc":2,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999992412,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_complex_nested_calls.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_complex_nested_calls.json new file mode 100644 index 00000000000..bc9e09f22d0 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_complex_nested_calls.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":5,"frame_id":0,"function_name":"test_complex_nested_calls","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":2,"function_name":"f","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999998867,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":7,"frame_id":4,"function_name":"k","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[{"ref_type":null,"type_":"u64"}],"type_instantiation":[]},"gas_left":999998867}},{"Instruction":{"gas_left":999997732,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999997093,"instruction":"RET","pc":1,"type_parameters":[]}},{"CloseFrame":{"frame_id":4,"gas_left":999997093,"return_":[{"RuntimeValue":{"value":1}}]}},{"Instruction":{"gas_left":999997091,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999997089,"instruction":"ADD","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999997057,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999997025,"instruction":"COPY_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[2,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999997023,"instruction":"LD_U64","pc":5,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999997021,"instruction":"GT","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999997019,"instruction":"BR_FALSE","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996987,"instruction":"MOVE_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[2,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999996987,"instruction":"CALL","pc":9,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":8,"frame_id":33,"function_name":"g","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999996987}},{"Instruction":{"gas_left":999994689,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[33,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999994686,"instruction":"CAST_U8","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999994654,"instruction":"ST_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[33,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999994604,"instruction":"LD_CONST","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":[1,2,3]}}}},{"Instruction":{"gas_left":999994602,"instruction":"POP","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[1,2,3]}}}},{"Instruction":{"gas_left":999994586,"instruction":"LD_CONST","pc":5,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999994584,"instruction":"LD_TRUE","pc":6,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994482,"instruction":"PACK","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Instruction":{"gas_left":999994480,"instruction":"LD_TRUE","pc":8,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994324,"instruction":"PACK_GENERIC","pc":9,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"X","type_args":[]}},"bool"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}},{"Instruction":{"gas_left":999994324,"instruction":"CALL_GENERIC","pc":10,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":10,"frame_id":62,"function_name":"i","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"X","type_args":[]}},"bool"]}}},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u8"},{"ref_type":"Mut","type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}],"return_types":[{"ref_type":null,"type_":"u8"}],"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"X","type_args":[]}},"bool"]},"gas_left":999994324}},{"Instruction":{"gas_left":999991888,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}},{"Instruction":{"gas_left":999991732,"instruction":"UNPACK_GENERIC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999991730,"instruction":"POP","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999991728,"instruction":"POP","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Instruction":{"gas_left":999991726,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991694,"instruction":"ST_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[62,1]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999991692,"instruction":"IMM_BORROW_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,1]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[62,1]},"snapshot":1}}}},{"Instruction":{"gas_left":999991660,"instruction":"READ_REF","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[62,1]},"snapshot":1}}}},{"Effect":{"Read":{"location":{"Local":[62,1]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991658,"instruction":"POP","pc":8,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991656,"instruction":"LD_U8","pc":9,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991624,"instruction":"ST_LOC","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[62,2]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999991621,"instruction":"MUT_BORROW_LOC","pc":11,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Instruction":{"gas_left":999991605,"instruction":"ST_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Effect":{"Write":{"location":{"Local":[62,3]},"root_value_after_write":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}}},{"Instruction":{"gas_left":999991603,"instruction":"LD_U8","pc":13,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999991587,"instruction":"COPY_LOC","pc":14,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,3]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Instruction":{"gas_left":999991555,"instruction":"WRITE_REF","pc":15,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[62,2]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999991539,"instruction":"MOVE_LOC","pc":16,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,3]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[62,2]},"snapshot":2}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[62,2]},"snapshot":2}}}},{"Instruction":{"gas_left":999991507,"instruction":"READ_REF","pc":17,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[62,2]},"snapshot":2}}}},{"Effect":{"Read":{"location":{"Local":[62,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999990868,"instruction":"RET","pc":18,"type_parameters":[]}},{"CloseFrame":{"frame_id":62,"gas_left":999990868,"return_":[{"RuntimeValue":{"value":2}}]}},{"Instruction":{"gas_left":999990868,"instruction":"CALL","pc":11,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":9,"frame_id":118,"function_name":"h","is_native":false,"locals_types":[{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999990868}},{"Instruction":{"gas_left":999987963,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":118,"gas_left":999987963,"return_":[]}},{"Instruction":{"gas_left":999987931,"instruction":"MOVE_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[33,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999987931,"instruction":"CALL","pc":13,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":9,"frame_id":125,"function_name":"h","is_native":false,"locals_types":[{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999987931}},{"Instruction":{"gas_left":999985026,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":125,"gas_left":999985026,"return_":[]}},{"Instruction":{"gas_left":999984387,"instruction":"RET","pc":14,"type_parameters":[]}},{"CloseFrame":{"frame_id":33,"gas_left":999984387,"return_":[]}},{"Instruction":{"gas_left":999983748,"instruction":"RET","pc":10,"type_parameters":[]}},{"CloseFrame":{"frame_id":2,"gas_left":999983748,"return_":[]}},{"Instruction":{"gas_left":999983109,"instruction":"RET","pc":1,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999983109,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_return_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_return_order.json new file mode 100644 index 00000000000..da67d038efd --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__calls__test_return_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"test_return_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":2,"function_name":"f_test_return_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999998865,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999998863,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998861,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998222,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":2,"gas_left":999998222,"return_":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":0}}]}},{"Instruction":{"gas_left":999998190,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999998158,"instruction":"ST_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999998126,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999998094,"instruction":"MOVE_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998092,"instruction":"LD_U8","pc":5,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998028,"instruction":"EQ","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998026,"instruction":"BR_FALSE","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998024,"instruction":"BRANCH","pc":8,"type_parameters":[]}},{"Instruction":{"gas_left":999997992,"instruction":"MOVE_LOC","pc":11,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999997990,"instruction":"BR_FALSE","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999997988,"instruction":"BRANCH","pc":13,"type_parameters":[]}},{"Instruction":{"gas_left":999997349,"instruction":"RET","pc":16,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999997349,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__aborter.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__aborter.json new file mode 100644 index 00000000000..689f2c8ec07 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__aborter.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"aborter","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999996,"instruction":"ABORT","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"ExecutionError":"ABORTED"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__bad_cast.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__bad_cast.json new file mode 100644 index 00000000000..c68db2b6df2 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__bad_cast.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":0,"function_name":"bad_cast","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":256}}}},{"Instruction":{"gas_left":999999995,"instruction":"CAST_U8","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":256}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__div_0.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__div_0.json new file mode 100644 index 00000000000..d901830856a --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__div_0.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":0,"function_name":"div_0","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999992,"instruction":"DIV","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_during_abort.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_during_abort.json new file mode 100644 index 00000000000..2b27b5e5b21 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_during_abort.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":0,"function_name":"fail_during_abort","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999992,"instruction":"DIV","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_in_native.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_in_native.json new file mode 100644 index 00000000000..0a002093a79 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__fail_in_native.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":7,"frame_id":0,"function_name":"fail_in_native","is_native":false,"locals_types":[{"ref_type":null,"type_":{"vector":"u8"}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999992,"instruction":"LD_CONST","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":[1,2,3]}}}},{"Instruction":{"gas_left":999999986,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[1,2,3]}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":[1,2,3]}}}}},{"Instruction":{"gas_left":999999984,"instruction":"IMM_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[1,2,3]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}}}},{"Instruction":{"gas_left":999999982,"instruction":"LD_U64","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999980,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999980,"instruction":"CALL","pc":5,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":17,"frame_id":14,"function_name":"internal_sub_string_for_testing","is_native":false,"locals_types":[{"ref_type":"Imm","type_":{"vector":"u8"}},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}},{"RuntimeValue":{"value":4}},{"RuntimeValue":{"value":1}}],"return_types":[{"ref_type":null,"type_":{"vector":"u8"}}],"type_instantiation":[]},"gas_left":999999980}},{"Instruction":{"gas_left":999995432,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,0]},"moved":true,"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}}}},{"Instruction":{"gas_left":999995400,"instruction":"MOVE_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":4}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999995368,"instruction":"MOVE_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999995368,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":15,"frame_id":25,"function_name":"internal_sub_string","is_native":true,"locals_types":[{"ref_type":"Imm","type_":{"vector":"u8"}},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}},{"RuntimeValue":{"value":4}},{"RuntimeValue":{"value":1}}],"return_types":[{"ref_type":null,"type_":{"vector":"u8"}}],"type_instantiation":[]},"gas_left":999995368}},{"Effect":{"ExecutionError":"ABORTED"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_l.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_l.json new file mode 100644 index 00000000000..61d23d2759d --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_l.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":4,"frame_id":0,"function_name":"overshift_l","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U8","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U8","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":20}}}},{"Instruction":{"gas_left":999999993,"instruction":"SHL","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":20}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_r.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_r.json new file mode 100644 index 00000000000..4222baf2612 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__overshift_r.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":5,"frame_id":0,"function_name":"overshift_r","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U8","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U8","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":20}}}},{"Instruction":{"gas_left":999999993,"instruction":"SHL","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":20}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__underflow.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__underflow.json new file mode 100644 index 00000000000..e0a985da8d2 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__errors__underflow.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"underflow","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"gas_left":999999994,"instruction":"SUB","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_orig_type_name_test.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_orig_type_name_test.json new file mode 100644 index 00000000000..dc92e46114e --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_orig_type_name_test.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":0,"function_name":"get_orig_type_name_test","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"natives"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL_GENERIC","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":2,"function_name":"get_with_original_ids","is_native":true,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"natives","name":"X","type_args":[]}}]},"gas_left":1000000000}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"CloseFrame":{"frame_id":2,"gas_left":999998834,"return_":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999998674,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Instruction":{"gas_left":999998672,"instruction":"IMM_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999998672,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":12,"function_name":"borrow_string","is_native":false,"locals_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999998672}},{"Instruction":{"gas_left":999996390,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[12,0]},"moved":true,"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999996388,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995749,"instruction":"RET","pc":2,"type_parameters":[]}},{"CloseFrame":{"frame_id":12,"gas_left":999995749,"return_":[{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999995747,"instruction":"POP","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"MOVE_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"CALL","pc":6,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":27,"function_name":"into_string","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999995587}},{"Instruction":{"gas_left":999993319,"instruction":"IMM_BORROW_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[27,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993317,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993161,"instruction":"READ_REF","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[27,0]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999992522,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":27,"gas_left":999992522,"return_":[{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}]}},{"Instruction":{"gas_left":999992520,"instruction":"POP","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999991881,"instruction":"RET","pc":8,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999991881,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_type_name_test.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_type_name_test.json new file mode 100644 index 00000000000..2c8e76ffa4f --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__natives__get_type_name_test.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"get_type_name_test","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"natives"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL_GENERIC","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":2,"function_name":"get","is_native":true,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"natives","name":"X","type_args":[]}}]},"gas_left":1000000000}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"CloseFrame":{"frame_id":2,"gas_left":999998834,"return_":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999998674,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Instruction":{"gas_left":999998672,"instruction":"IMM_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999998672,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":12,"function_name":"borrow_string","is_native":false,"locals_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999998672}},{"Instruction":{"gas_left":999996390,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[12,0]},"moved":true,"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999996388,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995749,"instruction":"RET","pc":2,"type_parameters":[]}},{"CloseFrame":{"frame_id":12,"gas_left":999995749,"return_":[{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999995747,"instruction":"POP","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"MOVE_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"CALL","pc":6,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":27,"function_name":"into_string","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999995587}},{"Instruction":{"gas_left":999993319,"instruction":"IMM_BORROW_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[27,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993317,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993161,"instruction":"READ_REF","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[27,0]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999992522,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":27,"gas_left":999992522,"return_":[{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}]}},{"Instruction":{"gas_left":999992520,"instruction":"POP","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999991881,"instruction":"RET","pc":8,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999991881,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_pack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_pack_order.json new file mode 100644 index 00000000000..ace8cfe2645 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_pack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"test_gen_pack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"packs","name":"GenX","type_args":["u64","bool","u8"]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK_GENERIC","pc":3,"type_parameters":["u64","bool","u8"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999741,"instruction":"ST_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}}},{"Instruction":{"gas_left":999999739,"instruction":"IMM_BORROW_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999737,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":6,"type_parameters":["u64","bool","u8"]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999705,"instruction":"READ_REF","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999703,"instruction":"LD_U8","pc":8,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999639,"instruction":"EQ","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999637,"instruction":"BR_FALSE","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999635,"instruction":"BRANCH","pc":11,"type_parameters":[]}},{"Instruction":{"gas_left":999998996,"instruction":"RET","pc":16,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998996,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_unpack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_unpack_order.json new file mode 100644 index 00000000000..0d2facae5bf --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_gen_unpack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":0,"function_name":"test_gen_unpack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK_GENERIC","pc":3,"type_parameters":["u64","bool","u8"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999688,"instruction":"UNPACK_GENERIC","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999656,"instruction":"ST_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,3]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999999624,"instruction":"ST_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999592,"instruction":"ST_LOC","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999560,"instruction":"MOVE_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,3]},"moved":true,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999558,"instruction":"LD_U8","pc":9,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999494,"instruction":"EQ","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999492,"instruction":"BR_FALSE","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999460,"instruction":"MOVE_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999428,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999426,"instruction":"BRANCH","pc":14,"type_parameters":[]}},{"Instruction":{"gas_left":999999394,"instruction":"MOVE_LOC","pc":17,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999392,"instruction":"BR_FALSE","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999390,"instruction":"BRANCH","pc":19,"type_parameters":[]}},{"Instruction":{"gas_left":999998751,"instruction":"RET","pc":22,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998751,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_pack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_pack_order.json new file mode 100644 index 00000000000..5b176fc2625 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_pack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"test_pack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"packs","name":"X","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999741,"instruction":"ST_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}}},{"Instruction":{"gas_left":999999739,"instruction":"IMM_BORROW_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999737,"instruction":"IMM_BORROW_FIELD","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999705,"instruction":"READ_REF","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999703,"instruction":"LD_U8","pc":8,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999639,"instruction":"EQ","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999637,"instruction":"BR_FALSE","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999635,"instruction":"BRANCH","pc":11,"type_parameters":[]}},{"Instruction":{"gas_left":999998996,"instruction":"RET","pc":16,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998996,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_unpack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_unpack_order.json new file mode 100644 index 00000000000..e1f6e8893c5 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__packs__test_unpack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":0,"function_name":"test_unpack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999688,"instruction":"UNPACK","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999656,"instruction":"ST_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,3]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999999624,"instruction":"ST_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999592,"instruction":"ST_LOC","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999560,"instruction":"MOVE_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,3]},"moved":true,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999558,"instruction":"LD_U8","pc":9,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999494,"instruction":"EQ","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999492,"instruction":"BR_FALSE","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999460,"instruction":"MOVE_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999428,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999426,"instruction":"BRANCH","pc":14,"type_parameters":[]}},{"Instruction":{"gas_left":999999394,"instruction":"MOVE_LOC","pc":17,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999392,"instruction":"BR_FALSE","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999390,"instruction":"BRANCH","pc":19,"type_parameters":[]}},{"Instruction":{"gas_left":999998751,"instruction":"RET","pc":22,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998751,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__nested_struct_reference_mutation.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__nested_struct_reference_mutation.json new file mode 100644 index 00000000000..ae31124c175 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__nested_struct_reference_mutation.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":5,"frame_id":0,"function_name":"nested_struct_reference_mutation","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U64","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999992,"instruction":"LD_U64","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999890,"instruction":"PACK_GENERIC","pc":4,"type_parameters":["u64"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}}}}},{"Instruction":{"gas_left":999999734,"instruction":"PACK_GENERIC","pc":5,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}}}}},{"Instruction":{"gas_left":999999524,"instruction":"PACK_GENERIC","pc":6,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999384,"instruction":"ST_LOC","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Instruction":{"gas_left":999999382,"instruction":"IMM_BORROW_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999380,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":9,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999378,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":10,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999376,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":11,"type_parameters":["u64"]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999344,"instruction":"READ_REF","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999342,"instruction":"LD_U64","pc":13,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999278,"instruction":"EQ","pc":14,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999276,"instruction":"BR_FALSE","pc":15,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999274,"instruction":"BRANCH","pc":16,"type_parameters":[]}},{"Instruction":{"gas_left":999999271,"instruction":"MUT_BORROW_LOC","pc":23,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999269,"instruction":"MUT_BORROW_FIELD_GENERIC","pc":24,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999269,"instruction":"CALL","pc":25,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":56,"function_name":"l0","is_native":false,"locals_types":[{"ref_type":"Mut","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}],"return_types":[],"type_instantiation":[]},"gas_left":999999269}},{"Instruction":{"gas_left":999996987,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[56,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999996985,"instruction":"MUT_BORROW_FIELD_GENERIC","pc":1,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999996985,"instruction":"CALL","pc":2,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":7,"frame_id":64,"function_name":"l1","is_native":false,"locals_types":[{"ref_type":"Mut","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}],"return_types":[],"type_instantiation":[]},"gas_left":999996985}},{"Instruction":{"gas_left":999994703,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[64,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999994701,"instruction":"MUT_BORROW_FIELD_GENERIC","pc":1,"type_parameters":["u64"]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999994701,"instruction":"CALL","pc":2,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":8,"frame_id":72,"function_name":"incr","is_native":false,"locals_types":[{"ref_type":"Mut","type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}],"return_types":[],"type_instantiation":[]},"gas_left":999994701}},{"Instruction":{"gas_left":999992419,"instruction":"COPY_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[72,0]},"moved":false,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999992387,"instruction":"READ_REF","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999992385,"instruction":"LD_U64","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999992383,"instruction":"ADD","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999992367,"instruction":"MOVE_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[72,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999992335,"instruction":"WRITE_REF","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Instruction":{"gas_left":999991696,"instruction":"RET","pc":6,"type_parameters":[]}},{"CloseFrame":{"frame_id":72,"gas_left":999991696,"return_":[]}},{"Instruction":{"gas_left":999991057,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":64,"gas_left":999991057,"return_":[]}},{"Instruction":{"gas_left":999990418,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":56,"gas_left":999990418,"return_":[]}},{"Instruction":{"gas_left":999990416,"instruction":"IMM_BORROW_LOC","pc":26,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990414,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":27,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990412,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":28,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990410,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":29,"type_parameters":["u64"]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990378,"instruction":"READ_REF","pc":30,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999990376,"instruction":"LD_U64","pc":31,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999990312,"instruction":"EQ","pc":32,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999990310,"instruction":"BR_FALSE","pc":33,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999990308,"instruction":"BRANCH","pc":34,"type_parameters":[]}},{"Instruction":{"gas_left":999989669,"instruction":"RET","pc":41,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999989669,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__pass_mut_assign_in_other_fn.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__pass_mut_assign_in_other_fn.json new file mode 100644 index 00000000000..765d28809cb --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__pass_mut_assign_in_other_fn.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"pass_mut_assign_in_other_fn","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999966,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999999963,"instruction":"MUT_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}},{"Instruction":{"gas_left":999999961,"instruction":"LD_U64","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999959,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999959,"instruction":"CALL","pc":5,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":14,"function_name":"assign_add","is_native":false,"locals_types":[{"ref_type":"Mut","type_":"u64"},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}},{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999999959}},{"Instruction":{"gas_left":999995395,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999995363,"instruction":"MOVE_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999995361,"instruction":"ADD","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999995345,"instruction":"MOVE_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}},{"Instruction":{"gas_left":999995313,"instruction":"WRITE_REF","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"gas_left":999994674,"instruction":"RET","pc":5,"type_parameters":[]}},{"CloseFrame":{"frame_id":14,"gas_left":999994674,"return_":[]}},{"Instruction":{"gas_left":999994642,"instruction":"MOVE_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999994640,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999994576,"instruction":"EQ","pc":8,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994574,"instruction":"BR_FALSE","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994572,"instruction":"BRANCH","pc":10,"type_parameters":[]}},{"Instruction":{"gas_left":999993933,"instruction":"RET","pc":13,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999993933,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_struct_borrow.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_struct_borrow.json new file mode 100644 index 00000000000..6076e89f639 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_struct_borrow.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"test_struct_borrow","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"X","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_FALSE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"gas_left":999999894,"instruction":"PACK","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Instruction":{"gas_left":999999826,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}}},{"Instruction":{"gas_left":999999824,"instruction":"IMM_BORROW_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Instruction":{"gas_left":999999822,"instruction":"IMM_BORROW_FIELD","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Instruction":{"gas_left":999999790,"instruction":"READ_REF","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999788,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999724,"instruction":"EQ","pc":8,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999722,"instruction":"BR_FALSE","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999720,"instruction":"BRANCH","pc":10,"type_parameters":[]}},{"Instruction":{"gas_left":999999081,"instruction":"RET","pc":13,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999999081,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow.json new file mode 100644 index 00000000000..10cba16aeb1 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":0,"function_name":"test_vector_mut_borrow","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":"Mut","type_":"u64"},{"ref_type":null,"type_":{"vector":"u64"}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999966,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999963,"instruction":"MUT_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999947,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Instruction":{"gas_left":999999945,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999929,"instruction":"COPY_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999897,"instruction":"WRITE_REF","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999999895,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999879,"instruction":"COPY_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Instruction":{"gas_left":999999847,"instruction":"WRITE_REF","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"gas_left":999999831,"instruction":"COPY_LOC","pc":10,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Instruction":{"gas_left":999999799,"instruction":"READ_REF","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999714,"instruction":"VEC_PACK","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":[3]}}}},{"Instruction":{"gas_left":999999698,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[3]}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":[3]}}}}},{"Instruction":{"gas_left":999999696,"instruction":"LD_U64","pc":14,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999693,"instruction":"MUT_BORROW_LOC","pc":15,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[3]}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999999691,"instruction":"LD_U64","pc":16,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999997788,"instruction":"VEC_MUT_BORROW","pc":17,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999997756,"instruction":"WRITE_REF","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,2]},0]},"root_value_after_write":{"RuntimeValue":{"value":[4]}}}}},{"Instruction":{"gas_left":999997754,"instruction":"IMM_BORROW_LOC","pc":19,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999997752,"instruction":"LD_U64","pc":20,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999996417,"instruction":"VEC_IMM_BORROW","pc":21,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999996385,"instruction":"READ_REF","pc":22,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,2]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996383,"instruction":"LD_U64","pc":23,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996319,"instruction":"EQ","pc":24,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996317,"instruction":"BR_FALSE","pc":25,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996315,"instruction":"BRANCH","pc":26,"type_parameters":[]}},{"Instruction":{"gas_left":999996299,"instruction":"MOVE_LOC","pc":31,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Instruction":{"gas_left":999996267,"instruction":"READ_REF","pc":32,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999996265,"instruction":"LD_U64","pc":33,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999996201,"instruction":"EQ","pc":34,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996199,"instruction":"BR_FALSE","pc":35,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996197,"instruction":"BRANCH","pc":36,"type_parameters":[]}},{"Instruction":{"gas_left":999995558,"instruction":"RET","pc":39,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999995558,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow_pop.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow_pop.json new file mode 100644 index 00000000000..40468e125fc --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/new_traces/0x1__references__test_vector_mut_borrow_pop.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":4,"frame_id":0,"function_name":"test_vector_mut_borrow_pop","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":"Mut","type_":"u64"},{"ref_type":null,"type_":{"vector":"u64"}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999966,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999963,"instruction":"MUT_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999947,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Instruction":{"gas_left":999999945,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999929,"instruction":"COPY_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999897,"instruction":"WRITE_REF","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999999895,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999879,"instruction":"COPY_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Instruction":{"gas_left":999999847,"instruction":"WRITE_REF","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"gas_left":999999831,"instruction":"MOVE_LOC","pc":10,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Instruction":{"gas_left":999999799,"instruction":"READ_REF","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999714,"instruction":"VEC_PACK","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":[3]}}}},{"Instruction":{"gas_left":999999698,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[3]}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":[3]}}}}},{"Instruction":{"gas_left":999999696,"instruction":"LD_U64","pc":14,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999693,"instruction":"MUT_BORROW_LOC","pc":15,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[3]}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999999691,"instruction":"LD_U64","pc":16,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999997788,"instruction":"VEC_MUT_BORROW","pc":17,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999997756,"instruction":"WRITE_REF","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,2]},0]},"root_value_after_write":{"RuntimeValue":{"value":[4]}}}}},{"Instruction":{"gas_left":999997754,"instruction":"IMM_BORROW_LOC","pc":19,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999997752,"instruction":"LD_U64","pc":20,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999996417,"instruction":"VEC_IMM_BORROW","pc":21,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999996385,"instruction":"READ_REF","pc":22,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,2]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996383,"instruction":"LD_U64","pc":23,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996319,"instruction":"EQ","pc":24,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996317,"instruction":"BR_FALSE","pc":25,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996315,"instruction":"BRANCH","pc":26,"type_parameters":[]}},{"Instruction":{"gas_left":999996312,"instruction":"MUT_BORROW_LOC","pc":29,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999996084,"instruction":"VEC_POP_BACK","pc":30,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996082,"instruction":"LD_U64","pc":31,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996018,"instruction":"EQ","pc":32,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996016,"instruction":"BR_FALSE","pc":33,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996014,"instruction":"BRANCH","pc":34,"type_parameters":[]}},{"Instruction":{"gas_left":999995375,"instruction":"RET","pc":37,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999995375,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_order.json new file mode 100644 index 00000000000..925a0e8a072 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"test_call_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999994,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":8,"function_name":"f_test_call_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":1}}],"return_types":[],"type_instantiation":[]},"gas_left":999999994}},{"Instruction":{"gas_left":999994823,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":8,"gas_left":999994823,"return_":[]}},{"Instruction":{"gas_left":999994184,"instruction":"RET","pc":4,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999994184,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_return_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_return_order.json new file mode 100644 index 00000000000..7a997c124db --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_call_return_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":4,"frame_id":0,"function_name":"test_call_return_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":2,"function_name":"f_test_return_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999998865,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999998863,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998861,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998222,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":2,"gas_left":999998222,"return_":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":0}}]}},{"Instruction":{"gas_left":999998222,"instruction":"CALL","pc":1,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":12,"function_name":"f_test_call_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":0}}],"return_types":[],"type_instantiation":[]},"gas_left":999998222}},{"Instruction":{"gas_left":999993051,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":12,"gas_left":999993051,"return_":[]}},{"Instruction":{"gas_left":999992412,"instruction":"RET","pc":2,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999992412,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_complex_nested_calls.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_complex_nested_calls.json new file mode 100644 index 00000000000..bc9e09f22d0 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_complex_nested_calls.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":5,"frame_id":0,"function_name":"test_complex_nested_calls","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":2,"function_name":"f","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999998867,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":7,"frame_id":4,"function_name":"k","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[{"ref_type":null,"type_":"u64"}],"type_instantiation":[]},"gas_left":999998867}},{"Instruction":{"gas_left":999997732,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999997093,"instruction":"RET","pc":1,"type_parameters":[]}},{"CloseFrame":{"frame_id":4,"gas_left":999997093,"return_":[{"RuntimeValue":{"value":1}}]}},{"Instruction":{"gas_left":999997091,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999997089,"instruction":"ADD","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999997057,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[2,0]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999997025,"instruction":"COPY_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[2,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999997023,"instruction":"LD_U64","pc":5,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999997021,"instruction":"GT","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999997019,"instruction":"BR_FALSE","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996987,"instruction":"MOVE_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[2,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999996987,"instruction":"CALL","pc":9,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":8,"frame_id":33,"function_name":"g","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999996987}},{"Instruction":{"gas_left":999994689,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[33,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999994686,"instruction":"CAST_U8","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999994654,"instruction":"ST_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[33,1]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999994604,"instruction":"LD_CONST","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":[1,2,3]}}}},{"Instruction":{"gas_left":999994602,"instruction":"POP","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[1,2,3]}}}},{"Instruction":{"gas_left":999994586,"instruction":"LD_CONST","pc":5,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999994584,"instruction":"LD_TRUE","pc":6,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994482,"instruction":"PACK","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Instruction":{"gas_left":999994480,"instruction":"LD_TRUE","pc":8,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994324,"instruction":"PACK_GENERIC","pc":9,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"X","type_args":[]}},"bool"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}},{"Instruction":{"gas_left":999994324,"instruction":"CALL_GENERIC","pc":10,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":10,"frame_id":62,"function_name":"i","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"X","type_args":[]}},"bool"]}}},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u8"},{"ref_type":"Mut","type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}],"return_types":[{"ref_type":null,"type_":"u8"}],"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"calls","name":"X","type_args":[]}},"bool"]},"gas_left":999994324}},{"Instruction":{"gas_left":999991888,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}},{"Instruction":{"gas_left":999991732,"instruction":"UNPACK_GENERIC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"},"y":true},"type":"0x1::calls::Y<0x1::calls::X, bool>"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999991730,"instruction":"POP","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999991728,"instruction":"POP","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":1,"y":true},"type":"0x1::calls::X"}}}}},{"Instruction":{"gas_left":999991726,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991694,"instruction":"ST_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[62,1]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999991692,"instruction":"IMM_BORROW_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,1]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[62,1]},"snapshot":1}}}},{"Instruction":{"gas_left":999991660,"instruction":"READ_REF","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[62,1]},"snapshot":1}}}},{"Effect":{"Read":{"location":{"Local":[62,1]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991658,"instruction":"POP","pc":8,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991656,"instruction":"LD_U8","pc":9,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999991624,"instruction":"ST_LOC","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[62,2]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999991621,"instruction":"MUT_BORROW_LOC","pc":11,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Instruction":{"gas_left":999991605,"instruction":"ST_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Effect":{"Write":{"location":{"Local":[62,3]},"root_value_after_write":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}}},{"Instruction":{"gas_left":999991603,"instruction":"LD_U8","pc":13,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999991587,"instruction":"COPY_LOC","pc":14,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,3]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Instruction":{"gas_left":999991555,"instruction":"WRITE_REF","pc":15,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[62,2]},"snapshot":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[62,2]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999991539,"instruction":"MOVE_LOC","pc":16,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[62,3]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[62,2]},"snapshot":2}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[62,2]},"snapshot":2}}}},{"Instruction":{"gas_left":999991507,"instruction":"READ_REF","pc":17,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[62,2]},"snapshot":2}}}},{"Effect":{"Read":{"location":{"Local":[62,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999990868,"instruction":"RET","pc":18,"type_parameters":[]}},{"CloseFrame":{"frame_id":62,"gas_left":999990868,"return_":[{"RuntimeValue":{"value":2}}]}},{"Instruction":{"gas_left":999990868,"instruction":"CALL","pc":11,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":9,"frame_id":118,"function_name":"h","is_native":false,"locals_types":[{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999990868}},{"Instruction":{"gas_left":999987963,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":118,"gas_left":999987963,"return_":[]}},{"Instruction":{"gas_left":999987931,"instruction":"MOVE_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[33,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999987931,"instruction":"CALL","pc":13,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":9,"frame_id":125,"function_name":"h","is_native":false,"locals_types":[{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999987931}},{"Instruction":{"gas_left":999985026,"instruction":"RET","pc":0,"type_parameters":[]}},{"CloseFrame":{"frame_id":125,"gas_left":999985026,"return_":[]}},{"Instruction":{"gas_left":999984387,"instruction":"RET","pc":14,"type_parameters":[]}},{"CloseFrame":{"frame_id":33,"gas_left":999984387,"return_":[]}},{"Instruction":{"gas_left":999983748,"instruction":"RET","pc":10,"type_parameters":[]}},{"CloseFrame":{"frame_id":2,"gas_left":999983748,"return_":[]}},{"Instruction":{"gas_left":999983109,"instruction":"RET","pc":1,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999983109,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_return_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_return_order.json new file mode 100644 index 00000000000..da67d038efd --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__calls__test_return_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"test_return_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":2,"function_name":"f_test_return_order","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"calls"},"parameters":[],"return_types":[{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999998865,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999998863,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998861,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998222,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":2,"gas_left":999998222,"return_":[{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":true}},{"RuntimeValue":{"value":0}}]}},{"Instruction":{"gas_left":999998190,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999998158,"instruction":"ST_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999998126,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999998094,"instruction":"MOVE_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998092,"instruction":"LD_U8","pc":5,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999998028,"instruction":"EQ","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998026,"instruction":"BR_FALSE","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999998024,"instruction":"BRANCH","pc":8,"type_parameters":[]}},{"Instruction":{"gas_left":999997992,"instruction":"MOVE_LOC","pc":11,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999997990,"instruction":"BR_FALSE","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999997988,"instruction":"BRANCH","pc":13,"type_parameters":[]}},{"Instruction":{"gas_left":999997349,"instruction":"RET","pc":16,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999997349,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__aborter.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__aborter.json new file mode 100644 index 00000000000..689f2c8ec07 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__aborter.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"aborter","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999996,"instruction":"ABORT","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"ExecutionError":"ABORTED"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__bad_cast.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__bad_cast.json new file mode 100644 index 00000000000..c68db2b6df2 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__bad_cast.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":0,"function_name":"bad_cast","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":256}}}},{"Instruction":{"gas_left":999999995,"instruction":"CAST_U8","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":256}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__div_0.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__div_0.json new file mode 100644 index 00000000000..d901830856a --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__div_0.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":0,"function_name":"div_0","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999992,"instruction":"DIV","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_during_abort.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_during_abort.json new file mode 100644 index 00000000000..2b27b5e5b21 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_during_abort.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":0,"function_name":"fail_during_abort","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999992,"instruction":"DIV","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_in_native.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_in_native.json new file mode 100644 index 00000000000..0a002093a79 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__fail_in_native.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":7,"frame_id":0,"function_name":"fail_in_native","is_native":false,"locals_types":[{"ref_type":null,"type_":{"vector":"u8"}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999992,"instruction":"LD_CONST","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":[1,2,3]}}}},{"Instruction":{"gas_left":999999986,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[1,2,3]}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":[1,2,3]}}}}},{"Instruction":{"gas_left":999999984,"instruction":"IMM_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[1,2,3]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}}}},{"Instruction":{"gas_left":999999982,"instruction":"LD_U64","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999980,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999980,"instruction":"CALL","pc":5,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":17,"frame_id":14,"function_name":"internal_sub_string_for_testing","is_native":false,"locals_types":[{"ref_type":"Imm","type_":{"vector":"u8"}},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}},{"RuntimeValue":{"value":4}},{"RuntimeValue":{"value":1}}],"return_types":[{"ref_type":null,"type_":{"vector":"u8"}}],"type_instantiation":[]},"gas_left":999999980}},{"Instruction":{"gas_left":999995432,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,0]},"moved":true,"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}}}},{"Instruction":{"gas_left":999995400,"instruction":"MOVE_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":4}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999995368,"instruction":"MOVE_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999995368,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":15,"frame_id":25,"function_name":"internal_sub_string","is_native":true,"locals_types":[{"ref_type":"Imm","type_":{"vector":"u8"}},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"string"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":[1,2,3]}},{"RuntimeValue":{"value":4}},{"RuntimeValue":{"value":1}}],"return_types":[{"ref_type":null,"type_":{"vector":"u8"}}],"type_instantiation":[]},"gas_left":999995368}},{"Effect":{"ExecutionError":"ABORTED"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_l.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_l.json new file mode 100644 index 00000000000..61d23d2759d --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_l.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":4,"frame_id":0,"function_name":"overshift_l","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U8","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U8","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":20}}}},{"Instruction":{"gas_left":999999993,"instruction":"SHL","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":20}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_r.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_r.json new file mode 100644 index 00000000000..4222baf2612 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__overshift_r.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":5,"frame_id":0,"function_name":"overshift_r","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U8","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U8","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":20}}}},{"Instruction":{"gas_left":999999993,"instruction":"SHL","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":20}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__underflow.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__underflow.json new file mode 100644 index 00000000000..e0a985da8d2 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__errors__underflow.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"underflow","is_native":false,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"errors"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":10}}}},{"Instruction":{"gas_left":999999994,"instruction":"SUB","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":10}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"ExecutionError":"ARITHMETIC_ERROR"}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_orig_type_name_test.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_orig_type_name_test.json new file mode 100644 index 00000000000..dc92e46114e --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_orig_type_name_test.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":0,"function_name":"get_orig_type_name_test","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"natives"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL_GENERIC","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":2,"function_name":"get_with_original_ids","is_native":true,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"natives","name":"X","type_args":[]}}]},"gas_left":1000000000}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"CloseFrame":{"frame_id":2,"gas_left":999998834,"return_":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999998674,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Instruction":{"gas_left":999998672,"instruction":"IMM_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999998672,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":12,"function_name":"borrow_string","is_native":false,"locals_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999998672}},{"Instruction":{"gas_left":999996390,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[12,0]},"moved":true,"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999996388,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995749,"instruction":"RET","pc":2,"type_parameters":[]}},{"CloseFrame":{"frame_id":12,"gas_left":999995749,"return_":[{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999995747,"instruction":"POP","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"MOVE_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"CALL","pc":6,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":27,"function_name":"into_string","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999995587}},{"Instruction":{"gas_left":999993319,"instruction":"IMM_BORROW_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[27,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993317,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993161,"instruction":"READ_REF","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[27,0]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999992522,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":27,"gas_left":999992522,"return_":[{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}]}},{"Instruction":{"gas_left":999992520,"instruction":"POP","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999991881,"instruction":"RET","pc":8,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999991881,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_type_name_test.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_type_name_test.json new file mode 100644 index 00000000000..2c8e76ffa4f --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__natives__get_type_name_test.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"get_type_name_test","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"natives"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":1000000000,"instruction":"CALL_GENERIC","pc":0,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":2,"function_name":"get","is_native":true,"locals_types":[],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"type_instantiation":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"natives","name":"X","type_args":[]}}]},"gas_left":1000000000}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"CloseFrame":{"frame_id":2,"gas_left":999998834,"return_":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999998674,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Instruction":{"gas_left":999998672,"instruction":"IMM_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999998672,"instruction":"CALL","pc":3,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":12,"function_name":"borrow_string","is_native":false,"locals_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":"Imm","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999998672}},{"Instruction":{"gas_left":999996390,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[12,0]},"moved":true,"root_value_read":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999996388,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995749,"instruction":"RET","pc":2,"type_parameters":[]}},{"CloseFrame":{"frame_id":12,"gas_left":999995749,"return_":[{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}]}},{"Instruction":{"gas_left":999995747,"instruction":"POP","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"MOVE_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999995587,"instruction":"CALL","pc":6,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":27,"function_name":"into_string","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"type_name","name":"TypeName","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"type_name"},"parameters":[{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}],"return_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"ascii","name":"String","type_args":[]}}}],"type_instantiation":[]},"gas_left":999995587}},{"Instruction":{"gas_left":999993319,"instruction":"IMM_BORROW_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[27,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993317,"instruction":"IMM_BORROW_FIELD","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[27,0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Instruction":{"gas_left":999993161,"instruction":"READ_REF","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[27,0]},0]},"snapshot":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[27,0]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"name":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}},"type":"0x1::type_name::TypeName"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999992522,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":27,"gas_left":999992522,"return_":[{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}]}},{"Instruction":{"gas_left":999992520,"instruction":"POP","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"bytes":[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,49,58,58,110,97,116,105,118,101,115,58,58,88]},"type":"0x1::ascii::String"}}}}},{"Instruction":{"gas_left":999991881,"instruction":"RET","pc":8,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999991881,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_pack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_pack_order.json new file mode 100644 index 00000000000..ace8cfe2645 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_pack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"test_gen_pack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"packs","name":"GenX","type_args":["u64","bool","u8"]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK_GENERIC","pc":3,"type_parameters":["u64","bool","u8"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999741,"instruction":"ST_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}}},{"Instruction":{"gas_left":999999739,"instruction":"IMM_BORROW_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999737,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":6,"type_parameters":["u64","bool","u8"]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999705,"instruction":"READ_REF","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999703,"instruction":"LD_U8","pc":8,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999639,"instruction":"EQ","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999637,"instruction":"BR_FALSE","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999635,"instruction":"BRANCH","pc":11,"type_parameters":[]}},{"Instruction":{"gas_left":999998996,"instruction":"RET","pc":16,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998996,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_unpack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_unpack_order.json new file mode 100644 index 00000000000..0d2facae5bf --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_gen_unpack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":0,"function_name":"test_gen_unpack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK_GENERIC","pc":3,"type_parameters":["u64","bool","u8"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Instruction":{"gas_left":999999688,"instruction":"UNPACK_GENERIC","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::GenX"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999656,"instruction":"ST_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,3]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999999624,"instruction":"ST_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999592,"instruction":"ST_LOC","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999560,"instruction":"MOVE_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,3]},"moved":true,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999558,"instruction":"LD_U8","pc":9,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999494,"instruction":"EQ","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999492,"instruction":"BR_FALSE","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999460,"instruction":"MOVE_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999428,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999426,"instruction":"BRANCH","pc":14,"type_parameters":[]}},{"Instruction":{"gas_left":999999394,"instruction":"MOVE_LOC","pc":17,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999392,"instruction":"BR_FALSE","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999390,"instruction":"BRANCH","pc":19,"type_parameters":[]}},{"Instruction":{"gas_left":999998751,"instruction":"RET","pc":22,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998751,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_pack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_pack_order.json new file mode 100644 index 00000000000..5b176fc2625 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_pack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"test_pack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"packs","name":"X","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999741,"instruction":"ST_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}}},{"Instruction":{"gas_left":999999739,"instruction":"IMM_BORROW_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999737,"instruction":"IMM_BORROW_FIELD","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999705,"instruction":"READ_REF","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},2]},"snapshot":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999703,"instruction":"LD_U8","pc":8,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999639,"instruction":"EQ","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999637,"instruction":"BR_FALSE","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999635,"instruction":"BRANCH","pc":11,"type_parameters":[]}},{"Instruction":{"gas_left":999998996,"instruction":"RET","pc":16,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998996,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_unpack_order.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_unpack_order.json new file mode 100644 index 00000000000..e1f6e8893c5 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__packs__test_unpack_order.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":0,"function_name":"test_unpack_order","is_native":false,"locals_types":[{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"bool"},{"ref_type":null,"type_":"u8"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"packs"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_TRUE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U8","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999841,"instruction":"PACK","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Instruction":{"gas_left":999999688,"instruction":"UNPACK","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":true,"pos2":0},"type":"0x1::packs::X"}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999656,"instruction":"ST_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,3]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999999624,"instruction":"ST_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999592,"instruction":"ST_LOC","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999560,"instruction":"MOVE_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,3]},"moved":true,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999558,"instruction":"LD_U8","pc":9,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999494,"instruction":"EQ","pc":10,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999492,"instruction":"BR_FALSE","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999460,"instruction":"MOVE_LOC","pc":12,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999428,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":true}}}}},{"Instruction":{"gas_left":999999426,"instruction":"BRANCH","pc":14,"type_parameters":[]}},{"Instruction":{"gas_left":999999394,"instruction":"MOVE_LOC","pc":17,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":true}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999392,"instruction":"BR_FALSE","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999390,"instruction":"BRANCH","pc":19,"type_parameters":[]}},{"Instruction":{"gas_left":999998751,"instruction":"RET","pc":22,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999998751,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__nested_struct_reference_mutation.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__nested_struct_reference_mutation.json new file mode 100644 index 00000000000..ae31124c175 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__nested_struct_reference_mutation.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":5,"frame_id":0,"function_name":"nested_struct_reference_mutation","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_U64","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999994,"instruction":"LD_U64","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999992,"instruction":"LD_U64","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999890,"instruction":"PACK_GENERIC","pc":4,"type_parameters":["u64"]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}}}}},{"Instruction":{"gas_left":999999734,"instruction":"PACK_GENERIC","pc":5,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}}}}},{"Instruction":{"gas_left":999999524,"instruction":"PACK_GENERIC","pc":6,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999384,"instruction":"ST_LOC","pc":7,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Instruction":{"gas_left":999999382,"instruction":"IMM_BORROW_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999380,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":9,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999378,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":10,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999376,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":11,"type_parameters":["u64"]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999344,"instruction":"READ_REF","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999342,"instruction":"LD_U64","pc":13,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999278,"instruction":"EQ","pc":14,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999276,"instruction":"BR_FALSE","pc":15,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999274,"instruction":"BRANCH","pc":16,"type_parameters":[]}},{"Instruction":{"gas_left":999999271,"instruction":"MUT_BORROW_LOC","pc":23,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999269,"instruction":"MUT_BORROW_FIELD_GENERIC","pc":24,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999999269,"instruction":"CALL","pc":25,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":6,"frame_id":56,"function_name":"l0","is_native":false,"locals_types":[{"ref_type":"Mut","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}],"return_types":[],"type_instantiation":[]},"gas_left":999999269}},{"Instruction":{"gas_left":999996987,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[56,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999996985,"instruction":"MUT_BORROW_FIELD_GENERIC","pc":1,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999996985,"instruction":"CALL","pc":2,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":7,"frame_id":64,"function_name":"l1","is_native":false,"locals_types":[{"ref_type":"Mut","type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}],"return_types":[],"type_instantiation":[]},"gas_left":999996985}},{"Instruction":{"gas_left":999994703,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[64,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999994701,"instruction":"MUT_BORROW_FIELD_GENERIC","pc":1,"type_parameters":["u64"]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999994701,"instruction":"CALL","pc":2,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":8,"frame_id":72,"function_name":"incr","is_native":false,"locals_types":[{"ref_type":"Mut","type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}],"return_types":[],"type_instantiation":[]},"gas_left":999994701}},{"Instruction":{"gas_left":999992419,"instruction":"COPY_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[72,0]},"moved":false,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999992387,"instruction":"READ_REF","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999992385,"instruction":"LD_U64","pc":2,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999992383,"instruction":"ADD","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999992367,"instruction":"MOVE_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[72,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999992335,"instruction":"WRITE_REF","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":3,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Instruction":{"gas_left":999991696,"instruction":"RET","pc":6,"type_parameters":[]}},{"CloseFrame":{"frame_id":72,"gas_left":999991696,"return_":[]}},{"Instruction":{"gas_left":999991057,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":64,"gas_left":999991057,"return_":[]}},{"Instruction":{"gas_left":999990418,"instruction":"RET","pc":3,"type_parameters":[]}},{"CloseFrame":{"frame_id":56,"gas_left":999990418,"return_":[]}},{"Instruction":{"gas_left":999990416,"instruction":"IMM_BORROW_LOC","pc":26,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990414,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":27,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990412,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":28,"type_parameters":[{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"Y","type_args":["u64"]}}]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990410,"instruction":"IMM_BORROW_FIELD_GENERIC","pc":29,"type_parameters":["u64"]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Instruction":{"gas_left":999990378,"instruction":"READ_REF","pc":30,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"snapshot":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Indexed":[{"Indexed":[{"Local":[0,0]},1]},1]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"x":1,"y":{"fields":{"x":2,"y":{"fields":{"x":4,"y":4},"type":"0x1::references::Y"}},"type":"0x1::references::Y<0x1::references::Y>"}},"type":"0x1::references::Y<0x1::references::Y<0x1::references::Y>>"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999990376,"instruction":"LD_U64","pc":31,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999990312,"instruction":"EQ","pc":32,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999990310,"instruction":"BR_FALSE","pc":33,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999990308,"instruction":"BRANCH","pc":34,"type_parameters":[]}},{"Instruction":{"gas_left":999989669,"instruction":"RET","pc":41,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999989669,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__pass_mut_assign_in_other_fn.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__pass_mut_assign_in_other_fn.json new file mode 100644 index 00000000000..765d28809cb --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__pass_mut_assign_in_other_fn.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":0,"frame_id":0,"function_name":"pass_mut_assign_in_other_fn","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999999966,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":0}}}}},{"Instruction":{"gas_left":999999963,"instruction":"MUT_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":0}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}},{"Instruction":{"gas_left":999999961,"instruction":"LD_U64","pc":3,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999959,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999959,"instruction":"CALL","pc":5,"type_parameters":[]}},{"OpenFrame":{"frame":{"binary_member_index":1,"frame_id":14,"function_name":"assign_add","is_native":false,"locals_types":[{"ref_type":"Mut","type_":"u64"},{"ref_type":null,"type_":"u64"},{"ref_type":null,"type_":"u64"}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}},{"RuntimeValue":{"value":1}},{"RuntimeValue":{"value":2}}],"return_types":[],"type_instantiation":[]},"gas_left":999999959}},{"Instruction":{"gas_left":999995395,"instruction":"MOVE_LOC","pc":0,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,1]},"moved":true,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999995363,"instruction":"MOVE_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,2]},"moved":true,"root_value_read":{"RuntimeValue":{"value":2}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999995361,"instruction":"ADD","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999995345,"instruction":"MOVE_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[14,0]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}},{"Instruction":{"gas_left":999995313,"instruction":"WRITE_REF","pc":4,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":0}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"gas_left":999994674,"instruction":"RET","pc":5,"type_parameters":[]}},{"CloseFrame":{"frame_id":14,"gas_left":999994674,"return_":[]}},{"Instruction":{"gas_left":999994642,"instruction":"MOVE_LOC","pc":6,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":true,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999994640,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999994576,"instruction":"EQ","pc":8,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994574,"instruction":"BR_FALSE","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999994572,"instruction":"BRANCH","pc":10,"type_parameters":[]}},{"Instruction":{"gas_left":999993933,"instruction":"RET","pc":13,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999993933,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_struct_borrow.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_struct_borrow.json new file mode 100644 index 00000000000..6076e89f639 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_struct_borrow.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":2,"frame_id":0,"function_name":"test_struct_borrow","is_native":false,"locals_types":[{"ref_type":null,"type_":{"struct":{"address":"0000000000000000000000000000000000000000000000000000000000000001","module":"references","name":"X","type_args":[]}}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999996,"instruction":"LD_FALSE","pc":1,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":false}}}},{"Instruction":{"gas_left":999999894,"instruction":"PACK","pc":2,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":false}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Instruction":{"gas_left":999999826,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}}},{"Instruction":{"gas_left":999999824,"instruction":"IMM_BORROW_LOC","pc":4,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Instruction":{"gas_left":999999822,"instruction":"IMM_BORROW_FIELD","pc":5,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Instruction":{"gas_left":999999790,"instruction":"READ_REF","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,0]},0]},"snapshot":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,0]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":{"fields":{"pos0":1,"pos1":false},"type":"0x1::references::X"}}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999788,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999724,"instruction":"EQ","pc":8,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999722,"instruction":"BR_FALSE","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999999720,"instruction":"BRANCH","pc":10,"type_parameters":[]}},{"Instruction":{"gas_left":999999081,"instruction":"RET","pc":13,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999999081,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow.json new file mode 100644 index 00000000000..10cba16aeb1 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":3,"frame_id":0,"function_name":"test_vector_mut_borrow","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":"Mut","type_":"u64"},{"ref_type":null,"type_":{"vector":"u64"}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999966,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999963,"instruction":"MUT_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999947,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Instruction":{"gas_left":999999945,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999929,"instruction":"COPY_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999897,"instruction":"WRITE_REF","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999999895,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999879,"instruction":"COPY_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Instruction":{"gas_left":999999847,"instruction":"WRITE_REF","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"gas_left":999999831,"instruction":"COPY_LOC","pc":10,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Instruction":{"gas_left":999999799,"instruction":"READ_REF","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999714,"instruction":"VEC_PACK","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":[3]}}}},{"Instruction":{"gas_left":999999698,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[3]}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":[3]}}}}},{"Instruction":{"gas_left":999999696,"instruction":"LD_U64","pc":14,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999693,"instruction":"MUT_BORROW_LOC","pc":15,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[3]}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999999691,"instruction":"LD_U64","pc":16,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999997788,"instruction":"VEC_MUT_BORROW","pc":17,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999997756,"instruction":"WRITE_REF","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,2]},0]},"root_value_after_write":{"RuntimeValue":{"value":[4]}}}}},{"Instruction":{"gas_left":999997754,"instruction":"IMM_BORROW_LOC","pc":19,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999997752,"instruction":"LD_U64","pc":20,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999996417,"instruction":"VEC_IMM_BORROW","pc":21,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999996385,"instruction":"READ_REF","pc":22,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,2]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996383,"instruction":"LD_U64","pc":23,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996319,"instruction":"EQ","pc":24,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996317,"instruction":"BR_FALSE","pc":25,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996315,"instruction":"BRANCH","pc":26,"type_parameters":[]}},{"Instruction":{"gas_left":999996299,"instruction":"MOVE_LOC","pc":31,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Instruction":{"gas_left":999996267,"instruction":"READ_REF","pc":32,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999996265,"instruction":"LD_U64","pc":33,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999996201,"instruction":"EQ","pc":34,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996199,"instruction":"BR_FALSE","pc":35,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996197,"instruction":"BRANCH","pc":36,"type_parameters":[]}},{"Instruction":{"gas_left":999995558,"instruction":"RET","pc":39,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999995558,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow_pop.json b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow_pop.json new file mode 100644 index 00000000000..40468e125fc --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/saved_traces/0x1__references__test_vector_mut_borrow_pop.json @@ -0,0 +1 @@ +{"events":[{"OpenFrame":{"frame":{"binary_member_index":4,"frame_id":0,"function_name":"test_vector_mut_borrow_pop","is_native":false,"locals_types":[{"ref_type":null,"type_":"u64"},{"ref_type":"Mut","type_":"u64"},{"ref_type":null,"type_":{"vector":"u64"}}],"module":{"address":"0000000000000000000000000000000000000000000000000000000000000001","name":"references"},"parameters":[],"return_types":[],"type_instantiation":[]},"gas_left":1000000000}},{"Instruction":{"gas_left":999999998,"instruction":"LD_U64","pc":0,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":1}}}},{"Instruction":{"gas_left":999999966,"instruction":"ST_LOC","pc":1,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":1}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":1}}}}},{"Instruction":{"gas_left":999999963,"instruction":"MUT_BORROW_LOC","pc":2,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999947,"instruction":"ST_LOC","pc":3,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Write":{"location":{"Local":[0,1]},"root_value_after_write":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Instruction":{"gas_left":999999945,"instruction":"LD_U64","pc":4,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":2}}}},{"Instruction":{"gas_left":999999929,"instruction":"COPY_LOC","pc":5,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Instruction":{"gas_left":999999897,"instruction":"WRITE_REF","pc":6,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":1}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":2}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":2}}}}},{"Instruction":{"gas_left":999999895,"instruction":"LD_U64","pc":7,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999879,"instruction":"COPY_LOC","pc":8,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":false,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Instruction":{"gas_left":999999847,"instruction":"WRITE_REF","pc":9,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":2}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Write":{"location":{"Local":[0,0]},"root_value_after_write":{"RuntimeValue":{"value":3}}}}},{"Instruction":{"gas_left":999999831,"instruction":"MOVE_LOC","pc":10,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,1]},"moved":true,"root_value_read":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Instruction":{"gas_left":999999799,"instruction":"READ_REF","pc":11,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,0]},"snapshot":3}}}},{"Effect":{"Read":{"location":{"Local":[0,0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":3}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":3}}}},{"Instruction":{"gas_left":999999714,"instruction":"VEC_PACK","pc":12,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":3}}}},{"Effect":{"Push":{"RuntimeValue":{"value":[3]}}}},{"Instruction":{"gas_left":999999698,"instruction":"ST_LOC","pc":13,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":[3]}}}},{"Effect":{"Write":{"location":{"Local":[0,2]},"root_value_after_write":{"RuntimeValue":{"value":[3]}}}}},{"Instruction":{"gas_left":999999696,"instruction":"LD_U64","pc":14,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999999693,"instruction":"MUT_BORROW_LOC","pc":15,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[3]}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999999691,"instruction":"LD_U64","pc":16,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999997788,"instruction":"VEC_MUT_BORROW","pc":17,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[3]}}}},{"Effect":{"Push":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Instruction":{"gas_left":999997756,"instruction":"WRITE_REF","pc":18,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[3]}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Write":{"location":{"Indexed":[{"Local":[0,2]},0]},"root_value_after_write":{"RuntimeValue":{"value":[4]}}}}},{"Instruction":{"gas_left":999997754,"instruction":"IMM_BORROW_LOC","pc":19,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999997752,"instruction":"LD_U64","pc":20,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":0}}}},{"Instruction":{"gas_left":999996417,"instruction":"VEC_IMM_BORROW","pc":21,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":0}}}},{"Effect":{"Pop":{"ImmRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Effect":{"Push":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999996385,"instruction":"READ_REF","pc":22,"type_parameters":[]}},{"Effect":{"Pop":{"ImmRef":{"location":{"Indexed":[{"Local":[0,2]},0]},"snapshot":[4]}}}},{"Effect":{"Read":{"location":{"Indexed":[{"Local":[0,2]},0]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996383,"instruction":"LD_U64","pc":23,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996319,"instruction":"EQ","pc":24,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996317,"instruction":"BR_FALSE","pc":25,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996315,"instruction":"BRANCH","pc":26,"type_parameters":[]}},{"Instruction":{"gas_left":999996312,"instruction":"MUT_BORROW_LOC","pc":29,"type_parameters":[]}},{"Effect":{"Read":{"location":{"Local":[0,2]},"moved":false,"root_value_read":{"RuntimeValue":{"value":[4]}}}}},{"Effect":{"Push":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Instruction":{"gas_left":999996084,"instruction":"VEC_POP_BACK","pc":30,"type_parameters":[]}},{"Effect":{"Pop":{"MutRef":{"location":{"Local":[0,2]},"snapshot":[4]}}}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996082,"instruction":"LD_U64","pc":31,"type_parameters":[]}},{"Effect":{"Push":{"RuntimeValue":{"value":4}}}},{"Instruction":{"gas_left":999996018,"instruction":"EQ","pc":32,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Pop":{"RuntimeValue":{"value":4}}}},{"Effect":{"Push":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996016,"instruction":"BR_FALSE","pc":33,"type_parameters":[]}},{"Effect":{"Pop":{"RuntimeValue":{"value":true}}}},{"Instruction":{"gas_left":999996014,"instruction":"BRANCH","pc":34,"type_parameters":[]}},{"Instruction":{"gas_left":999995375,"instruction":"RET","pc":37,"type_parameters":[]}},{"CloseFrame":{"frame_id":0,"gas_left":999995375,"return_":[]}}],"version":1} \ No newline at end of file diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/calls.move b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/calls.move new file mode 100644 index 00000000000..ead1f74736b --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/calls.move @@ -0,0 +1,75 @@ +module 0x1::calls { + const A: u64 = 1; + const B: vector = vector[1,2,3]; + + public struct X has drop { + x: u64, + y: bool, + } + + public struct Y has drop { + x: A, + y: B, + } + + #[test] + fun test_call_order() { + let a = 1u64; + let b = true; + let c = 1u8; + f_test_call_order(a, b, c); + } + + fun f_test_call_order(_x: u64, _b: bool, _c: u8) { } + + #[test] + fun test_return_order() { + let (a, b, c) = f_test_return_order(); + assert!(c == 0u8, a); + assert!(b, a); + } + + fun f_test_return_order(): (u64, bool, u8) { + (1, true, 0u8) + } + + #[test] + fun test_call_return_order() { + let (a, b, c) = f_test_return_order(); + f_test_call_order(a, b, c); + } + + #[test] + fun test_complex_nested_calls() { + f() + } + + fun f() { + let x = k() + 1; + if (x > 0) g(x) + } + + fun k(): u64 { + 1 + } + + fun g(x: u64) { + let y = x as u8; + let _ = B; + let x = X { x: A, y: true }; + let j = Y { x, y: true }; + h(i(j)); + h(y) + } + + fun h(_y: u8) { } + + fun i(y: Y): u8 { + let Y { x: _, y: _ } = y; + let x = &1; + let _h = *x; + let j = &mut 1; + *j = 2; + *j + } +} diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/errors.move b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/errors.move new file mode 100644 index 00000000000..bf76d79c88c --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/errors.move @@ -0,0 +1,50 @@ +module 0x1::errors { + #[test] + #[expected_failure] + fun aborter() { + let x = 1 + 1; + abort x + } + + #[test] + #[expected_failure] + fun div_0() { + 1/0; + } + + #[test] + #[expected_failure] + fun underflow() { + 1 - 10; + } + + #[test] + #[expected_failure] + fun bad_cast() { + 256u64 as u8; + } + + #[test] + #[expected_failure] + fun overshift_l() { + 1u8 << 20; + } + + #[test] + #[expected_failure] + fun overshift_r() { + 1u8 << 20; + } + + #[test] + #[expected_failure] + fun fail_during_abort() { + abort 1/0 + } + + #[test] + #[expected_failure] + fun fail_in_native() { + std::string::internal_sub_string_for_testing(&vector[1, 2, 3], 4, 1); + } +} diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/natives.move b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/natives.move new file mode 100644 index 00000000000..d48eb04a24e --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/natives.move @@ -0,0 +1,17 @@ +module 0x1::natives { + public struct X() has drop; + + #[test] + fun get_type_name_test() { + let x = std::type_name::get(); + let _t = x.borrow_string(); + let _t = x.into_string(); + } + + #[test] + fun get_orig_type_name_test() { + let x = std::type_name::get_with_original_ids(); + let _t = x.borrow_string(); + let _t = x.into_string(); + } +} diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/references.move b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/references.move new file mode 100644 index 00000000000..c1451a4ad97 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/references.move @@ -0,0 +1,74 @@ +module 0x1::references { + + #[test] + fun pass_mut_assign_in_other_fn() { + let x = 1; + let y = 2; + let mut res = 0; + assign_add(&mut res, x, y); + assert!(res == 3); + } + + fun assign_add(x: &mut u64, a: u64, b: u64) { + *x = a + b; + } + + public struct X(u64, bool) has drop; + + #[test] + fun test_struct_borrow() { + let x = &X(1, false); + assert!(x.0 == 1); + } + + #[test] + fun test_vector_mut_borrow() { + let x = &mut 1; + *x = 2; + *x = 3; + let mut y = vector[*x]; + *y.borrow_mut(0) = 4; + assert!(*y.borrow(0) == 4, 42); + assert!(*x == 3, 42) + } + + #[test] + fun test_vector_mut_borrow_pop() { + let x = &mut 1; + *x = 2; + *x = 3; + let mut y = vector[*x]; + *y.borrow_mut(0) = 4; + assert!(*y.borrow(0) == 4); + assert!(y.pop_back() == 4); + } + + public struct Y { + x: u64, + y: T, + } has drop; + + #[test] + fun nested_struct_reference_mutation() { + let mut y = Y { x: 1, y: Y { x: 2, y: Y { x: 3, y: 4 } } }; + + assert!(y.y.y.x == 3, y.y.y.x); + + let l0 = &mut y.y; + l0(l0); + assert!(y.y.y.x == 4, y.y.y.x); + } + + fun l0(x: &mut Y>){ + l1(&mut x.y); + } + + fun l1(x: &mut Y){ + incr(&mut x.x); + } + + fun incr(a: &mut u64) { + *a = *a + 1; + } +} + diff --git a/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/structs.move b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/structs.move new file mode 100644 index 00000000000..93bbf285181 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_tests/tracing-unit-tests/sources/structs.move @@ -0,0 +1,44 @@ +module 0x1::packs { + + public struct X(u64, bool, u8) has drop; + + public struct GenX(A, B, C) has drop; + + #[test] + fun test_pack_order() { + let a = 1; + let b = true; + let c = 0u8; + let x = X(a, b, c); + assert!(x.2 == 0u8, x.0); + } + + #[test] + fun test_unpack_order() { + let a = 1; + let b = true; + let c = 0u8; + let x = X(a, b, c); + let X(a, b, c) = x; + assert!(c == 0u8 && b, a); + } + + #[test] + fun test_gen_pack_order() { + let a = 1u64; + let b = true; + let c = 0u8; + let x = GenX(a, b, c); + assert!(x.2 == 0u8, x.0); + } + + #[test] + fun test_gen_unpack_order() { + let a = 1u64; + let b = true; + let c = 0u8; + let x = GenX(a, b, c); + let GenX(a, b, c) = x; + assert!(c == 0u8 && b, a); + } +} diff --git a/external-crates/move/crates/move-cli/tests/tracing_testsuite.rs b/external-crates/move/crates/move-cli/tests/tracing_testsuite.rs new file mode 100644 index 00000000000..d70274c26d0 --- /dev/null +++ b/external-crates/move/crates/move-cli/tests/tracing_testsuite.rs @@ -0,0 +1,27 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use std::path::Path; + +#[allow(unused_variables)] +fn run_all(args_path: &Path) -> datatest_stable::Result<()> { + #[cfg(feature = "tracing")] + { + use move_cli::sandbox::commands::test; + use std::path::PathBuf; + let cli_exe = env!("CARGO_BIN_EXE_move"); + let use_temp_dir = !args_path.parent().unwrap().join("NO_TEMPDIR").exists(); + test::run_one( + args_path, + &PathBuf::from(cli_exe), + /* use_temp_dir */ use_temp_dir, + /* track_cov */ false, + )?; + } + Ok(()) +} + +// runs all the tests +datatest_stable::harness!(run_all, "tests/tracing_tests", r"args\.txt$"); diff --git a/external-crates/move/crates/move-cli/tests/upload_tests/no_git_remote_package/sources/Dummy.move b/external-crates/move/crates/move-cli/tests/upload_tests/no_git_remote_package/sources/Dummy.move index 45646f1b13b..c2eff2a2272 100644 --- a/external-crates/move/crates/move-cli/tests/upload_tests/no_git_remote_package/sources/Dummy.move +++ b/external-crates/move/crates/move-cli/tests/upload_tests/no_git_remote_package/sources/Dummy.move @@ -1 +1 @@ -module 0x1::Dummy {} +module 0x6::Dummy {} diff --git a/external-crates/move/crates/move-cli/tests/upload_tests/valid_package1/sources/Dummy.move b/external-crates/move/crates/move-cli/tests/upload_tests/valid_package1/sources/Dummy.move index 45646f1b13b..c2eff2a2272 100644 --- a/external-crates/move/crates/move-cli/tests/upload_tests/valid_package1/sources/Dummy.move +++ b/external-crates/move/crates/move-cli/tests/upload_tests/valid_package1/sources/Dummy.move @@ -1 +1 @@ -module 0x1::Dummy {} +module 0x6::Dummy {} diff --git a/external-crates/move/crates/move-cli/tests/upload_tests/valid_package2/sources/Dummy.move b/external-crates/move/crates/move-cli/tests/upload_tests/valid_package2/sources/Dummy.move index 45646f1b13b..c2eff2a2272 100644 --- a/external-crates/move/crates/move-cli/tests/upload_tests/valid_package2/sources/Dummy.move +++ b/external-crates/move/crates/move-cli/tests/upload_tests/valid_package2/sources/Dummy.move @@ -1 +1 @@ -module 0x1::Dummy {} +module 0x6::Dummy {} diff --git a/external-crates/move/crates/move-cli/tests/upload_tests/valid_package3/sources/Dummy.move b/external-crates/move/crates/move-cli/tests/upload_tests/valid_package3/sources/Dummy.move index 45646f1b13b..c2eff2a2272 100644 --- a/external-crates/move/crates/move-cli/tests/upload_tests/valid_package3/sources/Dummy.move +++ b/external-crates/move/crates/move-cli/tests/upload_tests/valid_package3/sources/Dummy.move @@ -1 +1 @@ -module 0x1::Dummy {} +module 0x6::Dummy {} diff --git a/external-crates/move/crates/move-command-line-common/Cargo.toml b/external-crates/move/crates/move-command-line-common/Cargo.toml index e5a5fe5fcf8..f8cb3e0ba29 100644 --- a/external-crates/move/crates/move-command-line-common/Cargo.toml +++ b/external-crates/move/crates/move-command-line-common/Cargo.toml @@ -24,10 +24,4 @@ move-binary-format.workspace = true move-core-types.workspace = true [dev-dependencies] -# Ok to do this since: -# edition = 2021 ==> resolver = 2 -# * https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html#summary -# resolver = 2 ==> feature-resolver-version-2 which allows dev-dependencies to set features -# * https://doc.rust-lang.org/cargo/reference/resolver.html#feature-resolver-version-2 -move-core-types = { workspace = true, features = ["fuzzing"] } proptest.workspace = true diff --git a/external-crates/move/crates/move-command-line-common/src/files.rs b/external-crates/move/crates/move-command-line-common/src/files.rs index 37bf9833faf..6e3078eec44 100644 --- a/external-crates/move/crates/move-command-line-common/src/files.rs +++ b/external-crates/move/crates/move-command-line-common/src/files.rs @@ -8,7 +8,7 @@ use std::{collections::BTreeMap, path::Path}; use anyhow::{anyhow, bail, *}; use serde::{Deserialize, Serialize}; use sha2::Digest; -use vfs::{error::VfsErrorKind, VfsPath, VfsResult}; +use vfs::{VfsPath, VfsResult, error::VfsErrorKind}; /// Result of sha256 hash of a file's contents. #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] diff --git a/external-crates/move/crates/move-command-line-common/src/lib.rs b/external-crates/move/crates/move-command-line-common/src/lib.rs index a65ad4878dc..825dffeea36 100644 --- a/external-crates/move/crates/move-command-line-common/src/lib.rs +++ b/external-crates/move/crates/move-command-line-common/src/lib.rs @@ -5,14 +5,10 @@ #![forbid(unsafe_code)] -pub mod address; pub mod character_sets; pub mod display; pub mod env; pub mod error_bitset; pub mod files; pub mod interactive; -pub mod parser; pub mod testing; -pub mod types; -pub mod values; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.exp new file mode 100644 index 00000000000..b980699ad1b --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.exp @@ -0,0 +1,11 @@ +processed 2 tasks + +task 1, lines 6-11: +//# run +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(9223372079804448767), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.move new file mode 100644 index 00000000000..c9e4464e3ad --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/derived_line_number_raw_abort.move @@ -0,0 +1,11 @@ +// NB: Do _not_ change the number of lines in this file. Any changes to the +// number of lines in this file may break the expected output of this test. + +//# init --edition 2024.beta + +//# run +module 0x42::m { + fun f() { + abort + } +} diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.exp new file mode 100644 index 00000000000..760fa19edda --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.exp @@ -0,0 +1,21 @@ +processed 4 tasks + +task 2, line 25: +//# run 0x42::m::t_a +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(9223372105574252543), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3, line 27: +//# run 0x42::m::t_calls_a +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(9223372118459154431), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.move new file mode 100644 index 00000000000..fc2069b6d0a --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/constants/macro_call_line_number_abort.move @@ -0,0 +1,27 @@ +// NB: Do _not_ change the number of lines in this file. Any changes to the +// number of lines in this file may break the expected output of this test. + +//# init --edition 2024.beta + +//# publish +module 0x42::m { + macro fun a() { + abort + } + + macro fun calls_a() { + a!() + } + + entry fun t_a() { + a!() // assert should point to this line + } + + entry fun t_calls_a() { + calls_a!() // assert should point to this line + } +} + +//# run 0x42::m::t_a + +//# run 0x42::m::t_calls_a diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/assert_in_while.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/assert_in_while.move index 3d2b6cd2edd..542d8316479 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/assert_in_while.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/assert_in_while.move @@ -19,7 +19,7 @@ module 0x42::Test { } //# run -module 0x42::m { +module 0x43::m { use 0x42::Test; fun main() { let x = Test::new(); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/basic_named_blocks.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/basic_named_blocks.move index 8fd2a8bcd9b..ca65c01f38b 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/basic_named_blocks.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/basic_named_blocks.move @@ -67,7 +67,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t00() == 10, 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/if_assignment.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/if_assignment.move index 8b2caf9af2e..34432dd7b8c 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/if_assignment.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/if_assignment.move @@ -11,7 +11,7 @@ module ReassignCond { } //# run -module 0x42::m { +module 0x43::m { use 0x42::ReassignCond::reassign_cond; fun main() { assert!(reassign_cond(@0x1, false) == @0x1, 42); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_blocks.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_blocks.move index c7f9e4505b6..2f058dd56ac 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_blocks.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_blocks.move @@ -106,7 +106,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t00() == 10, 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_loops.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_loops.move index 8c2da22652b..43bf8dd6b10 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_loops.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/nested_loops.move @@ -11,7 +11,7 @@ module 0x42::M { } //# run -module 0x42::m { +module 0x43::m { use 0x42::M; fun main() { diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move index 17bfb185b66..982096b42a9 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move @@ -7,7 +7,7 @@ module 0x42::Test { } //# run -module 0x42::m { +module 0x43::m { use 0x42::Test; fun main() { diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/unused_named_blocks.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/unused_named_blocks.move index e275a4700a6..b7c83354ec5 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/unused_named_blocks.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/control_flow/unused_named_blocks.move @@ -86,7 +86,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 10, 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/dependency_order.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/dependency_order.move index 213896bd5a4..93c5ec0c9bc 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/dependency_order.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/dependency_order.move @@ -8,14 +8,14 @@ module 0x42::C { //# publish // names used to try to force an ordering of depedencies -module 0x42::B { +module 0x43::B { public fun foo(): 0x42::C::T { 0x42::C::foo() } } //# publish -module 0x42::A { +module 0x44::A { struct T { t_b: 0x42::C::T, t_c: 0x42::C::T, @@ -23,7 +23,7 @@ module 0x42::A { public fun foo(): T { T { t_c: 0x42::C::foo(), - t_b: 0x42::B::foo() + t_b: 0x43::B::foo() } } } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/transitive_deps.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/transitive_deps.move index 7c54abb7633..244430d35ef 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/transitive_deps.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/dependencies/transitive_deps.move @@ -7,7 +7,7 @@ module 0x42::X { } //# publish -module 0x42::Y { +module 0x43::Y { use 0x42::X; public fun foo(): X::T { X::new() @@ -16,8 +16,8 @@ module 0x42::Y { //# run -module 0x42::m { -use 0x42::Y; +module 0x44::m { +use 0x43::Y; fun main() { Y::foo(); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.exp index 6974f42fec4..f7b3b56aaaf 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.exp +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.exp @@ -5,7 +5,7 @@ task 1, lines 14-20: Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(2), - location: 0x42::test0, + location: 0x43::test0, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -25,7 +25,7 @@ task 3, lines 31-37: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x42::test2, + location: 0x45::test2, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -35,7 +35,7 @@ task 4, lines 39-45: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x42::test3, + location: 0x46::test3, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 5, lines 47-53: Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), - location: 0x42::test4, + location: 0x47::test4, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -55,7 +55,7 @@ task 6, lines 55-61: Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), - location: 0x42::test5, + location: 0x48::test5, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -65,7 +65,7 @@ task 7, lines 63-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x42::test37, + location: 0x49::test37, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.move index bd43a4707e2..c8c856eb5b5 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_aborts.move @@ -12,7 +12,7 @@ module 0x42::m { // All of these should abort //# run -module 0x42::test0 { +module 0x43::test0 { // abort with 2 public fun main(): u64 { if (false) {0x42::m::aborter(1)} else {abort 2} + {abort 3; 0} @@ -20,7 +20,7 @@ module 0x42::test0 { } //# run -module 0x42::test1 { +module 0x44::test1 { // abort with 1 public fun main(): u64 { let x = 1; @@ -29,7 +29,7 @@ module 0x42::test1 { } //# run -module 0x42::test2 { +module 0x45::test2 { // aborts with bad math public fun main(): u8 { abort (1u64 - 10u64) @@ -37,7 +37,7 @@ module 0x42::test2 { } //# run -module 0x42::test3 { +module 0x46::test3 { // aborts with bad math public fun main(): u8 { {250u8 + 50u8} + {abort 55; 5u8} @@ -45,7 +45,7 @@ module 0x42::test3 { } //# run -module 0x42::test4 { +module 0x47::test4 { // aborts with 0 public fun test(): u64 { 0x42::m::add3(abort 0, {abort 14; 0}, 0) @@ -53,7 +53,7 @@ module 0x42::test4 { } //# run -module 0x42::test5 { +module 0x48::test5 { //abort with 0 public fun test(): u64 { (abort 0) + {(abort 14); 0} + 0 @@ -61,7 +61,7 @@ module 0x42::test5 { } //# run -module 0x42::test37 { +module 0x49::test37 { // aborts with bad math public fun main(): u8 { {250u8 + 50u8} + {return 55; 5u8} diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_call_struct.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_call_struct.move index 40376a28533..849ab7c8829 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_call_struct.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_call_struct.move @@ -71,24 +71,24 @@ module 0x42::m { } //# run -module 0x042::test1 { public fun main() { assert!(0x42::m::test1() == 6, 1); } } +module 0x043::test1 { public fun main() { assert!(0x42::m::test1() == 6, 1); } } //# run -module 0x042::test2 { public fun main() { assert!(0x42::m::test2() == 20, 2); } } +module 0x044::test2 { public fun main() { assert!(0x42::m::test2() == 20, 2); } } //# run -module 0x042::test3 { public fun main() { assert!(0x42::m::test3() == 6, 3); } } +module 0x045::test3 { public fun main() { assert!(0x42::m::test3() == 6, 3); } } //# run -module 0x042::test4 { public fun main() { assert!(0x42::m::test4() == 6, 4); } } +module 0x046::test4 { public fun main() { assert!(0x42::m::test4() == 6, 4); } } //# run -module 0x042::test5 { public fun main() { assert!(0x42::m::test5() == 6, 5); } } +module 0x047::test5 { public fun main() { assert!(0x42::m::test5() == 6, 5); } } //# run -module 0x042::test6 { public fun main() { assert!(0x42::m::test6() == 28, 6); } } +module 0x048::test6 { public fun main() { assert!(0x42::m::test6() == 28, 6); } } //# run -module 0x042::test7 { public fun main() { assert!(0x42::m::test7() == 6, 7); } } +module 0x049::test7 { public fun main() { assert!(0x42::m::test7() == 6, 7); } } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_calls.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_calls.move index 4199dba601b..b5e8541c653 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_calls.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/binop_calls.move @@ -234,119 +234,119 @@ module 0x42::m { // Run the tests separately so that we get all the results //# run -module 0x42::test00 { public fun main() { assert!(0x42::m::test00() == 3, 0); } } +module 0x43::test00 { public fun main() { assert!(0x42::m::test00() == 3, 0); } } //# run -module 0x42::test01 { public fun main() { assert!(0x42::m::test01() == true, 1); } } +module 0x44::test01 { public fun main() { assert!(0x42::m::test01() == true, 1); } } //# run -module 0x42::test02 { public fun main() { assert!(0x42::m::test02() == 31, 2); } } +module 0x45::test02 { public fun main() { assert!(0x42::m::test02() == 31, 2); } } //# run -module 0x42::test03 { public fun main() { assert!(0x42::m::test03() == 27, 3); } } +module 0x46::test03 { public fun main() { assert!(0x42::m::test03() == 27, 3); } } //# run -module 0x42::test04 { public fun main() { assert!(0x42::m::test04() == 27, 4); } } +module 0x47::test04 { public fun main() { assert!(0x42::m::test04() == 27, 4); } } //# run -module 0x42::test05 { public fun main() { assert!(0x42::m::test05() == 14, 5); } } +module 0x48::test05 { public fun main() { assert!(0x42::m::test05() == 14, 5); } } //# run -module 0x42::test06 { public fun main() { assert!(0x42::m::test06() == 37, 6); } } +module 0x49::test06 { public fun main() { assert!(0x42::m::test06() == 37, 6); } } //# run -module 0x42::test07 { public fun main() { assert!(0x42::m::test07() == 20, 7); } } +module 0x4a::test07 { public fun main() { assert!(0x42::m::test07() == 20, 7); } } //# run -module 0x42::test08 { public fun main() { assert!(0x42::m::test08() == 962, 8); } } +module 0x4b::test08 { public fun main() { assert!(0x42::m::test08() == 962, 8); } } //# run -module 0x42::test09 { public fun main() { assert!(0x42::m::test09() == 890, 9); } } +module 0x4c::test09 { public fun main() { assert!(0x42::m::test09() == 890, 9); } } //# run -module 0x42::test10 { public fun main() { assert!(0x42::m::test10() == 746, 10); } } +module 0x4d::test10 { public fun main() { assert!(0x42::m::test10() == 746, 10); } } //# run -module 0x42::test11 { public fun main() { assert!(0x42::m::test11() == 1, 11); } } +module 0x4e::test11 { public fun main() { assert!(0x42::m::test11() == 1, 11); } } //# run -module 0x42::test12 { public fun main() { assert!(0x42::m::test12() == 4, 12); } } +module 0x4f::test12 { public fun main() { assert!(0x42::m::test12() == 4, 12); } } //# run -module 0x42::test13 { public fun main() { assert!(0x42::m::test13() == 29, 13); } } +module 0x50::test13 { public fun main() { assert!(0x42::m::test13() == 29, 13); } } //# run -module 0x42::test14 { public fun main() { assert!(0x42::m::test14() == 15, 14); } } +module 0x51::test14 { public fun main() { assert!(0x42::m::test14() == 15, 14); } } //# run -module 0x42::test15 { public fun main() { assert!(0x42::m::test15() == 19, 15); } } +module 0x52::test15 { public fun main() { assert!(0x42::m::test15() == 19, 15); } } //# run -module 0x42::test16 { public fun main() { assert!(0x42::m::test16() == 20, 16); } } +module 0x53::test16 { public fun main() { assert!(0x42::m::test16() == 20, 16); } } //# run -module 0x42::test17 { public fun main() { assert!(0x42::m::test17(54) == 168, 17); } } +module 0x54::test17 { public fun main() { assert!(0x42::m::test17(54) == 168, 17); } } //# run -module 0x42::test18 { public fun main() { assert!(0x42::m::test18(true) == 6, 18); } } +module 0x55::test18 { public fun main() { assert!(0x42::m::test18(true) == 6, 18); } } //# run -module 0x42::test19 { public fun main() { assert!(0x42::m::test18(false) == 6, 18); } } +module 0x56::test19 { public fun main() { assert!(0x42::m::test18(false) == 6, 18); } } //# run -module 0x42::test20 { public fun main() { assert!(0x42::m::test19() == 28, 18); } } +module 0x57::test20 { public fun main() { assert!(0x42::m::test19() == 28, 18); } } //# run -module 0x42::test21 { public fun main() { assert!(0x42::m::test20(true) == true, 20); } } +module 0x58::test21 { public fun main() { assert!(0x42::m::test20(true) == true, 20); } } //# run -module 0x42::test22 { public fun main() { assert!(0x42::m::test20(false) == false, 20); } } +module 0x59::test22 { public fun main() { assert!(0x42::m::test20(false) == false, 20); } } //# run -module 0x42::test23 { public fun main() { assert!(0x42::m::test21() == true, 21); } } +module 0x5a::test23 { public fun main() { assert!(0x42::m::test21() == true, 21); } } //# run -module 0x42::test24 { public fun main() { assert!(0x42::m::test22(3) == vector[3,4,5], 22); } } +module 0x5b::test24 { public fun main() { assert!(0x42::m::test22(3) == vector[3,4,5], 22); } } //# run -module 0x42::test25 { public fun main() { assert!(0x42::m::test23() == 6, 23); } } +module 0x5c::test25 { public fun main() { assert!(0x42::m::test23() == 6, 23); } } //# run -module 0x42::test26 { public fun main() { assert!(0x42::m::test24() == 39, 24); } } +module 0x5d::test26 { public fun main() { assert!(0x42::m::test24() == 39, 24); } } //# run -module 0x42::test27 { public fun main() { assert!(0x42::m::test25() == 99, 25); } } +module 0x5e::test27 { public fun main() { assert!(0x42::m::test25() == 99, 25); } } //# run -module 0x42::test28 { public fun main() { assert!(0x42::m::test26() == 9, 26); } } +module 0x5f::test28 { public fun main() { assert!(0x42::m::test26() == 9, 26); } } //# run -module 0x42::test29 { public fun main() { assert!(0x42::m::test27() == 6, 27); } } +module 0x60::test29 { public fun main() { assert!(0x42::m::test27() == 6, 27); } } //# run -module 0x42::test30 { public fun main() { assert!(0x42::m::test28() == 28, 28); } } +module 0x61::test30 { public fun main() { assert!(0x42::m::test28() == 28, 28); } } //# run -module 0x42::test31 { public fun main() { assert!(0x42::m::test29() == 11, 29); } } +module 0x62::test31 { public fun main() { assert!(0x42::m::test29() == 11, 29); } } //# run -module 0x42::test32 { public fun main() { assert!(0x42::m::test30() == 8, 30); } } +module 0x63::test32 { public fun main() { assert!(0x42::m::test30() == 8, 30); } } //# run -module 0x42::test33 { public fun main() { assert!(0x42::m::test31() == 6, 31); } } +module 0x64::test33 { public fun main() { assert!(0x42::m::test31() == 6, 31); } } //# run -module 0x42::test34 { public fun main() { assert!(0x42::m::test32() == 7, 32); } } +module 0x65::test34 { public fun main() { assert!(0x42::m::test32() == 7, 32); } } //# run -module 0x42::test35 { public fun main() { assert!(0x42::m::test33() == 6, 33); } } +module 0x66::test35 { public fun main() { assert!(0x42::m::test33() == 6, 33); } } //# run -module 0x42::test36 { public fun main() { assert!(0x42::m::test34() == 1, 34); } } +module 0x67::test36 { public fun main() { assert!(0x42::m::test34() == 1, 34); } } //# run -module 0x42::test37 { public fun main() { assert!(0x42::m::test35() == 6, 35); } } +module 0x68::test37 { public fun main() { assert!(0x42::m::test35() == 6, 35); } } //# run -module 0x42::test38 { public fun main() { assert!(0x42::m::test36(1) == 4, 36); } } +module 0x69::test38 { public fun main() { assert!(0x42::m::test36(1) == 4, 36); } } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/macro_calls.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/macro_calls.move index c502215d644..31fc4f33bc7 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/macro_calls.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/macro_calls.move @@ -61,7 +61,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; public fun main() { diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting.move index 2be7d17b179..48c71c87abf 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting.move @@ -6,7 +6,7 @@ module 0x42::X { } //# run -module 0x42::m { +module 0x43::m { use 0x42::X; fun main() { let vtrue = true; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp index e8d63c87cbb..7084ceb74b2 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp @@ -45,7 +45,7 @@ task 5, lines 43-48: Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), - location: 0x6::m, + location: 0xb::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.move index b916d0197c1..87314184e8d 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/short_circuiting_invalid.move @@ -8,7 +8,7 @@ module 0x42::X { // all should abort //# run -module 2::m { +module 7::m { use 0x42::X; fun main() { false || X::error(); @@ -17,7 +17,7 @@ fun main() { //# run -module 3::m { +module 8::m { use 0x42::X; fun main() { true && X::error(); @@ -25,7 +25,7 @@ fun main() { } //# run -module 4::m { +module 9::m { use 0x42::X; fun main() { X::error() && false; @@ -33,7 +33,7 @@ fun main() { } //# run -module 5::m { +module 0xa::m { use 0x42::X; fun main() { X::error() || true; @@ -41,7 +41,7 @@ fun main() { } //# run -module 6::m { +module 0xb::m { fun main() { false || { abort 0 }; } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/struct_arguments.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/struct_arguments.move index c4aa1bb37e3..75c320034d1 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/struct_arguments.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/evaluation_order/struct_arguments.move @@ -38,7 +38,7 @@ module 0x42::M { } //# run -module 1::m { +module 6::m { use 0x42::M; fun main() { // arithmetic error @@ -47,7 +47,7 @@ fun main() { } //# run -module 2::m { +module 7::m { use 0x42::M; fun main() { // arithmetic error @@ -56,7 +56,7 @@ fun main() { } //# run -module 3::m { +module 8::m { use 0x42::M; fun main() { // arithmetic error @@ -65,7 +65,7 @@ fun main() { } //# run -module 4::m { +module 9::m { use 0x42::M; fun main() { // arithmetic error @@ -74,7 +74,7 @@ fun main() { } //# run -module 5::m { +module 0xa::m { use 0x42::M; fun main() { // arithmetic error diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.exp index f32b667741b..27d53946a00 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.exp +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.exp @@ -1,11 +1,15 @@ -processed 4 tasks +processed 5 tasks -task 2, line 34: +task 2, line 43: //# run 0x42::m::x1 return values: |0|{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -task 3, line 36: +task 3, line 45: //# run 0x42::m::x3 +return values: |1|{ 0 } + +task 4, line 47: +//# run 0x42::m::x4 Error: Function execution failed with VMError: { major_status: VERIFICATION_ERROR, sub_status: None, diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.move index 97813d424a5..121896afebc 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/functions/large_enum.move @@ -21,6 +21,11 @@ public enum X3 { U64(u64), } +public enum X4 { + X2(X3, X3, X3), + U64(u64), +} + entry fun x1(): X1 { X1::Big(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) } @@ -29,8 +34,14 @@ entry fun x3(): X3 { X3::U64(0) } +entry fun x4(): X4 { + X4::U64(0) +} + } //# run 0x42::m::x1 //# run 0x42::m::x3 + +//# run 0x42::m::x4 diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.exp index 318772f1fd2..b4c541ab835 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.exp +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.exp @@ -1,6 +1,6 @@ processed 4 tasks -task 2, line 26: +task 2, line 29: //# run 42::m::aborts0 Error: Function execution failed with VMError: { major_status: ABORTED, @@ -10,7 +10,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(0), 1)], } -task 3, line 28: +task 3, line 31: //# run 42::m::aborts1 Error: Function execution failed with VMError: { major_status: ABORTED, diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.move index 47b5cf4aaf2..41a2bce493b 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/macros/method_is_by_value_even_when_ignored.move @@ -12,14 +12,17 @@ module 42::m { macro fun macro_abort(_: X) { abort 2 } + // method syntax results in the macro arg being bound first before being passed to the method // meaning these should abort from the LHS not the macro. Even though the LHS is discarded + #[allow(dead_code)] fun aborts0() { - x_abort().macro_abort!(); + x_abort().macro_abort!() } + #[allow(dead_code)] fun aborts1() { - X().id_abort().macro_abort!(); + X().id_abort().macro_abort!() } } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match.move index f2fef14b652..d43af7f0680 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match.move @@ -21,7 +21,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { use 0x42::m::t0; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_binder.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_binder.move index 43f15561691..470d83c800b 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_binder.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_binder.move @@ -53,7 +53,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m::{a, b, c}; fun main() { assert!(a().t0().is_a(), 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_mut_ref.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_mut_ref.move index def0ff8c567..e38a388b085 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_mut_ref.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_mut_ref.move @@ -53,7 +53,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m::{a, b, c}; fun main() { let mut x = 43; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_no_drop.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_no_drop.move index 485d9ae7e0f..65d5d5b52ff 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_no_drop.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_no_drop.move @@ -19,7 +19,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { use 0x42::m::t0; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_ref.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_ref.move index dab2b9e3fc7..21bcaa15c32 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_ref.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_ref.move @@ -31,7 +31,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m::{a, b, c}; fun main() { let x = 43; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_twice.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_twice.move index 5522c27072d..0ea05706e20 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_twice.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_twice.move @@ -73,7 +73,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m::{a, b, c}; fun main() { let a = a().t0(); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_value_wildcard.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_value_wildcard.move index 8dc2bf151ff..88bdac79233 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_value_wildcard.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/abc_match_value_wildcard.move @@ -19,7 +19,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m::t0; fun main() { assert!(t0() == 0, 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/at_pattern_lit.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/at_pattern_lit.move index 500981296f7..0e3bbfe5df8 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/at_pattern_lit.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/at_pattern_lit.move @@ -13,7 +13,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t() == 10); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.move new file mode 100644 index 00000000000..fc8525f8dfe --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_0.move @@ -0,0 +1,27 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum E { + One { a: u64, b: u64, c: u64 }, + Two { d: u64, e: u64, f: u64 }, + } + + fun test() { + let e_0 = E::One { a: 0, b: 1, c: 2 }; + let x = match (e_0) { + E::One { c: a, b: b, a: c } => a + c * b, + E::Two { .. } => abort 0, + }; + assert!(x == 2); + let e_1 = E::Two { d: 0, e: 1, f: 2 }; + let x = match (e_1) { + E::Two { e: d, f: e, d: f } => d * e + f, + E::One { .. } => abort 0, + }; + assert!(x == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.move new file mode 100644 index 00000000000..301729babc1 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/awful_naming_1.move @@ -0,0 +1,26 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum E { + One { a: u64, b: u64, c: u64 }, + Two(u64, u64, u64) + } + + fun do(e: E): u64 { + match (e) { + E::One { c: a, b: c, a: b } | E::Two(c, b, a) => a * (b + c) + } + } + + + fun test() { + let e_0 = E::One { a: 0, b: 1, c: 2 }; + assert!(do(e_0) == 2); + let e_1 = E::Two(0, 1, 2); + assert!(do(e_1) == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_1.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_1.move index 4b17f2574a2..f7749cdbd0d 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_1.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_1.move @@ -23,7 +23,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 2); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_2.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_2.move index e9b41b4a71a..2034890d461 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_2.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bad_guard_2.move @@ -32,7 +32,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 2); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bind_subject.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bind_subject.move index 1cb8dc09caa..e096feec0f8 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bind_subject.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/bind_subject.move @@ -22,7 +22,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 3); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_at.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_at.move index 12a32f09b92..accc670a964 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_at.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_at.move @@ -18,7 +18,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { assert!(0x42::m::test() == 1, 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_in_guard.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_in_guard.move index 554ee7fcf27..a6af3009f23 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_in_guard.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_in_guard.move @@ -18,7 +18,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { assert!(0x42::m::test() == 0, 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_matching.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_matching.move index d490d2de1ec..83483820e80 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_matching.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_matching.move @@ -68,7 +68,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m::{t00, t01, t02, t03, t04, t05}; fun main() { diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_mut_guard.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_mut_guard.move index 4057beb9661..cca960b9e7e 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_mut_guard.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_mut_guard.move @@ -19,7 +19,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { assert!(0x42::m::test() == 0, 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_pair.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_pair.move index 46aa732480a..173ed79d06c 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_pair.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_pair.move @@ -21,7 +21,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_result.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_result.move index 469cd42f96a..c6d7dd57c6f 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_result.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_result.move @@ -63,7 +63,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_self.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_self.move index 76111a7d41e..7ac6bd13e80 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_self.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/const_self.move @@ -62,7 +62,7 @@ module 0x42::m { } //#run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/drop_ref.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/drop_ref.move index 136f1147024..c9f89e936c7 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/drop_ref.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/drop_ref.move @@ -32,7 +32,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { let f = m::f(); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_no_tyargs_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_no_tyargs_match.move index 44e40db0258..e40275f38cb 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_no_tyargs_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_no_tyargs_match.move @@ -20,7 +20,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_poly_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_poly_match.move index d47d86cdf34..f98e4e949dd 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_poly_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/enum_poly_match.move @@ -22,7 +22,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/exhaustive_struct.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/exhaustive_struct.move index 96a0e62ad73..6c0d69e5148 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/exhaustive_struct.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/exhaustive_struct.move @@ -47,7 +47,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t00() == 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/fib.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/fib.move index b7aacde4bc4..ef565c7cef2 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/fib.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/fib.move @@ -14,7 +14,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { use 0x42::m::fib; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/go_repro.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/go_repro.exp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard.move index ea5349c80f7..6b2d2ee80b4 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard.move @@ -21,7 +21,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 3); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack.move index 07f0d18bee2..4737f7ffd8a 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack.move @@ -24,7 +24,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t2() == 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_2.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_2.move index 90448c248a8..302911bbe20 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_2.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_2.move @@ -24,7 +24,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_3.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_3.move index 9cd461c9974..b6f5b0dac97 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_3.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_3.move @@ -31,7 +31,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_4.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_4.move index c296a00a77e..863d70f143c 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_4.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_4.move @@ -40,7 +40,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 1); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_5.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_5.move index 638584f64a2..89e33137e7d 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_5.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/guard_backtrack_5.move @@ -26,7 +26,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 6); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.move new file mode 100644 index 00000000000..c93dc36859e --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_0.move @@ -0,0 +1,35 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum E has drop { + A { a: vector }, + B { b: vector } + } + + #[syntax(index)] + fun e_index(e: &E, ndx: u64): &u64 { + match (e) { + E::A { a } => &a[ndx], + E::B { b } => &b[ndx], + } + } + + fun test() { + let e = E::A { a: vector[0,1,2,3,4] }; + assert!(e[0] == 0); + assert!(e[1] == 1); + assert!(e[2] == 2); + assert!(e[3] == 3); + assert!(e[4] == 4); + let e = E::B { b: vector[0,1,2,3,4] }; + assert!(e[0] == 0); + assert!(e[1] == 1); + assert!(e[2] == 2); + assert!(e[3] == 3); + assert!(e[4] == 4); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.move new file mode 100644 index 00000000000..3943c13738e --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_1.move @@ -0,0 +1,34 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum E has drop { + A { a: vector }, + B { b: vector } + } + + #[syntax(index)] + fun e_index(e: &E, ndx: u64): &u64 { + match (e) { + E::A { a } | E::B { b: a } => &a[ndx], + } + } + + fun test() { + let e = E::A { a: vector[0,1,2,3,4] }; + assert!(e[0] == 0); + assert!(e[1] == 1); + assert!(e[2] == 2); + assert!(e[3] == 3); + assert!(e[4] == 4); + let e = E::B { b: vector[0,1,2,3,4] }; + assert!(e[0] == 0); + assert!(e[1] == 1); + assert!(e[2] == 2); + assert!(e[3] == 3); + assert!(e[4] == 4); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.move new file mode 100644 index 00000000000..965a2a1627f --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/index_syntax_2.move @@ -0,0 +1,39 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum E has drop { + A { a: vector }, + B { b: vector } + } + + fun get_vec(e: &E): &vector { + match (e) { + E::A { a } => a, + E::B { b } => b, + } + } + + #[syntax(index)] + fun e_index(e: &E, ndx: u64): &u64 { + &e.get_vec()[ndx] + } + + fun test() { + let e = E::A { a: vector[0,1,2,3,4] }; + assert!(e[0] == 0); + assert!(e[1] == 1); + assert!(e[2] == 2); + assert!(e[3] == 3); + assert!(e[4] == 4); + let e = E::B { b: vector[0,1,2,3,4] }; + assert!(e[0] == 0); + assert!(e[1] == 1); + assert!(e[2] == 2); + assert!(e[3] == 3); + assert!(e[4] == 4); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.move new file mode 100644 index 00000000000..111d0963957 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_abort.move @@ -0,0 +1,19 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun from_index(index: u64): u64 { + match (index) { + 0 => 1, + 1 => 2, + 2 => 3, + _ => abort 0, + } + } + + public fun run() { + assert!(from_index(2) == 3) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_match.move index 010bc3ddba9..2b7dd140c81 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_match.move @@ -13,7 +13,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::fib(5) == 8); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_mut_borrow_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_mut_borrow_match.move index 8d190307582..0008dd9762b 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_mut_borrow_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/lit_mut_borrow_match.move @@ -13,7 +13,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { let mut n = 5; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/macro_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/macro_match.move index 85cb1c9dd6a..aa90f9b91f0 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/macro_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/macro_match.move @@ -24,7 +24,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { m::maybe_macro_call_2(); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.move new file mode 100644 index 00000000000..340b1798822 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_lit_mut_bind.move @@ -0,0 +1,26 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun test() { + let x = 10; + let y = match (x) { + 0 => 10, + mut x => { + x = x + 10; + x + } + }; + assert!(y == 20); + let y = match (x) { + 0 => 10, + mut y => { + y = y + 10; + y + } + }; + assert!(y == 20); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_mut_lit.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_mut_lit.move index de1606604a6..1fac5f2ead3 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_mut_lit.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_mut_lit.move @@ -13,7 +13,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { let mut n = 10; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_type.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_type.move index 4cb21aca404..8f7169f5c8a 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_type.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/match_type.move @@ -24,7 +24,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/multi_or.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/multi_or.move index 95014baafc8..3db53129d41 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/multi_or.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/multi_or.move @@ -31,7 +31,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t0() == 0); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.move new file mode 100644 index 00000000000..c4b8f503cac --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/mut_field_alias.move @@ -0,0 +1,22 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public enum E { + X { x: u64 }, + Y { y: u64 } + } + + public fun test() { + let e = E::Y { y: 1 }; + let value = match (e) { + E::X { mut x } | E::Y { y: mut x } => { + x = x + 1; + x + } + }; + assert!(value == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/nested_at.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/nested_at.move index dd83a343454..f34efb5ecef 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/nested_at.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/nested_at.move @@ -12,7 +12,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { assert!(m::t() == 20); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.move new file mode 100644 index 00000000000..2b7935cf747 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_0.move @@ -0,0 +1,56 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Action has drop { + Stop, + MoveTo { x: u64, y: u64 }, + ChangeSpeed(u64), + } + + public fun test() { + // Define a list of actions + let actions: vector = vector[ + Action::MoveTo { x: 10, y: 20 }, + Action::ChangeSpeed(40), + Action::MoveTo { x: 10, y: 20 }, + Action::Stop, + Action::ChangeSpeed(40), + ]; + + let mut total_moves = 0; + + 'loop_label: loop { + let mut i = 0; + while (i < actions.length()) { + let action = &actions[i]; + + match (action) { + Action::MoveTo { x, y } => { + 'loop_label: loop { + total_moves = total_moves + *x + *y; + break 'loop_label + }; + }, + Action::ChangeSpeed(speed) => { + 'loop_label: loop { + total_moves = total_moves + *speed; + break 'loop_label + }; + }, + Action::Stop => { + break 'loop_label + }, + }; + i = i + 1; + }; + }; + + actions.destroy!(|_| {}); + + assert!(total_moves == 100); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.move new file mode 100644 index 00000000000..76874f413e9 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_1.move @@ -0,0 +1,50 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Action has drop { + Stop, + MoveTo { x: u64, y: u64 }, + ChangeSpeed(u64), + } + + public fun test() { + // Define a list of actions + let actions: vector = vector[ + Action::MoveTo { x: 10, y: 20 }, + Action::ChangeSpeed(20), + Action::MoveTo { x: 10, y: 20 }, + Action::Stop, + Action::ChangeSpeed(40), + ]; + + let mut total_moves = 0; + + 'loop_label: loop { + let mut i = 0; + while (i < actions.length()) { + let action = &actions[i]; + + match (action) { + Action::MoveTo { x: speed, y: _ } | Action::ChangeSpeed(speed) => { + 'loop_label: loop { + total_moves = total_moves + *speed; + break 'loop_label + }; + }, + Action::Stop => { + break 'loop_label + }, + }; + i = i + 1; + }; + }; + + actions.destroy!(|_| {}); + + assert!(total_moves == 40); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.move new file mode 100644 index 00000000000..8088c6de28c --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_2.move @@ -0,0 +1,58 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Action has copy, drop { + Stop, + MoveTo { x: u64, y: u64 }, + ChangeSpeed(u64), + } + + public fun speed(action: &Action): u64 { + match (action) { + Action::MoveTo { x: speed, y: _ } => *speed, + Action::ChangeSpeed(speed) => *speed, + Action::Stop => abort 0, + } + } + + public fun test() { + // Define a list of actions + let actions: vector = vector[ + Action::MoveTo { x: 10, y: 20 }, + Action::ChangeSpeed(20), + Action::MoveTo { x: 10, y: 20 }, + Action::Stop, + Action::ChangeSpeed(40), + ]; + + let mut total_moves = 0; + + 'loop_label: loop { + let mut i = 0; + while (i < actions.length()) { + let action = actions[i]; + + match (action) { + action @ Action::MoveTo { .. } | action @ Action::ChangeSpeed(_) => { + 'loop_label: loop { + total_moves = total_moves + action.speed(); + break 'loop_label + }; + }, + Action::Stop => { + break 'loop_label + }, + }; + i = i + 1; + }; + }; + + actions.destroy!(|_| {}); + + assert!(total_moves == 40); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.move new file mode 100644 index 00000000000..95e1eaef765 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/rhs_shadow_loop_label_3.move @@ -0,0 +1,58 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Action has copy, drop { + Stop, + MoveTo { x: u64, y: u64 }, + ChangeSpeed(u64), + } + + public fun speed(action: &Action): u64 { + match (action) { + Action::MoveTo { x: speed, y: _ } => *speed, + Action::ChangeSpeed(speed) => *speed, + Action::Stop => abort 0, + } + } + + public fun test() { + // Define a list of actions + let actions: vector = vector[ + Action::MoveTo { x: 10, y: 20 }, + Action::ChangeSpeed(20), + Action::MoveTo { x: 10, y: 20 }, + Action::Stop, + Action::ChangeSpeed(40), + ]; + + let mut total_moves = 0; + + 'loop_label: loop { + let mut i = 0; + while (i < actions.length()) { + let action = actions[i]; + + match (action) { + action @ (Action::MoveTo { x: _, y: _ } | Action::ChangeSpeed(..)) => { + 'loop_label: loop { + total_moves = total_moves + action.speed(); + break 'loop_label + }; + }, + Action::Stop => { + break 'loop_label + }, + }; + i = i + 1; + }; + }; + + actions.destroy!(|_| {}); + + assert!(total_moves == 40); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.move new file mode 100644 index 00000000000..c20fe05d04b --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp.move @@ -0,0 +1,117 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Op has drop { + LoopOpen, + BreakIfEven(u64), // encodes jump PC + Return, + Push(u64), + Add, + LoopClose, + } + + fun interp(ops: vector): u64 { + let mut stack = vector[]; + let mut loop_pcs = vector[]; + let mut cur_pc = 0; + + 'exit: { + 'interp: loop { + match (&ops[cur_pc]) { + Op::LoopOpen => { + loop_pcs.push_back(cur_pc + 1); + }, + Op::BreakIfEven(new_pc) => { + let top = stack[stack.length() - 1]; + if (top % 2 == 0) { + loop_pcs.pop_back(); + cur_pc = *new_pc; + continue 'interp + } + }, + Op::Return => { + return 'exit + }, + Op::Push(value) => { + stack.push_back(*value); + }, + Op::Add => { + let n0 = stack.pop_back(); + let n1 = stack.pop_back(); + stack.push_back(n0 + n1); + }, + Op::LoopClose => { + cur_pc = loop_pcs[loop_pcs.length() - 1]; + continue 'interp + } + }; + cur_pc = cur_pc + 1; + } + }; + + stack.pop_back() + } + + fun test() { + + let push = vector[ + Op::Push(1), + Op::Return, + ]; + + assert!(interp(push) == 1); + + let add = vector[ + Op::Push(1), + Op::Push(1), + Op::Add, + Op::Return, + ]; + + assert!(interp(add) == 2); + + let early_break = vector[ + Op::Push(1), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp(early_break) == 100); + + let exiting = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp(exiting) == 1); + + let loop_and_break = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(6), + Op::LoopClose, + Op::Return, + ]; + + assert!(interp(loop_and_break) == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.move new file mode 100644 index 00000000000..d7671fb22fe --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/stack_interp_macro.move @@ -0,0 +1,118 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Op has drop { + LoopOpen, + BreakIfEven(u64), // encodes jump PC + Return, + Push(u64), + Add, + LoopClose, + } + + macro fun interp($ops: vector): u64 { + let ops = $ops; + let mut stack = vector[]; + let mut loop_pcs = vector[]; + let mut cur_pc = 0; + + 'exit: { + 'interp: loop { + match (&ops[cur_pc]) { + Op::LoopOpen => { + loop_pcs.push_back(cur_pc + 1); + }, + Op::BreakIfEven(new_pc) => { + let top = stack[stack.length() - 1]; + if (top % 2 == 0) { + loop_pcs.pop_back(); + cur_pc = *new_pc; + continue 'interp + } + }, + Op::Return => { + return 'exit + }, + Op::Push(value) => { + stack.push_back(*value); + }, + Op::Add => { + let n0 = stack.pop_back(); + let n1 = stack.pop_back(); + stack.push_back(n0 + n1); + }, + Op::LoopClose => { + cur_pc = loop_pcs[loop_pcs.length() - 1]; + continue 'interp + } + }; + cur_pc = cur_pc + 1; + } + }; + + stack.pop_back() + } + + fun test() { + + let push = vector[ + Op::Push(1), + Op::Return, + ]; + + assert!(interp!(push) == 1); + + let add = vector[ + Op::Push(1), + Op::Push(1), + Op::Add, + Op::Return, + ]; + + assert!(interp!(add) == 2); + + let early_break = vector[ + Op::Push(1), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp!(early_break) == 100); + + let exiting = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp!(exiting) == 1); + + let loop_and_break = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(6), + Op::LoopClose, + Op::Return, + ]; + + assert!(interp!(loop_and_break) == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.move new file mode 100644 index 00000000000..c3d9bf35fa1 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_abort.move @@ -0,0 +1,19 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public struct S has drop { x: u64 } + + public fun from_index(s: S): u64 { + match (s) { + S { x: 0} => 1, + _ => abort 0, + } + } + + public fun run() { + assert!(from_index(S { x: 0 }) == 1) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match.move index 6c21f625acc..d972ca775df 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match.move @@ -291,7 +291,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { use 0x42::m::{make_nbase, make_pbase, make_npoly, make_ppoly, make_nempty, make_pempty}; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match_mut.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match_mut.move index 8a350506dd5..43ee6ad0d24 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match_mut.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/struct_match_mut.move @@ -102,7 +102,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { use 0x42::m::{make_nbase, make_pbase, make_npoly, make_ppoly}; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.move new file mode 100644 index 00000000000..58a37086695 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_abort.move @@ -0,0 +1,17 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun test(value: bool): u64 { + match (value) { + true => abort 0, + false => 0, + } + } + + public fun run() { + assert!(test(false) == 0) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.move new file mode 100644 index 00000000000..8449e4e069a --- /dev/null +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/matching/true_false_nested_abort.move @@ -0,0 +1,17 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun test(value: bool): u64 { + match (value) { + true => match (value) { true => abort 0, false => abort 0 }, + false => match (value) { true => abort 0, false => 1 }, + } + } + + public fun run() { + assert!(test(false) == 1) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.exp index 30105f51054..e4b8e8b7a36 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.exp +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.exp @@ -5,7 +5,7 @@ task 1, lines 17-23: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 25-31: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x4::m, + location: 0x9::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 48-54: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x6::m, + location: 0x11::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -35,7 +35,7 @@ task 5, lines 56-62: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0x12::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 79-85: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x9::m, + location: 0x14::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 10, lines 112-119: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0xc::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 11, lines 121-126: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0xd::m, + location: 0x18::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 14, lines 152-158: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0xf::m, + location: 0x20::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 15, lines 160-166: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x21::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 16, lines 168-174: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x22::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.move index 8bff88c4aea..be36ed036aa 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/arithmetic_operators_u32.move @@ -1,5 +1,5 @@ //# run -module 1::m { +module 6::m { fun main() { assert!(0u32 + 0u32 == 0u32, 1000); assert!(0u32 + 1u32 == 1u32, 1001); @@ -15,7 +15,7 @@ fun main() { } //# run -module 2::m { +module 7::m { fun main() { // should fail 1u32 + 4294967295u32; @@ -23,7 +23,7 @@ fun main() { } //# run -module 4::m { +module 9::m { fun main() { // should fail 4294967295u32 + 4294967295u32; @@ -31,7 +31,7 @@ fun main() { } //# run -module 5::m { +module 10::m { fun main() { assert!(0u32 - 0u32 == 0u32, 2000); assert!(1u32 - 0u32 == 1u32, 2001); @@ -46,7 +46,7 @@ fun main() { } //# run -module 6::m { +module 0x11::m { fun main() { // should fail 0u32 - 1u32; @@ -54,7 +54,7 @@ fun main() { } //# run -module 7::m { +module 0x12::m { fun main() { // should fail 54u32 - 100u32; @@ -63,7 +63,7 @@ fun main() { //# run -module 8::m { +module 0x13::m { fun main() { assert!(0u32 * 0u32 == 0u32, 3000); assert!(1u32 * 0u32 == 0u32, 3001); @@ -77,7 +77,7 @@ fun main() { } //# run -module 9::m { +module 0x14::m { fun main() { // should fail 1147483647u32 * 2147483647u32; @@ -85,7 +85,7 @@ fun main() { } //# run -module 10::m { +module 0x15::m { fun main() { // should fail 1147483647u32 * 2u32; @@ -95,7 +95,7 @@ fun main() { //# run -module 11::m { +module 0x16::m { fun main() { assert!(0u32 / 1u32 == 0u32, 4000); assert!(1u32 / 1u32 == 1u32, 4001); @@ -110,7 +110,7 @@ fun main() { } //# run -module 12::m { +module 0x17::m { fun main() { // should fail 0u32 / 0u32; @@ -119,7 +119,7 @@ fun main() { // check: ARITHMETIC_ERROR //# run -module 13::m { +module 0x18::m { fun main() { 1u32 / 0u32; } @@ -135,7 +135,7 @@ fun main() { //# run -module 14::m { +module 0x19::m { fun main() { assert!(0u32 % 1u32 == 0u32, 5000); assert!(1u32 % 1u32 == 0u32, 5001); @@ -150,7 +150,7 @@ fun main() { } //# run -module 15::m { +module 0x20::m { fun main() { // should fail 0u32 % 0u32; @@ -158,7 +158,7 @@ fun main() { } //# run -module 16::m { +module 0x21::m { fun main() { // should fail 1u32 % 0u32; @@ -166,7 +166,7 @@ fun main() { } //# run -module 17::m { +module 0x22::m { fun main() { // should fail 4294967294u32 % 0u32; diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/bitwise_operators.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/bitwise_operators.move index 7382f201b1d..683d364e308 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/bitwise_operators.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/bitwise_operators.move @@ -1,5 +1,5 @@ //# run -module 1::m { +module 6::m { fun main() { assert!(0u8 & 0u8 == 0u8, 1000); assert!(0u64 & 0u64 == 0u64, 1001); @@ -100,7 +100,7 @@ fun main() { //# run -module 2::m { +module 7::m { fun main() { assert!(0u8 ^ 0u8 == 0u8, 3000); assert!(0u64 ^ 0u64 == 0u64, 3001); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/eq_refs.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/eq_refs.move index 2636e3aa710..e8b967861f3 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/eq_refs.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/eq_refs.move @@ -172,7 +172,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { fun main() { let s_val = 0x42::m::make_s(42); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.exp b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.exp index 9142a02ea9b..7bc92a9d98f 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.exp +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.exp @@ -5,7 +5,7 @@ task 0, lines 1-8: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x1::m, + location: 0x6::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 1, lines 10-16: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 2, lines 18-24: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -35,7 +35,7 @@ task 3, lines 26-32: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x4::m, + location: 0x9::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 4, lines 34-40: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 5, lines 42-48: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x6::m, + location: 0xb::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 6, lines 50-56: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 7, lines 58-64: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 8, lines 66-72: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x9::m, + location: 0xe::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 9, lines 74-83: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0xa::m, + location: 0xf::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.move index cc77e580ae2..669fbb1b4ff 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/operators/shift_operators.move @@ -1,6 +1,6 @@ //# run // Number of bits shifted >= total number of bits in the number. -module 1::m { +module 6::m { fun main() { // should fail 0u8 << 8u8; @@ -8,7 +8,7 @@ fun main() { } //# run -module 2::m { +module 7::m { fun main() { // should fail 0u64 << 64u8; @@ -16,7 +16,7 @@ fun main() { } //# run -module 3::m { +module 8::m { fun main() { // should fail 0u128 << 128u8; @@ -24,7 +24,7 @@ fun main() { } //# run -module 4::m { +module 9::m { fun main() { // should fail 0u8 >> 8u8; @@ -32,7 +32,7 @@ fun main() { } //# run -module 5::m { +module 0xa::m { fun main() { // should fail 0u64 >> 64u8; @@ -40,7 +40,7 @@ fun main() { } //# run -module 6::m { +module 0xb::m { fun main() { // should fail 0u128 >> 128u8; @@ -48,7 +48,7 @@ fun main() { } //# run -module 7::m { +module 0xc::m { fun main() { // should fail 0u16 << 16u8; @@ -56,7 +56,7 @@ fun main() { } //# run -module 8::m { +module 0xd::m { fun main() { // should fail 0u32 << 32u8; @@ -64,7 +64,7 @@ fun main() { } //# run -module 9::m { +module 0xe::m { fun main() { // should fail 0u16 >> 16u8; @@ -72,7 +72,7 @@ fun main() { } //# run -module 10::m { +module 0xf::m { fun main() { // should fail 0u32 >> 32u8; @@ -82,7 +82,7 @@ fun main() { // Shifting 0 results in 0. //# run -module 11::m { +module 0x10::m { fun main() { assert!(0u8 << 4u8 == 0u8, 1000); assert!(0u64 << 1u8 == 0u64, 1001); @@ -103,7 +103,7 @@ fun main() { // Shifting by 0 bits results in the same number. //# run -module 12::m { +module 0x11::m { fun main() { assert!(100u8 << 0u8 == 100u8, 2000); assert!(43u64 << 0u8 == 43u64, 2001); @@ -146,7 +146,7 @@ fun main() { // Underflowing results in 0. //# run -module 13::m { +module 0x13::m { fun main() { assert!(1234u64 >> 63u8 == 0u64, 4000); assert!(3u8 >> 5u8 == 0u8, 4001); @@ -161,7 +161,7 @@ fun main() { // Overflowing results are truncated. //# run -module 14::m { +module 0x14::m { fun main() { assert!(7u8 << 7u8 == 128u8, 5000); assert!(7u64 << 62u8 == 13835058055282163712u64, 5001); @@ -176,7 +176,7 @@ fun main() { // Some random tests. //# run -module 15::m { +module 0x15::m { fun main() { assert!(54u8 << 3u8 == 176u8, 6000); assert!(5u8 << 2u8 == 20u8, 6001); diff --git a/external-crates/move/crates/move-compiler-transactional-tests/tests/syntax/index_syntax.move b/external-crates/move/crates/move-compiler-transactional-tests/tests/syntax/index_syntax.move index 74fe6cd5c32..e114bd460ce 100644 --- a/external-crates/move/crates/move-compiler-transactional-tests/tests/syntax/index_syntax.move +++ b/external-crates/move/crates/move-compiler-transactional-tests/tests/syntax/index_syntax.move @@ -38,7 +38,7 @@ module 0x42::m { } //# run -module 0x42::main { +module 0x43::main { use 0x42::m; fun main() { diff --git a/external-crates/move/crates/move-compiler/Cargo.toml b/external-crates/move/crates/move-compiler/Cargo.toml index fa2974e55aa..72a849c8230 100644 --- a/external-crates/move/crates/move-compiler/Cargo.toml +++ b/external-crates/move/crates/move-compiler/Cargo.toml @@ -16,11 +16,13 @@ hex.workspace = true lsp-types.workspace = true once_cell.workspace = true petgraph.workspace = true +rayon.workspace = true regex.workspace = true serde.workspace = true serde_json.workspace = true similar.workspace = true stacker.workspace = true +tempfile.workspace = true vfs.workspace = true bcs.workspace = true diff --git a/external-crates/move/crates/move-compiler/README.md b/external-crates/move/crates/move-compiler/README.md index 39d928cc5ab..215f16dd685 100644 --- a/external-crates/move/crates/move-compiler/README.md +++ b/external-crates/move/crates/move-compiler/README.md @@ -47,7 +47,7 @@ Deliver a minimalistic, expressive, safe, and transparent language to produce--a ### Non-Principles -- **Heavy Abstractions** The Move source language does not intend to hide the details of the Move bytecode, this ranges from everything of references to global storage. There might be some abstractions that make interacting with these items easier, but they should always be available in Move at their most basic (bytecode equivalent) level. This does not mean that conveniences currently given by the source language, such as easy field access or implicit freezing, are against the core set of principles, but only that conveniences should not be ambiguous or opaque in how they interact at the bytecode level. Note though, this does not preclude the addition of features to the language, such as access modifiers that translate to compiler-generated dynamic checks. It is just that it is not an active goal of the language to add on heavy abstractions just for the sake of obscuring bytecode design choices. +- **Heavy Abstractions** The Move source language does not intend to hide the details of the Move bytecode, this ranges from everything of references to global storage. There might be some abstractions that make interacting with these items easier, but they should always be available in Move at their most basic (bytecode equivalent) level. This does not mean that conveniences currently given by the source language, such as easy field access or implicit freezing, are against the core set of principles, but only that conveniences should not be ambiguous or opaque in how they interact at the bytecode level. Note though, this does not preclude the addition of features to the lanugage, such as access modifiers that translate to compiler-generated dynamic checks. It is just that it is not an active goal of the language to add on heavy abstractions just for the sake of obscuring bytecode design choices. ## Command-line options diff --git a/external-crates/move/crates/move-compiler/src/cfgir/ast.rs b/external-crates/move/crates/move-compiler/src/cfgir/ast.rs index 568347bcfd8..0008355c2bf 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/ast.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/ast.rs @@ -13,7 +13,7 @@ use move_ir_types::location::*; use move_symbol_pool::Symbol; use crate::{ - diagnostics::WarningFilters, + diagnostics::warning_filters::{WarningFilters, WarningFiltersTable}, expansion::ast::{Attributes, Friend, ModuleIdent, Mutability, TargetKind}, hlir::ast::{ BaseType, Command, Command_, EnumDefinition, FunctionSignature, Label, SingleType, @@ -32,6 +32,8 @@ use crate::{ #[derive(Debug, Clone)] pub struct Program { pub info: Arc, + /// Safety: This table should not be dropped as long as any `WarningFilters` are alive + pub warning_filters_table: Arc, pub modules: UniqueMap, } @@ -93,6 +95,7 @@ pub struct Function { // index in the original order as defined in the source file pub index: usize, pub attributes: Attributes, + pub loc: Loc, /// The original, declared visibility as defined in the source file pub visibility: Visibility, /// We sometimes change the visibility of functions, e.g. `entry` is marked @@ -174,7 +177,7 @@ fn remap_labels_cmd(remapping: &BTreeMap, sp!(_, cmd_): &mut Comma use Command_::*; match cmd_ { Break(_) | Continue(_) => panic!("ICE break/continue not translated to jumps"), - Mutate(_, _) | Assign(_, _, _) | IgnoreAndPop { .. } | Abort(_) | Return { .. } => (), + Mutate(_, _) | Assign(_, _, _) | IgnoreAndPop { .. } | Abort(_, _) | Return { .. } => (), Jump { target, .. } => *target = remapping[target], JumpIf { if_true, if_false, .. @@ -196,10 +199,14 @@ fn remap_labels_cmd(remapping: &BTreeMap, sp!(_, cmd_): &mut Comma impl AstDebug for Program { fn ast_debug(&self, w: &mut AstWriter) { - let Program { modules, info: _ } = self; + let Program { + modules, + info: _, + warning_filters_table: _, + } = self; for (m, mdef) in modules.key_cloned_iter() { - w.write(&format!("module {}", m)); + w.write(format!("module {}", m)); w.block(|w| mdef.ast_debug(w)); w.new_line(); } @@ -222,7 +229,7 @@ impl AstDebug for ModuleDefinition { } = self; warning_filter.ast_debug(w); if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); w.writeln(match target_kind { @@ -234,9 +241,9 @@ impl AstDebug for ModuleDefinition { } => "dependency module", TargetKind::External => "external module", }); - w.writeln(&format!("dependency order #{}", dependency_order)); + w.writeln(format!("dependency order #{}", dependency_order)); for (mident, _loc) in friends.key_cloned_iter() { - w.write(&format!("friend {};", mident)); + w.write(format!("friend {};", mident)); w.new_line(); } for sdef in structs.key_cloned_iter() { @@ -273,7 +280,7 @@ impl AstDebug for (ConstantName, &Constant) { ) = self; warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("const#{index} {name}:")); + w.write(format!("const#{index} {name}:")); signature.ast_debug(w); w.write(" = "); match value { @@ -288,14 +295,14 @@ impl AstDebug for MoveValue { fn ast_debug(&self, w: &mut AstWriter) { use MoveValue as V; match self { - V::U8(u) => w.write(&format!("{}", u)), - V::U16(u) => w.write(&format!("{}", u)), - V::U32(u) => w.write(&format!("{}", u)), - V::U64(u) => w.write(&format!("{}", u)), - V::U128(u) => w.write(&format!("{}", u)), - V::U256(u) => w.write(&format!("{}", u)), - V::Bool(b) => w.write(&format!("{}", b)), - V::Address(a) => w.write(&format!("{}", a)), + V::U8(u) => w.write(format!("{}", u)), + V::U16(u) => w.write(format!("{}", u)), + V::U32(u) => w.write(format!("{}", u)), + V::U64(u) => w.write(format!("{}", u)), + V::U128(u) => w.write(format!("{}", u)), + V::U256(u) => w.write(format!("{}", u)), + V::Bool(b) => w.write(format!("{}", b)), + V::Address(a) => w.write(format!("{}", a)), V::Vector(vs) => { w.write("vector["); w.comma(vs, |w, v| v.ast_debug(w)); @@ -316,6 +323,7 @@ impl AstDebug for (FunctionName, &Function) { warning_filter, index, attributes, + loc: _, visibility, compiled_visibility, entry, @@ -331,12 +339,12 @@ impl AstDebug for (FunctionName, &Function) { compiled_visibility.ast_debug(w); w.write(") "); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if let FunctionBody_::Native = &body.value { w.write("native "); } - w.write(&format!("fun#{index} {name}")); + w.write(format!("fun#{index} {name}")); signature.ast_debug(w); match &body.value { FunctionBody_::Defined { @@ -349,7 +357,7 @@ impl AstDebug for (FunctionName, &Function) { w.indent(4, |w| { w.list(locals, ",", |w, (_, v, (mut_, st))| { mut_.ast_debug(w); - w.write(&format!("{}: ", v)); + w.write(format!("{}: ", v)); st.ast_debug(w); true }) @@ -358,11 +366,11 @@ impl AstDebug for (FunctionName, &Function) { w.writeln("block info:"); w.indent(4, |w| { for (lbl, info) in block_info { - w.writeln(&format!("{lbl}: ")); + w.writeln(format!("{lbl}: ")); info.ast_debug(w); } }); - w.writeln(&format!("start={}", start.0)); + w.writeln(format!("start={}", start.0)); w.new_line(); blocks.ast_debug(w); }), @@ -383,7 +391,7 @@ impl AstDebug for BasicBlocks { impl AstDebug for (&Label, &BasicBlock) { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("label {}:", (self.0).0)); + w.write(format!("label {}:", (self.0).0)); w.indent(4, |w| w.semicolon(self.1, |w, cmd| cmd.ast_debug(w))) } } @@ -403,7 +411,7 @@ impl AstDebug for LoopInfo { is_loop_stmt, loop_end, } = self; - w.write(&format!( + w.write(format!( "{{ is_loop_stmt: {}, end: ", if *is_loop_stmt { "true" } else { "false" } )); @@ -416,7 +424,7 @@ impl AstDebug for LoopEnd { fn ast_debug(&self, w: &mut AstWriter) { match self { LoopEnd::Unused => w.write("unused end"), - LoopEnd::Target(lbl) => w.write(&format!("{lbl}")), + LoopEnd::Target(lbl) => w.write(format!("{lbl}")), } } } diff --git a/external-crates/move/crates/move-compiler/src/cfgir/borrows/mod.rs b/external-crates/move/crates/move-compiler/src/cfgir/borrows/mod.rs index a585d278d8a..a96b5ac714a 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/borrows/mod.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/borrows/mod.rs @@ -19,7 +19,7 @@ use crate::{ translate::{display_var, DisplayVar}, }, parser::ast::BinOp_, - shared::{unique_map::UniqueMap, CompilationEnv}, + shared::unique_map::UniqueMap, }; //************************************************************************************************** @@ -92,7 +92,6 @@ impl TransferFunctions for BorrowSafety { impl AbstractInterpreter for BorrowSafety {} pub fn verify( - compilation_env: &mut CompilationEnv, context: &super::CFGContext, cfg: &super::cfg::MutForwardCFG, ) -> BTreeMap { @@ -102,21 +101,17 @@ pub fn verify( let mut safety = BorrowSafety::new(locals); // check for existing errors - let has_errors = compilation_env.has_errors(); + let has_errors = context.env.has_errors(); let mut initial_state = BorrowState::initial(locals, safety.mutably_used.clone(), has_errors); initial_state.bind_arguments(&signature.parameters); initial_state.canonicalize_locals(&safety.local_numbers); let (final_state, ds) = safety.analyze_function(cfg, initial_state); - compilation_env.add_diags(ds); - unused_mut_borrows(compilation_env, context, safety.mutably_used); + context.add_diags(ds); + unused_mut_borrows(context, safety.mutably_used); final_state } -fn unused_mut_borrows( - compilation_env: &mut CompilationEnv, - context: &super::CFGContext, - mutably_used: RefExpInfoMap, -) { +fn unused_mut_borrows(context: &super::CFGContext, mutably_used: RefExpInfoMap) { const MSG: &str = "Mutable reference is never used mutably, \ consider switching to an immutable reference '&' instead"; @@ -145,7 +140,7 @@ fn unused_mut_borrows( } else { diag!(UnusedItem::MutReference, (*loc, MSG)) }; - compilation_env.add_diag(diag) + context.add_diag(diag) } } } @@ -189,7 +184,7 @@ fn command(context: &mut Context, sp!(loc, cmd_): &Command) { let diags = context.borrow_state.return_(*loc, values); context.add_diags(diags); } - C::Abort(e) => { + C::Abort(_, e) => { let value = assert_single_value(exp(context, e)); assert!(!value.is_ref()); context.borrow_state.abort() diff --git a/external-crates/move/crates/move-compiler/src/cfgir/cfg.rs b/external-crates/move/crates/move-compiler/src/cfgir/cfg.rs index 1f19bedf301..6b0a5884958 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/cfg.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/cfg.rs @@ -361,7 +361,7 @@ fn maybe_unmark_infinite_loop_starts( { infinite_loop_starts.remove(&cur_loop_start); } - C::Return { .. } | C::Abort(_) => { + C::Return { .. } | C::Abort(_, _) => { infinite_loop_starts.remove(&cur_loop_start); } @@ -706,7 +706,7 @@ impl<'a, T: Deref> AstDebug for ReverseCFG<'a, T> { loop_heads, } = self; w.writeln("--ReverseBlockCFG--"); - w.writeln(&format!("terminal: {}", terminal)); + w.writeln(format!("terminal: {}", terminal)); ast_debug_cfg( w, traversal_order[0], @@ -731,8 +731,8 @@ fn ast_debug_cfg<'a>( w.write("successor_map:"); w.indent(4, |w| { for (lbl, nexts) in successor_map { - w.write(&format!("{} => [", lbl)); - w.comma(nexts, |w, next| w.write(&format!("{}", next))); + w.write(format!("{} => [", lbl)); + w.comma(nexts, |w, next| w.write(format!("{}", next))); w.writeln("]") } }); @@ -740,8 +740,8 @@ fn ast_debug_cfg<'a>( w.write("predecessor_map:"); w.indent(4, |w| { for (lbl, nexts) in predecessor_map { - w.write(&format!("{} <= [", lbl)); - w.comma(nexts, |w, next| w.write(&format!("{}", next))); + w.write(format!("{} <= [", lbl)); + w.comma(nexts, |w, next| w.write(format!("{}", next))); w.writeln("]") } }); @@ -749,7 +749,7 @@ fn ast_debug_cfg<'a>( w.write("traversal:"); w.indent(4, |w| { for (cur, next) in traversal { - w.writeln(&format!("{} => {}", cur, next)) + w.writeln(format!("{} => {}", cur, next)) } }); @@ -757,7 +757,7 @@ fn ast_debug_cfg<'a>( w.indent(4, |w| { for (loop_head, back_edge_predecessors) in loop_heads { for pred in back_edge_predecessors { - w.writeln(&format!( + w.writeln(format!( "loop head: {}. back edge predecessor: {}", loop_head, pred )) @@ -765,7 +765,7 @@ fn ast_debug_cfg<'a>( } }); - w.writeln(&format!("start: {}", start)); + w.writeln(format!("start: {}", start)); w.writeln("blocks:"); w.indent(4, |w| blocks.ast_debug(w)); } diff --git a/external-crates/move/crates/move-compiler/src/cfgir/liveness/mod.rs b/external-crates/move/crates/move-compiler/src/cfgir/liveness/mod.rs index 0e65c708ef4..b7d6aac031b 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/liveness/mod.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/liveness/mod.rs @@ -20,7 +20,7 @@ use crate::{ diagnostics::Diagnostics, expansion::ast::Mutability, hlir::ast::{self as H, *}, - shared::{unique_map::UniqueMap, CompilationEnv}, + shared::unique_map::UniqueMap, }; //************************************************************************************************** @@ -97,7 +97,7 @@ fn command(state: &mut LivenessState, sp!(_, cmd_): &Command) { exp(state, el) } C::Return { exp: e, .. } - | C::Abort(e) + | C::Abort(_, e) | C::IgnoreAndPop { exp: e, .. } | C::JumpIf { cond: e, .. } | C::VariantSwitch { subject: e, .. } => exp(state, e), @@ -172,11 +172,7 @@ fn exp(state: &mut LivenessState, parent_e: &Exp) { /// `Ignore` if it has the drop ability (helps with error messages for /// borrows) -pub fn last_usage( - compilation_env: &mut CompilationEnv, - context: &super::CFGContext, - cfg: &mut MutForwardCFG, -) { +pub fn last_usage(context: &super::CFGContext, cfg: &mut MutForwardCFG) { let super::CFGContext { infinite_loop_starts, .. @@ -187,7 +183,7 @@ pub fn last_usage( .get(lbl) .unwrap_or_else(|| panic!("ICE no liveness states for {}", lbl)); let command_states = per_command_states.get(lbl).unwrap(); - last_usage::block(compilation_env, final_invariant, command_states, block) + last_usage::block(context, final_invariant, command_states, block) } } @@ -197,29 +193,28 @@ mod last_usage { use move_proc_macros::growing_stack; use crate::{ - cfgir::liveness::state::LivenessState, + cfgir::{liveness::state::LivenessState, CFGContext}, diag, hlir::{ ast::*, translate::{display_var, DisplayVar}, }, - shared::*, }; struct Context<'a, 'b> { - env: &'a mut CompilationEnv, + outer: &'a CFGContext<'a>, next_live: &'b BTreeSet, dropped_live: BTreeSet, } impl<'a, 'b> Context<'a, 'b> { fn new( - env: &'a mut CompilationEnv, + outer: &'a CFGContext<'a>, next_live: &'b BTreeSet, dropped_live: BTreeSet, ) -> Self { Context { - env, + outer, next_live, dropped_live, } @@ -227,7 +222,7 @@ mod last_usage { } pub fn block( - compilation_env: &mut CompilationEnv, + context: &CFGContext, final_invariant: &LivenessState, command_states: &VecDeque, block: &mut BasicBlock, @@ -250,10 +245,7 @@ mod last_usage { .difference(next_data) .cloned() .collect::>(); - command( - &mut Context::new(compilation_env, next_data, dropped_live), - cmd, - ) + command(&mut Context::new(context, next_data, dropped_live), cmd) } } @@ -270,7 +262,7 @@ mod last_usage { exp(context, er) } C::Return { exp: e, .. } - | C::Abort(e) + | C::Abort(_, e) | C::IgnoreAndPop { exp: e, .. } | C::JumpIf { cond: e, .. } | C::VariantSwitch { subject: e, .. } => exp(context, e), @@ -305,7 +297,7 @@ mod last_usage { '_{vstr}')", ); context - .env + .outer .add_diag(diag!(UnusedItem::Assignment, (l.loc, msg))); } *unused_assignment = true; diff --git a/external-crates/move/crates/move-compiler/src/cfgir/locals/mod.rs b/external-crates/move/crates/move-compiler/src/cfgir/locals/mod.rs index ba06c2a2e8d..a4750a41343 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/locals/mod.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/locals/mod.rs @@ -9,26 +9,22 @@ use std::collections::BTreeMap; use move_ir_types::location::*; use move_proc_macros::growing_stack; -use move_symbol_pool::Symbol; use state::*; use super::absint::*; use crate::{ + cfgir::CFGContext, diag, diagnostics::{Diagnostic, Diagnostics}, editions::Edition, expansion::ast::{AbilitySet, ModuleIdent, Mutability}, hlir::{ ast::*, - translate::{display_var, DisplayVar}, + translate::{DisplayVar, display_var}, }, naming::ast::{self as N, TParam}, parser::ast::{Ability_, DatatypeName}, - shared::{ - program_info::{DatatypeKind, TypingProgramInfo}, - unique_map::UniqueMap, - *, - }, + shared::{program_info::DatatypeKind, unique_map::UniqueMap}, }; //************************************************************************************************** @@ -36,9 +32,7 @@ use crate::{ //************************************************************************************************** struct LocalsSafety<'a> { - env: &'a CompilationEnv, - info: &'a TypingProgramInfo, - package: Option, + context: &'a CFGContext<'a>, local_types: &'a UniqueMap, signature: &'a FunctionSignature, unused_mut: BTreeMap, @@ -46,9 +40,7 @@ struct LocalsSafety<'a> { impl<'a> LocalsSafety<'a> { fn new( - env: &'a CompilationEnv, - info: &'a TypingProgramInfo, - package: Option, + context: &'a CFGContext<'a>, local_types: &'a UniqueMap, signature: &'a FunctionSignature, ) -> Self { @@ -63,9 +55,7 @@ impl<'a> LocalsSafety<'a> { }) .collect(); Self { - env, - info, - package, + context, local_types, signature, unused_mut, @@ -74,9 +64,7 @@ impl<'a> LocalsSafety<'a> { } struct Context<'a, 'b> { - env: &'a CompilationEnv, - info: &'a TypingProgramInfo, - package: Option, + outer: &'a CFGContext<'a>, local_types: &'a UniqueMap, unused_mut: &'a mut BTreeMap, local_states: &'b mut LocalStates, @@ -86,15 +74,12 @@ struct Context<'a, 'b> { impl<'a, 'b> Context<'a, 'b> { fn new(locals_safety: &'a mut LocalsSafety, local_states: &'b mut LocalStates) -> Self { - let env = locals_safety.env; - let info = locals_safety.info; + let outer = locals_safety.context; let local_types = locals_safety.local_types; let signature = locals_safety.signature; let unused_mut = &mut locals_safety.unused_mut; Self { - env, - info, - package: locals_safety.package, + outer, local_types, unused_mut, local_states, @@ -157,18 +142,18 @@ impl<'a, 'b> Context<'a, 'b> { // .unwrap(); fn datatype_decl_loc(&self, m: &ModuleIdent, n: &DatatypeName) -> Loc { - let kind = self.info.datatype_kind(m, n); + let kind = self.outer.info.datatype_kind(m, n); match kind { - DatatypeKind::Struct => self.info.struct_declared_loc(m, n), - DatatypeKind::Enum => self.info.enum_declared_loc(m, n), + DatatypeKind::Struct => self.outer.info.struct_declared_loc(m, n), + DatatypeKind::Enum => self.outer.info.enum_declared_loc(m, n), } } fn datatype_declared_abilities(&self, m: &ModuleIdent, n: &DatatypeName) -> &'a AbilitySet { - let kind = self.info.datatype_kind(m, n); + let kind = self.outer.info.datatype_kind(m, n); match kind { - DatatypeKind::Struct => self.info.struct_declared_abilities(m, n), - DatatypeKind::Enum => self.info.enum_declared_abilities(m, n), + DatatypeKind::Struct => self.outer.info.struct_declared_abilities(m, n), + DatatypeKind::Enum => self.outer.info.enum_declared_abilities(m, n), } } } @@ -192,7 +177,6 @@ impl<'a> TransferFunctions for LocalsSafety<'a> { impl<'a> AbstractInterpreter for LocalsSafety<'a> {} pub fn verify( - compilation_env: &mut CompilationEnv, context: &super::CFGContext, cfg: &super::cfg::MutForwardCFG, ) -> BTreeMap { @@ -200,22 +184,16 @@ pub fn verify( signature, locals, .. } = context; let initial_state = LocalStates::initial(&signature.parameters, locals); - let mut locals_safety = LocalsSafety::new( - compilation_env, - context.info, - context.package, - locals, - signature, - ); + let mut locals_safety = LocalsSafety::new(context, locals, signature); let (final_state, ds) = locals_safety.analyze_function(cfg, initial_state); - unused_let_muts(compilation_env, locals, locals_safety.unused_mut); - compilation_env.add_diags(ds); + unused_let_muts(context, locals, locals_safety.unused_mut); + context.add_diags(ds); final_state } /// Generates warnings for unused mut declarations fn unused_let_muts( - env: &mut CompilationEnv, + context: &CFGContext, locals: &UniqueMap, unused_mut_locals: BTreeMap, ) { @@ -229,7 +207,7 @@ fn unused_let_muts( let decl_loc = *locals.get_loc(&v).unwrap(); let decl_msg = format!("The variable '{vstr}' is never used mutably"); let mut_msg = "Consider removing the 'mut' declaration here"; - env.add_diag(diag!( + context.add_diag(diag!( UnusedItem::MutModifier, (decl_loc, decl_msg), (mut_loc, mut_msg) @@ -254,7 +232,7 @@ fn command(context: &mut Context, sp!(loc, cmd_): &Command) { exp(context, er); exp(context, el) } - C::Abort(e) + C::Abort(_, e) | C::IgnoreAndPop { exp: e, .. } | C::JumpIf { cond: e, .. } | C::VariantSwitch { subject: e, .. } => exp(context, e), @@ -527,7 +505,7 @@ fn check_mutability( let usage_msg = format!("Invalid {usage} of immutable variable '{vstr}'"); let decl_msg = format!("To use the variable mutably, it must be declared 'mut', e.g. 'mut {vstr}'"); - if context.env.edition(context.package) == Edition::E2024_MIGRATION { + if context.outer.env.edition(context.outer.package) == Edition::E2024_MIGRATION { context.add_diag(diag!(Migration::NeedsLetMut, (decl_loc, decl_msg.clone()))) } else { let mut diag = diag!( @@ -555,7 +533,7 @@ fn check_mutability( //************************************************************************************************** fn add_drop_ability_tip(context: &Context, diag: &mut Diagnostic, st: SingleType) { - use N::{TypeName_ as TN, Type_ as T}; + use N::{Type_ as T, TypeName_ as TN}; let ty = single_type_to_naming_type(st); let owned_abilities; let (declared_loc_opt, declared_abilities, ty_args) = match &ty.value { @@ -606,8 +584,8 @@ fn single_type_to_naming_type(sp!(loc, st_): SingleType) -> N::Type { } fn single_type_to_naming_type_(st_: SingleType_) -> N::Type_ { - use SingleType_ as S; use N::Type_ as T; + use SingleType_ as S; match st_ { S::Ref(mut_, b) => T::Ref(mut_, Box::new(base_type_to_naming_type(b))), S::Base(sp!(_, b_)) => base_type_to_naming_type_(b_), @@ -638,8 +616,8 @@ fn type_name_to_naming_type_name(sp!(loc, tn_): TypeName) -> N::TypeName { } fn type_name_to_naming_type_name_(tn_: TypeName_) -> N::TypeName_ { - use TypeName_ as TN; use N::TypeName_ as NTN; + use TypeName_ as TN; match tn_ { TN::Builtin(b) => NTN::Builtin(b), TN::ModuleType(m, n) => NTN::ModuleType(m, n), diff --git a/external-crates/move/crates/move-compiler/src/cfgir/mod.rs b/external-crates/move/crates/move-compiler/src/cfgir/mod.rs index b30b3107962..778a5e40452 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/mod.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/mod.rs @@ -23,12 +23,15 @@ use move_symbol_pool::Symbol; use optimize::optimize; use crate::{ + diagnostics::DiagnosticReporter, expansion::ast::{Attributes, ModuleIdent, Mutability}, hlir::ast::{FunctionSignature, Label, SingleType, Var, Visibility}, shared::{program_info::TypingProgramInfo, unique_map::UniqueMap, CompilationEnv, Name}, }; pub struct CFGContext<'a> { + pub env: &'a CompilationEnv, + pub reporter: &'a DiagnosticReporter<'a>, pub info: &'a TypingProgramInfo, pub package: Option, pub module: ModuleIdent, @@ -46,16 +49,22 @@ pub enum MemberName { Function(Name), } -pub fn refine_inference_and_verify( - env: &mut CompilationEnv, - context: &CFGContext, - cfg: &mut MutForwardCFG, -) { - liveness::last_usage(env, context, cfg); - let locals_states = locals::verify(env, context, cfg); +pub fn refine_inference_and_verify(context: &CFGContext, cfg: &mut MutForwardCFG) { + liveness::last_usage(context, cfg); + let locals_states = locals::verify(context, cfg); liveness::release_dead_refs(context, &locals_states, cfg); - borrows::verify(env, context, cfg); + borrows::verify(context, cfg); +} + +impl CFGContext<'_> { + fn add_diag(&self, diag: crate::diagnostics::Diagnostic) { + self.reporter.add_diag(diag); + } + + fn add_diags(&self, diags: crate::diagnostics::Diagnostics) { + self.reporter.add_diags(diags); + } } impl MemberName { diff --git a/external-crates/move/crates/move-compiler/src/cfgir/optimize/constant_fold.rs b/external-crates/move/crates/move-compiler/src/cfgir/optimize/constant_fold.rs index d09e170c98f..d8faf452d7c 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/optimize/constant_fold.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/optimize/constant_fold.rs @@ -10,6 +10,7 @@ use move_proc_macros::growing_stack; use crate::{ cfgir::cfg::MutForwardCFG, + diagnostics::DiagnosticReporter, expansion::ast::Mutability, hlir::ast::{ BaseType, BaseType_, Command, Command_, Exp, FunctionSignature, SingleType, TypeName, @@ -22,17 +23,22 @@ use crate::{ /// returns true if anything changed pub fn optimize( + reporter: &DiagnosticReporter, _signature: &FunctionSignature, _locals: &UniqueMap, constants: &UniqueMap, cfg: &mut MutForwardCFG, ) -> bool { + let context = Context { + reporter, + constants, + }; let mut changed = false; for block_ref in cfg.blocks_mut().values_mut() { let block = std::mem::take(block_ref); *block_ref = block .into_iter() - .filter_map(|mut cmd| match optimize_cmd(constants, &mut cmd) { + .filter_map(|mut cmd| match optimize_cmd(&context, &mut cmd) { None => { changed = true; None @@ -47,6 +53,12 @@ pub fn optimize( changed } +struct Context<'a> { + #[allow(dead_code)] + reporter: &'a DiagnosticReporter<'a>, + constants: &'a UniqueMap, +} + //************************************************************************************************** // Scaffolding //************************************************************************************************** @@ -54,24 +66,21 @@ pub fn optimize( // Some(changed) to keep // None to remove the cmd #[growing_stack] -fn optimize_cmd( - consts: &UniqueMap, - sp!(_, cmd_): &mut Command, -) -> Option { +fn optimize_cmd(context: &Context, sp!(_, cmd_): &mut Command) -> Option { use Command_ as C; Some(match cmd_ { - C::Assign(_, _ls, e) => optimize_exp(consts, e), + C::Assign(_, _ls, e) => optimize_exp(context, e), C::Mutate(el, er) => { - let c1 = optimize_exp(consts, er); - let c2 = optimize_exp(consts, el); + let c1 = optimize_exp(context, er); + let c2 = optimize_exp(context, el); c1 || c2 } C::Return { exp: e, .. } - | C::Abort(e) + | C::Abort(_, e) | C::JumpIf { cond: e, .. } - | C::VariantSwitch { subject: e, .. } => optimize_exp(consts, e), + | C::VariantSwitch { subject: e, .. } => optimize_exp(context, e), C::IgnoreAndPop { exp: e, .. } => { - let c = optimize_exp(consts, e); + let c = optimize_exp(context, e); if ignorable_exp(e) { // value(s), so the command can be removed return None; @@ -86,9 +95,9 @@ fn optimize_cmd( } #[growing_stack] -fn optimize_exp(consts: &UniqueMap, e: &mut Exp) -> bool { +fn optimize_exp(context: &Context, e: &mut Exp) -> bool { use UnannotatedExp_ as E; - let optimize_exp = |e| optimize_exp(consts, e); + let optimize_exp = |e| optimize_exp(context, e); match &mut e.exp.value { //************************************ // Pass through cases @@ -106,7 +115,7 @@ fn optimize_exp(consts: &UniqueMap, e: &mut Exp) -> bool { let E::Constant(name) = e_ else { unreachable!() }; - if let Some(value) = consts.get(name) { + if let Some(value) = context.constants.get(name) { *e_ = E::Value(value.clone()); true } else { @@ -155,7 +164,10 @@ fn optimize_exp(consts: &UniqueMap, e: &mut Exp) -> bool { let changed1 = optimize_exp(e1); let changed2 = optimize_exp(e2); let changed = changed1 || changed2; - if let (Some(v1), Some(v2)) = (foldable_exp(e1), foldable_exp(e2)) { + let v1_opt = foldable_exp(e1); + let v2_opt = foldable_exp(e2); + // TODO warn on operations that always fail + if let (Some(v1), Some(v2)) = (v1_opt, v2_opt) { if let Some(folded) = fold_binary_op(e.exp.loc, op, v1, v2) { *e_ = folded; true @@ -173,6 +185,7 @@ fn optimize_exp(consts: &UniqueMap, e: &mut Exp) -> bool { _ => unreachable!(), }; let changed = optimize_exp(e); + // TODO warn on operations that always fail let v = match foldable_exp(e) { Some(v) => v, None => return changed, diff --git a/external-crates/move/crates/move-compiler/src/cfgir/optimize/eliminate_locals.rs b/external-crates/move/crates/move-compiler/src/cfgir/optimize/eliminate_locals.rs index a9fb0a1dfcd..f3765c1f447 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/optimize/eliminate_locals.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/optimize/eliminate_locals.rs @@ -7,6 +7,7 @@ use std::collections::BTreeSet; use crate::{ cfgir::{cfg::MutForwardCFG, remove_no_ops}, + diagnostics::DiagnosticReporter, expansion::ast::Mutability, hlir::ast::{FunctionSignature, SingleType, Value, Var}, parser, @@ -15,6 +16,7 @@ use crate::{ /// returns true if anything changed pub fn optimize( + _reporter: &DiagnosticReporter, signature: &FunctionSignature, _locals: &UniqueMap, _constants: &UniqueMap, @@ -128,7 +130,7 @@ mod count { exp(context, el) } C::Return { exp: e, .. } - | C::Abort(e) + | C::Abort(_, e) | C::IgnoreAndPop { exp: e, .. } | C::JumpIf { cond: e, .. } | C::VariantSwitch { subject: e, .. } => exp(context, e), @@ -307,7 +309,7 @@ mod eliminate { exp(context, el) } C::Return { exp: e, .. } - | C::Abort(e) + | C::Abort(_, e) | C::IgnoreAndPop { exp: e, .. } | C::JumpIf { cond: e, .. } | C::VariantSwitch { subject: e, .. } => exp(context, e), diff --git a/external-crates/move/crates/move-compiler/src/cfgir/optimize/forwarding_jumps.rs b/external-crates/move/crates/move-compiler/src/cfgir/optimize/forwarding_jumps.rs index 05809fd83da..1c1a9cc7d10 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/optimize/forwarding_jumps.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/optimize/forwarding_jumps.rs @@ -36,6 +36,7 @@ use crate::{ ast::remap_labels, cfg::{MutForwardCFG, CFG}, }, + diagnostics::DiagnosticReporter, expansion::ast::Mutability, hlir::ast::{BasicBlocks, Command, Command_, FunctionSignature, Label, SingleType, Value, Var}, parser::ast::ConstantName, @@ -44,6 +45,7 @@ use crate::{ /// returns true if anything changed pub fn optimize( + _reporter: &DiagnosticReporter, _signature: &FunctionSignature, _locals: &UniqueMap, _constants: &UniqueMap, diff --git a/external-crates/move/crates/move-compiler/src/cfgir/optimize/inline_blocks.rs b/external-crates/move/crates/move-compiler/src/cfgir/optimize/inline_blocks.rs index 1e6df6839a9..26c13312e0f 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/optimize/inline_blocks.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/optimize/inline_blocks.rs @@ -12,6 +12,7 @@ use crate::{ ast::remap_labels, cfg::{MutForwardCFG, CFG}, }, + diagnostics::DiagnosticReporter, expansion::ast::Mutability, hlir::ast::{BasicBlocks, Command_, FunctionSignature, Label, SingleType, Value, Var}, parser::ast::ConstantName, @@ -20,6 +21,7 @@ use crate::{ /// returns true if anything changed pub fn optimize( + _reporter: &DiagnosticReporter, _signature: &FunctionSignature, _locals: &UniqueMap, _constants: &UniqueMap, diff --git a/external-crates/move/crates/move-compiler/src/cfgir/optimize/mod.rs b/external-crates/move/crates/move-compiler/src/cfgir/optimize/mod.rs index 46baea47700..b96536eca63 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/optimize/mod.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/optimize/mod.rs @@ -13,6 +13,7 @@ use move_symbol_pool::Symbol; use crate::{ cfgir::cfg::MutForwardCFG, + diagnostics::DiagnosticReporter, editions::FeatureGate, expansion::ast::Mutability, hlir::ast::*, @@ -21,6 +22,7 @@ use crate::{ }; pub type Optimization = fn( + &DiagnosticReporter, &FunctionSignature, &UniqueMap, &UniqueMap, @@ -44,7 +46,8 @@ const MOVE_2024_OPTIMIZATIONS: &[Optimization] = &[ #[growing_stack] pub fn optimize( - env: &mut CompilationEnv, + env: &CompilationEnv, + reporter: &DiagnosticReporter, package: Option, signature: &FunctionSignature, locals: &UniqueMap, @@ -67,7 +70,7 @@ pub fn optimize( } // reset the count if something has changed - if optimization(signature, locals, constants, cfg) { + if optimization(reporter, signature, locals, constants, cfg) { count = 0 } else { count += 1 diff --git a/external-crates/move/crates/move-compiler/src/cfgir/optimize/simplify_jumps.rs b/external-crates/move/crates/move-compiler/src/cfgir/optimize/simplify_jumps.rs index 06ab6f7e2b4..121cb512591 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/optimize/simplify_jumps.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/optimize/simplify_jumps.rs @@ -7,6 +7,7 @@ use move_proc_macros::growing_stack; use crate::{ cfgir::cfg::MutForwardCFG, + diagnostics::DiagnosticReporter, expansion::ast::Mutability, hlir::ast::{ Command, Command_, Exp, FunctionSignature, SingleType, UnannotatedExp_, Value, Value_, Var, @@ -17,6 +18,7 @@ use crate::{ /// returns true if anything changed pub fn optimize( + _reporter: &DiagnosticReporter, _signature: &FunctionSignature, _locals: &UniqueMap, _constants: &UniqueMap, diff --git a/external-crates/move/crates/move-compiler/src/cfgir/translate.rs b/external-crates/move/crates/move-compiler/src/cfgir/translate.rs index d8200049b63..e0f49a31f7e 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/translate.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/translate.rs @@ -17,21 +17,23 @@ use petgraph::{ algo::{kosaraju_scc as petgraph_scc, toposort as petgraph_toposort}, graphmap::DiGraphMap, }; +use rayon::prelude::*; use crate::{ + FullyCompiledProgram, cfgir::{ self, ast::{self as G, BasicBlock, BasicBlocks, BlockInfo}, cfg::{ImmForwardCFG, MutForwardCFG}, - visitor::{CFGIRVisitorConstructor, CFGIRVisitorContext}, + visitor::{CFGIRVisitor, CFGIRVisitorConstructor, CFGIRVisitorContext}, }, diag, - diagnostics::Diagnostics, + diagnostics::{Diagnostic, DiagnosticReporter, Diagnostics, warning_filters::WarningFilters}, expansion::ast::{Attributes, ModuleIdent, Mutability}, hlir::ast::{self as H, BlockLabel, Label, Value, Value_, Var}, + ice_assert, parser::ast::{ConstantName, FunctionName}, - shared::{program_info::TypingProgramInfo, unique_map::UniqueMap, CompilationEnv}, - FullyCompiledProgram, + shared::{CompilationEnv, program_info::TypingProgramInfo, unique_map::UniqueMap}, }; //************************************************************************************************** @@ -45,8 +47,9 @@ enum NamedBlockType { } struct Context<'env> { - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, info: &'env TypingProgramInfo, + reporter: DiagnosticReporter<'env>, current_package: Option, label_count: usize, named_blocks: UniqueMap, @@ -55,9 +58,11 @@ struct Context<'env> { } impl<'env> Context<'env> { - pub fn new(env: &'env mut CompilationEnv, info: &'env TypingProgramInfo) -> Self { + pub fn new(env: &'env CompilationEnv, info: &'env TypingProgramInfo) -> Self { + let reporter = env.diagnostic_reporter_at_top_level(); Context { env, + reporter, info, current_package: None, label_count: 0, @@ -66,6 +71,22 @@ impl<'env> Context<'env> { } } + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + fn new_label(&mut self) -> Label { let count = self.label_count; self.label_count += 1; @@ -80,13 +101,10 @@ impl<'env> Context<'env> { let start_label = self.new_label(); let end_label = self.new_label(); if matches!(block_type, NamedBlockType::Loop | NamedBlockType::While) { - self.loop_bounds.insert( - start_label, - LoopInfo { - is_loop_stmt: matches!(block_type, NamedBlockType::Loop), - loop_end: G::LoopEnd::Target(end_label), - }, - ); + self.loop_bounds.insert(start_label, LoopInfo { + is_loop_stmt: matches!(block_type, NamedBlockType::Loop), + loop_end: G::LoopEnd::Target(end_label), + }); } self.named_blocks .add(name, (start_label, end_label)) @@ -124,12 +142,13 @@ impl<'env> Context<'env> { //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, _pre_compiled_lib: Option>, prog: H::Program, ) -> G::Program { let H::Program { modules: hmodules, + warning_filters_table, info, } = prog; @@ -139,6 +158,7 @@ pub fn program( let mut program = G::Program { modules, + warning_filters_table, info: info.clone(), }; visit_program(&mut context, &mut program); @@ -173,26 +193,23 @@ fn module( constants: hconstants, } = mdef; context.current_package = package_name; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let constants = constants(context, module_ident, hconstants); let functions = hfunctions.map(|name, f| function(context, module_ident, name, f)); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); context.current_package = None; - ( - module_ident, - G::ModuleDefinition { - warning_filter, - package_name, - attributes, - target_kind, - dependency_order, - friends, - structs, - enums, - constants, - functions, - }, - ) + (module_ident, G::ModuleDefinition { + warning_filter, + package_name, + attributes, + target_kind, + dependency_order, + friends, + structs, + enums, + constants, + functions, + }) } //************************************************************************************************** @@ -229,7 +246,7 @@ fn constants( .collect::>() .join(", "); let mut diag = diag!( - BytecodeGeneration::UnfoldableConstant, + CodeGeneration::UnfoldableConstant, ( *consts.get_loc(&scc[0]).unwrap(), format!("Constant definitions form a circular dependency: {}", names), @@ -241,7 +258,7 @@ fn constants( "Cyclic constant defined here", )); } - context.env.add_diag(diag); + context.add_diag(diag); cycle_nodes.append(&mut scc.into_iter().collect()); } } @@ -255,8 +272,8 @@ fn constants( .filter(|node| !cycle_nodes.contains(node) && graph.contains_node(*node)) .collect(); for node in neighbors { - context.env.add_diag(diag!( - BytecodeGeneration::UnfoldableConstant, + context.add_diag(diag!( + CodeGeneration::UnfoldableConstant, ( *consts.get_loc(&node).unwrap(), format!( @@ -329,7 +346,7 @@ fn dependent_constants(constant: &H::Constant) -> BTreeSet { match command { C::IgnoreAndPop { exp, .. } => dep_exp(set, exp), C::Return { exp, .. } => dep_exp(set, exp), - C::Abort(exp) | C::Assign(_, _, exp) => dep_exp(set, exp), + C::Abort(_, exp) | C::Assign(_, _, exp) => dep_exp(set, exp), C::Mutate(lhs, rhs) => { dep_exp(set, lhs); dep_exp(set, rhs) @@ -407,7 +424,7 @@ fn constant( value: (locals, block), } = c; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let final_value = constant_( context, constant_values, @@ -432,7 +449,7 @@ fn constant( _ => None, }; - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); G::Constant { warning_filter, index, @@ -476,6 +493,8 @@ fn constant_( }; let fake_infinite_loop_starts = BTreeSet::new(); let function_context = super::CFGContext { + env: context.env, + reporter: &context.reporter, info: context.info, package: context.current_package, module, @@ -487,14 +506,17 @@ fn constant_( locals: &locals, infinite_loop_starts: &fake_infinite_loop_starts, }; - cfgir::refine_inference_and_verify(context.env, &function_context, &mut cfg); - assert!( + cfgir::refine_inference_and_verify(&function_context, &mut cfg); + ice_assert!( + context.reporter, num_previous_errors == context.env.count_diags(), + full_loc, "{}", ICE_MSG ); cfgir::optimize( context.env, + &context.reporter, context.current_package, &fake_signature, &locals, @@ -503,8 +525,8 @@ fn constant_( ); if blocks.len() != 1 { - context.env.add_diag(diag!( - BytecodeGeneration::UnfoldableConstant, + context.add_diag(diag!( + CodeGeneration::UnfoldableConstant, (full_loc, CANNOT_FOLD) )); return None; @@ -515,8 +537,8 @@ fn constant_( let e = match cmd_ { C::IgnoreAndPop { exp, .. } => exp, _ => { - context.env.add_diag(diag!( - BytecodeGeneration::UnfoldableConstant, + context.add_diag(diag!( + CodeGeneration::UnfoldableConstant, (*cloc, CANNOT_FOLD) )); continue; @@ -537,8 +559,8 @@ fn check_constant_value(context: &mut Context, e: &H::Exp) { use H::UnannotatedExp_ as E; match &e.exp.value { E::Value(_) => (), - _ => context.env.add_diag(diag!( - BytecodeGeneration::UnfoldableConstant, + _ => context.add_diag(diag!( + CodeGeneration::UnfoldableConstant, (e.exp.loc, CANNOT_FOLD) )), } @@ -578,13 +600,14 @@ fn function( warning_filter, index, attributes, + loc, visibility, compiled_visibility, entry, signature, body, } = f; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let body = function_body( context, module, @@ -595,11 +618,12 @@ fn function( &signature, body, ); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); G::Function { warning_filter, index, attributes, + loc, visibility, compiled_visibility, entry, @@ -632,9 +656,11 @@ fn function_body( let (mut cfg, infinite_loop_starts, diags) = MutForwardCFG::new(start, &mut blocks, binfo); - context.env.add_diags(diags); + context.add_diags(diags); let function_context = super::CFGContext { + env: context.env, + reporter: &context.reporter, info: context.info, package: context.current_package, module, @@ -646,11 +672,12 @@ fn function_body( locals: &locals, infinite_loop_starts: &infinite_loop_starts, }; - cfgir::refine_inference_and_verify(context.env, &function_context, &mut cfg); + cfgir::refine_inference_and_verify(&function_context, &mut cfg); // do not optimize if there are errors, warnings are okay if !context.env.has_errors() { cfgir::optimize( context.env, + &context.reporter, context.current_package, signature, &locals, @@ -658,7 +685,6 @@ fn function_body( &mut cfg, ); } - let block_info = block_info .into_iter() .filter(|(lbl, _info)| blocks.contains_key(lbl)) @@ -771,14 +797,11 @@ fn statement( let false_label = context.new_label(); let phi_label = context.new_label(); - let test_block = VecDeque::from([sp( - sloc, - C::JumpIf { - cond: *test, - if_true: true_label, - if_false: false_label, - }, - )]); + let test_block = VecDeque::from([sp(sloc, C::JumpIf { + cond: *test, + if_true: true_label, + if_false: false_label, + })]); let (true_entry_block, true_blocks) = block_( context, @@ -830,14 +853,11 @@ fn statement( arm_blocks.push((phi_label, current_block)); - let test_block = VecDeque::from([sp( - sloc, - C::VariantSwitch { - subject, - enum_name, - arms, - }, - )]); + let test_block = VecDeque::from([sp(sloc, C::VariantSwitch { + subject, + enum_name, + arms, + })]); (test_block, arm_blocks) } @@ -854,14 +874,11 @@ fn statement( let entry_block = VecDeque::from([make_jump(sloc, start_label, false)]); let (initial_test_block, test_blocks) = { - let test_jump = sp( - sloc, - C::JumpIf { - cond: *test, - if_true: body_label, - if_false: end_label, - }, - ); + let test_jump = sp(sloc, C::JumpIf { + cond: *test, + if_true: body_label, + if_false: end_label, + }); block_(context, with_last(test_block, test_jump)) }; @@ -976,15 +993,18 @@ fn visit_program(context: &mut Context, prog: &mut G::Program) { AbsintVisitor.visit(context.env, prog); - for visitor in &context.env.visitors().cfgir { - let mut v = visitor.borrow_mut(); - v.visit(context.env, prog) - } + context + .env + .visitors() + .cfgir + .par_iter() + .for_each(|v| v.visit(context.env, prog)); } struct AbsintVisitor; struct AbsintVisitorContext<'a> { - env: &'a mut CompilationEnv, + env: &'a CompilationEnv, + reporter: DiagnosticReporter<'a>, info: Arc, current_package: Option, } @@ -992,25 +1012,38 @@ struct AbsintVisitorContext<'a> { impl CFGIRVisitorConstructor for AbsintVisitor { type Context<'a> = AbsintVisitorContext<'a>; - fn context<'a>(env: &'a mut CompilationEnv, program: &G::Program) -> Self::Context<'a> { + fn context<'a>(env: &'a CompilationEnv, program: &G::Program) -> Self::Context<'a> { + let reporter = env.diagnostic_reporter_at_top_level(); AbsintVisitorContext { env, + reporter, info: program.info.clone(), current_package: None, } } } +impl AbsintVisitorContext<'_> { + #[allow(unused)] + fn add_diag(&self, diag: crate::diagnostics::Diagnostic) { + self.reporter.add_diag(diag); + } + + fn add_diags(&self, diags: crate::diagnostics::Diagnostics) { + self.reporter.add_diags(diags); + } +} + impl<'a> CFGIRVisitorContext for AbsintVisitorContext<'a> { - fn add_warning_filter_scope(&mut self, filter: crate::diagnostics::WarningFilters) { - self.env.add_warning_filter_scope(filter) + fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) } fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() + self.reporter.pop_warning_filter_scope() } - fn visit_module_custom(&mut self, _ident: ModuleIdent, mdef: &mut G::ModuleDefinition) -> bool { + fn visit_module_custom(&mut self, _ident: ModuleIdent, mdef: &G::ModuleDefinition) -> bool { self.current_package = mdef.package_name; false } @@ -1019,12 +1052,13 @@ impl<'a> CFGIRVisitorContext for AbsintVisitorContext<'a> { &mut self, mident: ModuleIdent, name: FunctionName, - fdef: &mut G::Function, + fdef: &G::Function, ) -> bool { let G::Function { warning_filter: _, index: _, attributes, + loc: _, compiled_visibility: _, visibility, entry, @@ -1042,6 +1076,8 @@ impl<'a> CFGIRVisitorContext for AbsintVisitorContext<'a> { }; let (cfg, infinite_loop_starts) = ImmForwardCFG::new(*start, blocks, block_info.iter()); let function_context = super::CFGContext { + env: self.env, + reporter: &self.reporter, info: &self.info, package: self.current_package, module: mident, @@ -1053,12 +1089,11 @@ impl<'a> CFGIRVisitorContext for AbsintVisitorContext<'a> { locals, infinite_loop_starts: &infinite_loop_starts, }; - let mut ds = Diagnostics::new(); - for visitor in &self.env.visitors().abs_int { - let mut v = visitor.borrow_mut(); - ds.extend(v.verify(self.env, &function_context, &cfg)); - } - self.env.add_diags(ds); + self.env + .visitors() + .abs_int + .par_iter() + .for_each(|v| self.add_diags(v.verify(&function_context, &cfg))); true } } diff --git a/external-crates/move/crates/move-compiler/src/cfgir/visitor.rs b/external-crates/move/crates/move-compiler/src/cfgir/visitor.rs index 2d7638b8d2b..b7e3c659d62 100644 --- a/external-crates/move/crates/move-compiler/src/cfgir/visitor.rs +++ b/external-crates/move/crates/move-compiler/src/cfgir/visitor.rs @@ -4,29 +4,30 @@ use std::{collections::BTreeMap, fmt::Debug}; +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; use move_proc_macros::growing_stack; use crate::{ cfgir::{ + CFGContext, absint::{AbstractDomain, AbstractInterpreter, JoinResult, TransferFunctions}, ast as G, cfg::ImmForwardCFG, - CFGContext, }, command_line::compiler::Visitor, - diagnostics::{Diagnostic, Diagnostics, WarningFilters}, + diagnostics::{Diagnostic, Diagnostics, warning_filters::WarningFilters}, expansion::ast::ModuleIdent, hlir::ast::{self as H, Command, Exp, LValue, LValue_, Label, ModuleCall, Type, Type_, Var}, - parser::ast::{ConstantName, DatatypeName, FunctionName}, + parser::ast::{ConstantName, DatatypeName, Field, FunctionName}, shared::CompilationEnv, }; pub type AbsIntVisitorObj = Box; pub type CFGIRVisitorObj = Box; -pub trait CFGIRVisitor { - fn visit(&mut self, env: &mut CompilationEnv, program: &mut G::Program); +pub trait CFGIRVisitor: Send + Sync { + fn visit(&self, env: &CompilationEnv, program: &G::Program); fn visitor(self) -> Visitor where @@ -36,13 +37,8 @@ pub trait CFGIRVisitor { } } -pub trait AbstractInterpreterVisitor { - fn verify( - &mut self, - env: &CompilationEnv, - context: &CFGContext, - cfg: &ImmForwardCFG, - ) -> Diagnostics; +pub trait AbstractInterpreterVisitor: Send + Sync { + fn verify(&self, context: &CFGContext, cfg: &ImmForwardCFG) -> Diagnostics; fn visitor(self) -> Visitor where @@ -53,53 +49,49 @@ pub trait AbstractInterpreterVisitor { } //************************************************************************************************** -// simple ast visitor +// CFGIR visitor //************************************************************************************************** -pub trait CFGIRVisitorConstructor { +pub trait CFGIRVisitorConstructor: Send { type Context<'a>: Sized + CFGIRVisitorContext; - fn context<'a>(env: &'a mut CompilationEnv, program: &G::Program) -> Self::Context<'a>; + fn context<'a>(env: &'a CompilationEnv, program: &G::Program) -> Self::Context<'a>; - fn visit(&mut self, env: &mut CompilationEnv, program: &mut G::Program) { + fn visit(env: &CompilationEnv, program: &G::Program) { let mut context = Self::context(env, program); context.visit(program); } } pub trait CFGIRVisitorContext { - fn add_warning_filter_scope(&mut self, filter: WarningFilters); + fn push_warning_filter_scope(&mut self, filters: WarningFilters); fn pop_warning_filter_scope(&mut self); - fn visit_module_custom( - &mut self, - _ident: ModuleIdent, - _mdef: &mut G::ModuleDefinition, - ) -> bool { + fn visit_module_custom(&mut self, _ident: ModuleIdent, _mdef: &G::ModuleDefinition) -> bool { false } - /// By default, the visitor will visit all all expressions in all functions in all modules. A - /// custom version should of this function should be created if different type of analysis is - /// required. - fn visit(&mut self, program: &mut G::Program) { - for (mident, mdef) in program.modules.key_cloned_iter_mut() { - self.add_warning_filter_scope(mdef.warning_filter.clone()); + /// By default, the visitor will visit all all expressions in all functions + /// in all modules. A custom version should of this function should be + /// created if different type of analysis is required. + fn visit(&mut self, program: &G::Program) { + for (mident, mdef) in program.modules.key_cloned_iter() { + self.push_warning_filter_scope(mdef.warning_filter); if self.visit_module_custom(mident, mdef) { self.pop_warning_filter_scope(); continue; } - for (struct_name, sdef) in mdef.structs.key_cloned_iter_mut() { + for (struct_name, sdef) in mdef.structs.key_cloned_iter() { self.visit_struct(mident, struct_name, sdef) } - for (enum_name, edef) in mdef.enums.key_cloned_iter_mut() { + for (enum_name, edef) in mdef.enums.key_cloned_iter() { self.visit_enum(mident, enum_name, edef) } - for (constant_name, cdef) in mdef.constants.key_cloned_iter_mut() { + for (constant_name, cdef) in mdef.constants.key_cloned_iter() { self.visit_constant(mident, constant_name, cdef) } - for (function_name, fdef) in mdef.functions.key_cloned_iter_mut() { + for (function_name, fdef) in mdef.functions.key_cloned_iter() { self.visit_function(mident, function_name, fdef) } @@ -113,7 +105,7 @@ pub trait CFGIRVisitorContext { &mut self, _module: ModuleIdent, _struct_name: DatatypeName, - _sdef: &mut H::StructDefinition, + _sdef: &H::StructDefinition, ) -> bool { false } @@ -121,9 +113,9 @@ pub trait CFGIRVisitorContext { &mut self, module: ModuleIdent, struct_name: DatatypeName, - sdef: &mut H::StructDefinition, + sdef: &H::StructDefinition, ) { - self.add_warning_filter_scope(sdef.warning_filter.clone()); + self.push_warning_filter_scope(sdef.warning_filter); if self.visit_struct_custom(module, struct_name, sdef) { self.pop_warning_filter_scope(); return; @@ -135,7 +127,7 @@ pub trait CFGIRVisitorContext { &mut self, _module: ModuleIdent, _enum_name: DatatypeName, - _edef: &mut H::EnumDefinition, + _edef: &H::EnumDefinition, ) -> bool { false } @@ -143,9 +135,9 @@ pub trait CFGIRVisitorContext { &mut self, module: ModuleIdent, enum_name: DatatypeName, - edef: &mut H::EnumDefinition, + edef: &H::EnumDefinition, ) { - self.add_warning_filter_scope(edef.warning_filter.clone()); + self.push_warning_filter_scope(edef.warning_filter); if self.visit_enum_custom(module, enum_name, edef) { self.pop_warning_filter_scope(); return; @@ -157,7 +149,7 @@ pub trait CFGIRVisitorContext { &mut self, _module: ModuleIdent, _constant_name: ConstantName, - _cdef: &mut G::Constant, + _cdef: &G::Constant, ) -> bool { false } @@ -165,9 +157,9 @@ pub trait CFGIRVisitorContext { &mut self, module: ModuleIdent, constant_name: ConstantName, - cdef: &mut G::Constant, + cdef: &G::Constant, ) { - self.add_warning_filter_scope(cdef.warning_filter.clone()); + self.push_warning_filter_scope(cdef.warning_filter); if self.visit_constant_custom(module, constant_name, cdef) { self.pop_warning_filter_scope(); return; @@ -179,7 +171,7 @@ pub trait CFGIRVisitorContext { &mut self, _module: ModuleIdent, _function_name: FunctionName, - _fdef: &mut G::Function, + _fdef: &G::Function, ) -> bool { false } @@ -187,9 +179,9 @@ pub trait CFGIRVisitorContext { &mut self, module: ModuleIdent, function_name: FunctionName, - fdef: &mut G::Function, + fdef: &G::Function, ) { - self.add_warning_filter_scope(fdef.warning_filter.clone()); + self.push_warning_filter_scope(fdef.warning_filter); if self.visit_function_custom(module, function_name, fdef) { self.pop_warning_filter_scope(); return; @@ -199,7 +191,7 @@ pub trait CFGIRVisitorContext { start: _, block_info: _, blocks, - } = &mut fdef.body.value + } = &fdef.body.value { for (lbl, block) in blocks { self.visit_block(*lbl, block); @@ -208,26 +200,26 @@ pub trait CFGIRVisitorContext { self.pop_warning_filter_scope(); } - fn visit_block_custom(&mut self, _lbl: Label, _block: &mut G::BasicBlock) -> bool { + fn visit_block_custom(&mut self, _lbl: Label, _block: &G::BasicBlock) -> bool { false } - fn visit_block(&mut self, _lbl: Label, block: &mut G::BasicBlock) { + fn visit_block(&mut self, _lbl: Label, block: &G::BasicBlock) { for cmd in block { self.visit_command(cmd) } } - fn visit_command_custom(&mut self, _cmd: &mut H::Command) -> bool { + fn visit_command_custom(&mut self, _cmd: &H::Command) -> bool { false } - fn visit_command(&mut self, cmd: &mut H::Command) { + fn visit_command(&mut self, cmd: &H::Command) { use H::Command_ as C; if self.visit_command_custom(cmd) { return; } - match &mut cmd.value { + match &cmd.value { C::Assign(_, _, e) - | C::Abort(e) + | C::Abort(_, e) | C::Return { exp: e, .. } | C::IgnoreAndPop { exp: e, .. } | C::JumpIf { cond: e, .. } @@ -243,16 +235,16 @@ pub trait CFGIRVisitorContext { } } - fn visit_exp_custom(&mut self, _e: &mut H::Exp) -> bool { + fn visit_exp_custom(&mut self, _e: &H::Exp) -> bool { false } #[growing_stack] - fn visit_exp(&mut self, e: &mut H::Exp) { + fn visit_exp(&mut self, e: &H::Exp) { use H::UnannotatedExp_ as E; if self.visit_exp_custom(e) { return; } - match &mut e.exp.value { + match &e.exp.value { E::Unit { .. } | E::Move { .. } | E::Copy { .. } @@ -276,7 +268,7 @@ pub trait CFGIRVisitorContext { } E::ModuleCall(m) => { - for arg in &mut m.arguments { + for arg in &m.arguments { self.visit_exp(arg) } } @@ -294,16 +286,16 @@ pub trait CFGIRVisitorContext { } } - fn visit_value_custom(&mut self, _v: &mut H::Value) -> bool { + fn visit_value_custom(&mut self, _v: &H::Value) -> bool { false } #[growing_stack] - fn visit_value(&mut self, v: &mut H::Value) { + fn visit_value(&mut self, v: &H::Value) { use H::Value_ as V; if self.visit_value_custom(v) { return; } - match &mut v.value { + match &v.value { V::Address(_) | V::U8(_) | V::U16(_) @@ -321,6 +313,70 @@ pub trait CFGIRVisitorContext { } } +impl From for CFGIRVisitorObj { + fn from(value: V) -> Self { + Box::new(value) + } +} + +impl CFGIRVisitor for V { + fn visit(&self, env: &CompilationEnv, program: &G::Program) { + Self::visit(env, program) + } +} + +macro_rules! simple_visitor { + ($visitor:ident, $($overrides:item),*) => { + pub struct $visitor; + + pub struct Context<'a> { + #[allow(unused)] + env: &'a crate::shared::CompilationEnv, + reporter: crate::diagnostics::DiagnosticReporter<'a>, + } + + impl crate::cfgir::visitor::CFGIRVisitorConstructor for $visitor { + type Context<'a> = Context<'a>; + + fn context<'a>(env: &'a crate::shared::CompilationEnv, _program: &crate::cfgir::ast::Program) -> Self::Context<'a> { + let reporter = env.diagnostic_reporter_at_top_level(); + Context { + env, + reporter, + } + } + } + + impl Context<'_> { + #[allow(unused)] + fn add_diag(&self, diag: crate::diagnostics::Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + fn add_diags(&self, diags: crate::diagnostics::Diagnostics) { + self.reporter.add_diags(diags); + } + } + + impl crate::cfgir::visitor::CFGIRVisitorContext for Context<'_> { + fn push_warning_filter_scope( + &mut self, + filters: crate::diagnostics::warning_filters::WarningFilters, + ) { + self.reporter.push_warning_filter_scope(filters) + } + + fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + + $($overrides)* + } + } +} +pub(crate) use simple_visitor; + //************************************************************************************************** // simple absint visitor //************************************************************************************************** @@ -447,17 +503,12 @@ pub trait SimpleAbsIntConstructor: Sized { /// Given the initial state/domain, construct a new abstract interpreter. /// Return None if it should not be run given this context fn new<'a>( - env: &CompilationEnv, context: &'a CFGContext<'a>, + cfg: &ImmForwardCFG, init_state: &mut as SimpleAbsInt>::State, ) -> Option>; - fn verify( - &mut self, - env: &CompilationEnv, - context: &CFGContext, - cfg: &ImmForwardCFG, - ) -> Diagnostics { + fn verify(context: &CFGContext, cfg: &ImmForwardCFG) -> Diagnostics { let mut locals = context .locals .key_cloned_iter() @@ -476,7 +527,7 @@ pub trait SimpleAbsIntConstructor: Sized { ); } let mut init_state = as SimpleAbsInt>::State::new(context, locals); - let Some(mut ai) = Self::new(env, context, &mut init_state) else { + let Some(mut ai) = Self::new(context, cfg, &mut init_state) else { return Diagnostics::new(); }; let (final_state, ds) = ai.analyze_function(cfg, init_state); @@ -542,7 +593,7 @@ pub trait SimpleAbsInt: Sized { | C::VariantSwitch { subject: e, .. } | C::IgnoreAndPop { exp: e, .. } | C::Return { exp: e, .. } - | C::Abort(e) => { + | C::Abort(_, e) => { self.exp(context, state, e); } C::Jump { .. } => (), @@ -759,13 +810,216 @@ impl TransferFunctions for V { } impl AbstractInterpreter for V {} -impl AbstractInterpreterVisitor for V { - fn verify( - &mut self, - env: &CompilationEnv, - context: &CFGContext, - cfg: &ImmForwardCFG, - ) -> Diagnostics { - SimpleAbsIntConstructor::verify(self, env, context, cfg) +impl From for AbsIntVisitorObj { + fn from(value: V) -> Self { + Box::new(value) + } +} + +impl AbstractInterpreterVisitor for V { + fn verify(&self, context: &CFGContext, cfg: &ImmForwardCFG) -> Diagnostics { + ::verify(context, cfg) + } +} + +//************************************************************************************************** +// utils +//************************************************************************************************** + +pub fn cfg_satisfies( + cfg: &ImmForwardCFG, + mut p_command: FCommand, + mut p_exp: FExp, +) -> bool +where + FCommand: FnMut(&Command) -> bool, + FExp: FnMut(&Exp) -> bool, +{ + cfg_satisfies_(cfg, &mut p_command, &mut p_exp) +} + +pub fn command_satisfies( + cmd: &Command, + mut p_command: FCommand, + mut p_exp: FExp, +) -> bool +where + FCommand: FnMut(&Command) -> bool, + FExp: FnMut(&Exp) -> bool, +{ + command_satisfies_(cmd, &mut p_command, &mut p_exp) +} + +pub fn exp_satisfies(e: &Exp, mut p: F) -> bool +where + F: FnMut(&Exp) -> bool, +{ + exp_satisfies_(e, &mut p) +} + +pub fn calls_special_function( + special: &[(AccountAddress, &str, &str)], + cfg: &ImmForwardCFG, +) -> bool { + cfg_satisfies(cfg, |_| true, |e| is_special_function(special, e)) +} + +pub fn calls_special_function_command( + special: &[(AccountAddress, &str, &str)], + cmd: &Command, +) -> bool { + command_satisfies(cmd, |_| true, |e| is_special_function(special, e)) +} + +pub fn calls_special_function_exp(special: &[(AccountAddress, &str, &str)], e: &Exp) -> bool { + exp_satisfies(e, |e| is_special_function(special, e)) +} + +fn is_special_function(special: &[(AccountAddress, &str, &str)], e: &Exp) -> bool { + use H::UnannotatedExp_ as E; + matches!( + &e.exp.value, + E::ModuleCall(call) if special.iter().any(|(a, m, f)| call.is(a, m, f)), + ) +} + +fn cfg_satisfies_( + cfg: &ImmForwardCFG, + p_command: &mut impl FnMut(&Command) -> bool, + p_exp: &mut impl FnMut(&Exp) -> bool, +) -> bool { + cfg.blocks().values().any(|block| { + block + .iter() + .any(|cmd| command_satisfies_(cmd, p_command, p_exp)) + }) +} + +fn command_satisfies_( + cmd @ sp!(_, cmd_): &Command, + p_command: &mut impl FnMut(&Command) -> bool, + p_exp: &mut impl FnMut(&Exp) -> bool, +) -> bool { + use H::Command_ as C; + p_command(cmd) + || match cmd_ { + C::Assign(_, _, e) + | C::Abort(_, e) + | C::Return { exp: e, .. } + | C::IgnoreAndPop { exp: e, .. } + | C::JumpIf { cond: e, .. } + | C::VariantSwitch { subject: e, .. } => exp_satisfies_(e, p_exp), + C::Mutate(el, er) => exp_satisfies_(el, p_exp) || exp_satisfies_(er, p_exp), + C::Jump { .. } => false, + C::Break(_) | C::Continue(_) => panic!("ICE break/continue not translated to jumps"), + } +} + +#[growing_stack] +fn exp_satisfies_(e: &Exp, p: &mut impl FnMut(&Exp) -> bool) -> bool { + use H::UnannotatedExp_ as E; + if p(e) { + return true; + } + match &e.exp.value { + E::Unit { .. } + | E::Move { .. } + | E::Copy { .. } + | E::Constant(_) + | E::ErrorConstant { .. } + | E::BorrowLocal(_, _) + | E::Unreachable + | E::UnresolvedError + | E::Value(_) => false, + + E::Freeze(e) + | E::Dereference(e) + | E::UnaryExp(_, e) + | E::Borrow(_, e, _, _) + | E::Cast(e, _) => exp_satisfies_(e, p), + + E::BinopExp(el, _, er) => exp_satisfies_(el, p) || exp_satisfies_(er, p), + + E::ModuleCall(call) => call.arguments.iter().any(|arg| exp_satisfies_(arg, p)), + E::Vector(_, _, _, es) | E::Multiple(es) => es.iter().any(move |e| exp_satisfies_(e, p)), + + E::Pack(_, _, es) | E::PackVariant(_, _, _, es) => { + es.iter().any(|(_, _, e)| exp_satisfies_(e, p)) + } + } +} + +/// Assumes equal types and as such will not check type arguments for equality. +/// Assumes function calls, assignments, and similar expressions are effectful +/// and thus not equal. +pub fn same_value_exp(e1: &H::Exp, e2: &H::Exp) -> bool { + same_value_exp_(&e1.exp.value, &e2.exp.value) +} + +#[growing_stack] +pub fn same_value_exp_(e1: &H::UnannotatedExp_, e2: &H::UnannotatedExp_) -> bool { + use H::UnannotatedExp_ as E; + match (e1, e2) { + (E::Dereference(e) | E::Freeze(e), other) | (other, E::Dereference(e) | E::Freeze(e)) => { + same_value_exp_(&e.exp.value, other) + } + + (E::Value(v1), E::Value(v2)) => v1 == v2, + (E::Unit { .. }, E::Unit { .. }) => true, + (E::Constant(c1), E::Constant(c2)) => c1 == c2, + (E::Move { var, .. } | E::Copy { var, .. } | E::BorrowLocal(_, var), other) + | (other, E::Move { var, .. } | E::Copy { var, .. } | E::BorrowLocal(_, var)) => { + same_local_(var, other) + } + + (E::Vector(_, _, _, e1), E::Vector(_, _, _, e2)) => { + e1.len() == e2.len() + && e1 + .iter() + .zip(e2.iter()) + .all(|(e1, e2)| same_value_exp(e1, e2)) + } + + (E::UnaryExp(op1, e1), E::UnaryExp(op2, e2)) => op1 == op2 && same_value_exp(e1, e2), + (E::BinopExp(l1, op1, r1), E::BinopExp(l2, op2, r2)) => { + op1 == op2 && same_value_exp(l1, l2) && same_value_exp(r1, r2) + } + + (E::Pack(n1, _, fields1), E::Pack(n2, _, fields2)) => { + n1 == n2 && same_value_fields(fields1, fields2) + } + (E::PackVariant(n1, v1, _, fields1), E::PackVariant(n2, v2, _, fields2)) => { + n1 == n2 && v1 == v2 && same_value_fields(fields1, fields2) + } + + (E::Borrow(_, e1, f1, _), E::Borrow(_, e2, f2, _)) => f1 == f2 && same_value_exp(e1, e2), + + // false for anything effectful + (E::ModuleCall(_), _) => false, + + // TODO there is some potential for equality here, but a bit too brittle now + (E::Cast(_, _), _) | (E::ErrorConstant { .. }, _) => false, + + // catch all + _ => false, + } +} + +fn same_value_fields( + fields1: &[(Field, H::BaseType, Exp)], + fields2: &[(Field, H::BaseType, Exp)], +) -> bool { + fields1.len() == fields2.len() + && fields1 + .iter() + .zip(fields2.iter()) + .all(|((_, _, e1), (_, _, e2))| same_value_exp(e1, e2)) +} + +fn same_local_(lhs: &Var, rhs: &H::UnannotatedExp_) -> bool { + use H::UnannotatedExp_ as E; + match &rhs { + E::Copy { var: r, .. } | E::Move { var: r, .. } | E::BorrowLocal(_, r) => lhs == r, + _ => false, } } diff --git a/external-crates/move/crates/move-compiler/src/command_line/compiler.rs b/external-crates/move/crates/move-compiler/src/command_line/compiler.rs index b60708696fb..d75ece49d65 100644 --- a/external-crates/move/crates/move-compiler/src/command_line/compiler.rs +++ b/external-crates/move/crates/move-compiler/src/command_line/compiler.rs @@ -11,7 +11,8 @@ use crate::{ command_line::{DEFAULT_OUTPUT_DIR, MOVE_COMPILED_INTERFACES_DIR}, compiled_unit::{self, AnnotatedCompiledUnit}, diagnostics::{ - codes::{Severity, WarningFilter}, + codes::Severity, + warning_filters::{WarningFilter, WarningFiltersBuilder}, *, }, editions::Edition, @@ -60,7 +61,7 @@ pub struct Compiler { flags: Flags, visitors: Vec, /// Predefined filter for compiler warnings. - warning_filter: Option, + warning_filter: Option, known_warning_filters: Vec<(/* Prefix */ Option, Vec)>, package_configs: BTreeMap, default_config: Option, @@ -100,6 +101,7 @@ enum PassResult { #[derive(Clone)] pub struct FullyCompiledProgram { pub files: MappedFiles, + pub comments: CommentMap, pub parser: parser::ast::Program, pub expansion: expansion::ast::Program, pub naming: naming::ast::Program, @@ -278,7 +280,7 @@ impl Compiler { self } - pub fn set_warning_filter(mut self, filter: Option) -> Self { + pub fn set_warning_filter(mut self, filter: Option) -> Self { assert!(self.warning_filter.is_none()); self.warning_filter = filter; self @@ -376,17 +378,19 @@ impl Compiler { interface_files_dir_opt, &compiled_module_named_address_mapping, )?; - let mut compilation_env = - CompilationEnv::new(flags, visitors, save_hooks, package_configs, default_config); - if let Some(filter) = warning_filter { - compilation_env.add_warning_filter_scope(filter); - } + let mut compilation_env = CompilationEnv::new( + flags, + visitors, + save_hooks, + warning_filter, + package_configs, + default_config, + ); for (prefix, filters) in known_warning_filters { compilation_env.add_custom_known_filters(prefix, filters)?; } - let (source_text, pprog, comments) = - parse_program(&mut compilation_env, maps, targets, deps)?; + let (source_text, pprog, comments) = parse_program(&compilation_env, maps, targets, deps)?; for (fhash, (fname, contents)) in &source_text { // TODO better support for bytecode interface file paths @@ -480,12 +484,12 @@ impl SteppedCompiler

{ "Invalid pass for run_to. Target pass precedes the current pass" ); let Self { - mut compilation_env, + compilation_env, pre_compiled_lib, program, } = self; let new_prog = run( - &mut compilation_env, + &compilation_env, pre_compiled_lib.clone(), program.unwrap(), TARGET, @@ -498,10 +502,7 @@ impl SteppedCompiler

{ }) } - pub fn compilation_env(&mut self) -> &mut CompilationEnv { - &mut self.compilation_env - } - pub fn compilation_env_ref(&self) -> &CompilationEnv { + pub fn compilation_env(&self) -> &CompilationEnv { &self.compilation_env } } @@ -652,18 +653,19 @@ pub fn construct_pre_compiled_lib, NamedAddress: Into()?; - let (_comments, stepped) = match pprog_and_comments_res { + let (comments, stepped) = match pprog_and_comments_res { Err((_pass, errors)) => return Ok(Err((files, errors))), Ok(res) => res, }; let (empty_compiler, ast) = stepped.into_ast(); - let mut compilation_env = empty_compiler.compilation_env; + let compilation_env = empty_compiler.compilation_env; let start = PassResult::Parser(ast); - match run(&mut compilation_env, None, start, PASS_COMPILATION) { + match run(&compilation_env, None, start, PASS_COMPILATION) { Err((_pass, errors)) => Ok(Err((files, errors))), Ok(PassResult::Compilation(compiled, _)) => Ok(Ok(FullyCompiledProgram { files, + comments, parser: hook.take_parser_ast(), expansion: hook.take_expansion_ast(), naming: hook.take_naming_ast(), @@ -889,7 +891,7 @@ pub fn move_check_for_errors( ) -> Result<(Vec, Diagnostics), (Pass, Diagnostics)> { let (_, compiler) = comments_and_compiler_res?; - let (mut compiler, cfgir) = compiler.run::()?.into_ast(); + let (compiler, cfgir) = compiler.run::()?.into_ast(); let compilation_env = compiler.compilation_env(); if compilation_env.flags().is_testing() { unit_test::plan_builder::construct_test_plan(compilation_env, None, &cfgir); @@ -925,7 +927,7 @@ impl PassResult { } } - pub fn save(&self, compilation_env: &mut CompilationEnv) { + pub fn save(&self, compilation_env: &CompilationEnv) { match self { PassResult::Parser(prog) => { compilation_env.save_parser_ast(prog); @@ -952,14 +954,14 @@ impl PassResult { } fn run( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, cur: PassResult, until: Pass, ) -> Result { #[growing_stack] fn rec( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, cur: PassResult, until: Pass, @@ -1066,13 +1068,3 @@ fn run( } rec(compilation_env, pre_compiled_lib, cur, until) } - -//************************************************************************************************** -// traits -//************************************************************************************************** - -impl From for Visitor { - fn from(f: AbsIntVisitorObj) -> Self { - Self::AbsIntVisitor(f) - } -} diff --git a/external-crates/move/crates/move-compiler/src/diagnostics/codes.rs b/external-crates/move/crates/move-compiler/src/diagnostics/codes.rs index 21faccfd8c3..37a41ded795 100644 --- a/external-crates/move/crates/move-compiler/src/diagnostics/codes.rs +++ b/external-crates/move/crates/move-compiler/src/diagnostics/codes.rs @@ -7,8 +7,6 @@ // Main types //************************************************************************************************** -use crate::shared::FILTER_ALL; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, PartialOrd, Ord)] pub enum Severity { Note = 0, @@ -21,13 +19,11 @@ pub enum Severity { /// A an optional prefix to distinguish between different types of warnings /// (internal vs. possibly multiple externally provided ones). pub type ExternalPrefix = Option<&'static str>; -/// The name for a well-known filter. -pub type WellKnownFilterName = &'static str; /// The ID for a diagnostic, consisting of an optional prefix, a category, and a /// code. pub type DiagnosticsID = (ExternalPrefix, u8, u8); -#[derive(PartialEq, Eq, Clone, Debug, Hash)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Hash)] pub struct DiagnosticInfo { severity: Severity, category: u8, @@ -57,28 +53,6 @@ pub(crate) trait DiagnosticCode: Copy { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug, PartialOrd, Ord)] -/// Represents a single annotation for a diagnostic filter -pub enum WarningFilter { - /// Filters all warnings - All(ExternalPrefix), - /// Filters all warnings of a specific category. Only known filters have - /// names. - Category { - prefix: ExternalPrefix, - category: u8, - name: Option, - }, - /// Filters a single warning, as defined by codes below. Only known filters - /// have names. - Code { - prefix: ExternalPrefix, - category: u8, - code: u8, - name: Option, - }, -} - //************************************************************************************************** // Categories and Codes //************************************************************************************************** @@ -318,7 +292,7 @@ codes!( InvalidTransfer: { msg: "invalid transfer of references", severity: NonblockingError }, AmbiguousVariableUsage: { msg: "ambiguous usage of variable", severity: NonblockingError }, ], - BytecodeGeneration: [ + CodeGeneration: [ UnfoldableConstant: { msg: "cannot compute constant value", severity: NonblockingError }, ], // errors for any unused code or items @@ -391,45 +365,6 @@ codes!( ], ); -//************************************************************************************************** -// Warning Filter -//************************************************************************************************** - -impl WarningFilter { - pub fn to_str(self) -> Option<&'static str> { - match self { - Self::All(_) => Some(FILTER_ALL), - Self::Category { name, .. } | Self::Code { name, .. } => name, - } - } - - pub fn code( - prefix: ExternalPrefix, - category: u8, - code: u8, - name: Option, - ) -> Self { - Self::Code { - prefix, - category, - code, - name, - } - } - - pub fn category( - prefix: ExternalPrefix, - category: u8, - name: Option, - ) -> Self { - Self::Category { - prefix, - category, - name, - } - } -} - //************************************************************************************************** // impls //************************************************************************************************** diff --git a/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs b/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs index 6806064adaf..4b0fb9b8a93 100644 --- a/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs +++ b/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 pub mod codes; +pub mod warning_filters; use std::{ collections::{BTreeMap, BTreeSet, HashSet}, @@ -11,14 +12,14 @@ use std::{ iter::FromIterator, ops::Range, path::PathBuf, + sync::RwLock, }; use codespan_reporting::{ self as csr, term::{ - emit, + Config, emit, termcolor::{Buffer, ColorChoice, StandardStream, WriteColor}, - Config, }, }; use csr::files::Files; @@ -26,18 +27,18 @@ use move_command_line_common::{env::read_env_var, files::FileHash}; use move_ir_types::location::*; use serde::{Deserialize, Serialize}; -use self::codes::UnusedItem; use crate::{ + Flags, command_line::COLOR_MODE_ENV_VAR, - diagnostics::codes::{ - Category, DiagnosticCode, DiagnosticInfo, ExternalPrefix, Severity, WarningFilter, - WellKnownFilterName, + diagnostics::{ + codes::{Category, DiagnosticCode, DiagnosticInfo, DiagnosticsID, Severity}, + warning_filters::{FilterName, FilterPrefix, WarningFilters, WarningFiltersScope}, }, shared::{ - ast_debug::AstDebug, files::{ByteSpan, FileByteSpan, FileId, MappedFiles}, - known_attributes, FILTER_UNUSED_CONST, FILTER_UNUSED_FUNCTION, FILTER_UNUSED_MUT_PARAM, - FILTER_UNUSED_MUT_REF, FILTER_UNUSED_STRUCT_FIELD, FILTER_UNUSED_TYPE_PARAMETER, + format_allow_attr, + ide::{IDEAnnotation, IDEInfo}, + known_attributes, }, }; @@ -45,13 +46,13 @@ use crate::{ // Types //************************************************************************************************** -#[derive(PartialEq, Eq, Clone, Debug, Hash)] -#[must_use] -pub struct Diagnostic { - info: DiagnosticInfo, - primary_label: (Loc, String), - secondary_labels: Vec<(Loc, String)>, - notes: Vec, +#[derive(Clone, Debug)] +pub struct DiagnosticReporter<'env> { + flags: &'env Flags, + known_filter_names: &'env BTreeMap, + diags: &'env RwLock, + ide_information: &'env RwLock, + warning_filters_scope: WarningFiltersScope, } #[derive(PartialEq, Eq, Hash, Clone, Debug, Default)] @@ -68,6 +69,15 @@ struct Diagnostics_ { severity_count: BTreeMap, } +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Hash)] +#[must_use] +pub struct Diagnostic { + info: DiagnosticInfo, + primary_label: (Loc, String), + secondary_labels: Vec<(Loc, String)>, + notes: Vec, +} + #[derive(PartialEq, Eq, Hash, Clone, Debug, Default)] pub enum DiagnosticsFormat { #[default] @@ -86,28 +96,6 @@ struct JsonDiagnostic { msg: String, } -#[derive(PartialEq, Eq, Clone, Debug)] -/// Used to filter out diagnostics, specifically used for warning suppression -pub struct WarningFilters { - filters: BTreeMap, - for_dependency: bool, // if false, the filters are used for source code -} - -#[derive(PartialEq, Eq, Clone, Debug)] -/// Filters split by category and code -enum UnprefixedWarningFilters { - /// Remove all warnings - All, - Specified { - /// Remove all diags of this category with optional known name - categories: BTreeMap>, - /// Remove specific diags with optional known filter name - codes: BTreeMap<(u8, u8), Option>, - }, - /// No filter - Empty, -} - #[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord)] enum MigrationChange { AddMut, @@ -239,7 +227,7 @@ fn render_diagnostics(writer: &mut dyn WriteColor, mapping: &MappedFiles, diags: diags.diagnostics.sort_by(|e1, e2| { let loc1: &Loc = &e1.primary_label.0; let loc2: &Loc = &e2.primary_label.0; - loc1.cmp(loc2) + loc1.cmp(loc2).then_with(|| e1.cmp(e2)) }); match format { DiagnosticsFormat::Text => emit_diagnostics_text(writer, mapping, diags), @@ -383,6 +371,100 @@ pub fn report_migration_to_buffer(files: &MappedFiles, diags: Diagnostics) -> Ve // impls //************************************************************************************************** +impl<'env> DiagnosticReporter<'env> { + pub const fn new( + flags: &'env Flags, + known_filter_names: &'env BTreeMap, + diags: &'env RwLock, + ide_information: &'env RwLock, + warning_filters_scope: WarningFiltersScope, + ) -> Self { + Self { + flags, + known_filter_names, + diags, + ide_information, + warning_filters_scope, + } + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.warning_filters_scope.push(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.warning_filters_scope.pop() + } + + pub fn add_diag(&self, mut diag: Diagnostic) { + if diag.info().severity() <= Severity::NonblockingError + && self + .diags + .read() + .unwrap() + .any_syntax_error_with_primary_loc(diag.primary_loc()) + { + // do not report multiple diags for the same location (unless they are blocking) + // to avoid noise that is likely to confuse the developer trying to + // localize the problem + // + // TODO: this check is O(n^2) for n diags - shouldn't be a huge problem but fix + // if it becomes one + return; + } + + if !self.warning_filters_scope.is_filtered(&diag) { + // add help to suppress warning, if applicable + // TODO do we want a centralized place for tips like this? + if diag.info().severity() == Severity::Warning { + if let Some((prefix, name)) = self.known_filter_names.get(&diag.info().id()) { + let help = format!( + "This warning can be suppressed with '#[{}({})]' \ + applied to the 'module' or module member ('const', 'fun', or 'struct')", + known_attributes::DiagnosticAttribute::ALLOW, + format_allow_attr(*prefix, *name), + ); + diag.add_note(help) + } + if self.flags.warnings_are_errors() { + diag = diag.set_severity(Severity::NonblockingError) + } + } + self.diags.write().unwrap().add(diag) + } else if !self.warning_filters_scope.is_filtered_for_dependency() { + // unwrap above is safe as the filter has been used (thus it must exist) + self.diags.write().unwrap().add_source_filtered(diag) + } + } + + pub fn add_diags(&self, diags: Diagnostics) { + for diag in diags.into_vec() { + self.add_diag(diag) + } + } + + pub fn extend_ide_info(&self, info: IDEInfo) { + if self.flags.ide_test_mode() { + for entry in info.annotations.iter() { + let diag = entry.clone().into(); + self.add_diag(diag); + } + } + self.ide_information.write().unwrap().extend(info); + } + + pub fn add_ide_annotation(&self, loc: Loc, info: IDEAnnotation) { + if self.flags.ide_test_mode() { + let diag = (loc, info.clone()).into(); + self.add_diag(diag); + } + self.ide_information + .write() + .unwrap() + .add_ide_annotation(loc, info); + } +} + impl Diagnostics { pub fn new() -> Self { Self { @@ -777,9 +859,9 @@ macro_rules! ice { #[macro_export] macro_rules! ice_assert { - ($env: expr, $cond: expr, $loc: expr, $($arg:tt)*) => {{ + ($reporter: expr, $cond: expr, $loc: expr, $($arg:tt)*) => {{ if !$cond { - $env.add_diag($crate::ice!(( + $reporter.add_diag($crate::ice!(( $loc, format!($($arg)*), ))); @@ -800,182 +882,6 @@ pub fn print_stack_trace() { } } -impl WarningFilters { - pub fn new_for_source() -> Self { - Self { - filters: BTreeMap::new(), - for_dependency: false, - } - } - - pub fn new_for_dependency() -> Self { - Self { - filters: BTreeMap::new(), - for_dependency: true, - } - } - - pub fn is_filtered(&self, diag: &Diagnostic) -> bool { - self.is_filtered_by_info(&diag.info) - } - - fn is_filtered_by_info(&self, info: &DiagnosticInfo) -> bool { - let prefix = info.external_prefix(); - self.filters - .get(&prefix) - .is_some_and(|filters| filters.is_filtered_by_info(info)) - } - - pub fn union(&mut self, other: &Self) { - for (prefix, filters) in &other.filters { - self.filters - .entry(*prefix) - .or_insert_with(UnprefixedWarningFilters::new) - .union(filters); - } - // if there is a dependency code filter on the stack, it means we are filtering - // dependent code and this information must be preserved when stacking - // up additional filters (which involves union of the current filter - // with the new one) - self.for_dependency = self.for_dependency || other.for_dependency; - } - - pub fn add(&mut self, filter: WarningFilter) { - let (prefix, category, code, name) = match filter { - WarningFilter::All(prefix) => { - self.filters.insert(prefix, UnprefixedWarningFilters::All); - return; - } - WarningFilter::Category { - prefix, - category, - name, - } => (prefix, category, None, name), - WarningFilter::Code { - prefix, - category, - code, - name, - } => (prefix, category, Some(code), name), - }; - self.filters - .entry(prefix) - .or_insert(UnprefixedWarningFilters::Empty) - .add(category, code, name) - } - - pub fn unused_warnings_filter_for_test() -> Self { - Self { - filters: BTreeMap::from([( - None, - UnprefixedWarningFilters::unused_warnings_filter_for_test(), - )]), - for_dependency: false, - } - } - - pub fn for_dependency(&self) -> bool { - self.for_dependency - } -} - -impl UnprefixedWarningFilters { - pub fn new() -> Self { - Self::Empty - } - - fn is_filtered_by_info(&self, info: &DiagnosticInfo) -> bool { - match self { - Self::All => info.severity() <= Severity::Warning, - Self::Specified { categories, codes } => { - info.severity() <= Severity::Warning - && (categories.contains_key(&info.category()) - || codes.contains_key(&(info.category(), info.code()))) - } - Self::Empty => false, - } - } - - pub fn union(&mut self, other: &Self) { - match (self, other) { - // if self is empty, just take the other filter - (s @ Self::Empty, _) => *s = other.clone(), - // if other is empty, or self is ALL, no change to the filter - (_, Self::Empty) => (), - (Self::All, _) => (), - // if other is all, self is now all - (s, Self::All) => *s = Self::All, - // category and code level union - ( - Self::Specified { categories, codes }, - Self::Specified { - categories: other_categories, - codes: other_codes, - }, - ) => { - categories.extend(other_categories); - // remove any codes covered by the category level filter - codes.extend( - other_codes - .iter() - .filter(|((category, _), _)| !categories.contains_key(category)), - ); - } - } - } - - /// Add a specific filter to the filter map. - /// If filter_code is None, then the filter applies to all codes in the - /// filter_category. - fn add( - &mut self, - filter_category: u8, - filter_code: Option, - filter_name: Option, - ) { - match self { - Self::All => (), - Self::Empty => { - *self = Self::Specified { - categories: BTreeMap::new(), - codes: BTreeMap::new(), - }; - self.add(filter_category, filter_code, filter_name) - } - Self::Specified { categories, .. } if categories.contains_key(&filter_category) => (), - Self::Specified { categories, codes } => { - if let Some(filter_code) = filter_code { - codes.insert((filter_category, filter_code), filter_name); - } else { - categories.insert(filter_category, filter_name); - codes.retain(|(category, _), _| *category != filter_category); - } - } - } - } - - pub fn unused_warnings_filter_for_test() -> Self { - let filtered_codes = [ - (UnusedItem::Function, FILTER_UNUSED_FUNCTION), - (UnusedItem::StructField, FILTER_UNUSED_STRUCT_FIELD), - (UnusedItem::FunTypeParam, FILTER_UNUSED_TYPE_PARAMETER), - (UnusedItem::Constant, FILTER_UNUSED_CONST), - (UnusedItem::MutReference, FILTER_UNUSED_MUT_REF), - (UnusedItem::MutParam, FILTER_UNUSED_MUT_PARAM), - ] - .into_iter() - .map(|(item, filter)| { - let info = item.into_info(); - ((info.category(), info.code()), Some(filter)) - }) - .collect(); - Self::Specified { - categories: BTreeMap::new(), - codes: filtered_codes, - } - } -} - impl Migration { pub fn new( mapped_files: MappedFiles, @@ -1212,43 +1118,6 @@ impl From> for Diagnostics { } } -impl AstDebug for WarningFilters { - fn ast_debug(&self, w: &mut crate::shared::ast_debug::AstWriter) { - for (prefix, filters) in &self.filters { - let prefix_str = prefix.unwrap_or(known_attributes::DiagnosticAttribute::ALLOW); - match filters { - UnprefixedWarningFilters::All => w.write(&format!( - "#[{}({})]", - prefix_str, - WarningFilter::All(*prefix).to_str().unwrap(), - )), - UnprefixedWarningFilters::Specified { categories, codes } => { - w.write(&format!("#[{}(", prefix_str)); - let items = categories - .iter() - .map(|(cat, n)| WarningFilter::Category { - prefix: *prefix, - category: *cat, - name: *n, - }) - .chain(codes.iter().map(|((cat, code), n)| WarningFilter::Code { - prefix: *prefix, - category: *cat, - code: *code, - name: *n, - })); - w.list(items, ",", |w, filter| { - w.write(filter.to_str().unwrap()); - false - }); - w.write(")]") - } - UnprefixedWarningFilters::Empty => (), - } - } - } -} - impl From for DiagnosticInfo { fn from(value: C) -> Self { value.into_info() diff --git a/external-crates/move/crates/move-compiler/src/diagnostics/warning_filters.rs b/external-crates/move/crates/move-compiler/src/diagnostics/warning_filters.rs new file mode 100644 index 00000000000..79ca29879a1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/diagnostics/warning_filters.rs @@ -0,0 +1,561 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + diagnostics::{ + codes::{Category, DiagnosticInfo, ExternalPrefix, Severity, UnusedItem}, + Diagnostic, DiagnosticCode, + }, + shared::{known_attributes, AstDebug}, +}; +use move_symbol_pool::Symbol; +use std::{ + collections::{BTreeMap, BTreeSet, HashSet}, + hash::Hash, + sync::Arc, +}; + +pub const FILTER_ALL: &str = "all"; +pub const FILTER_UNUSED: &str = "unused"; +pub const FILTER_MISSING_PHANTOM: &str = "missing_phantom"; +pub const FILTER_UNUSED_USE: &str = "unused_use"; +pub const FILTER_UNUSED_VARIABLE: &str = "unused_variable"; +pub const FILTER_UNUSED_ASSIGNMENT: &str = "unused_assignment"; +pub const FILTER_UNUSED_TRAILING_SEMI: &str = "unused_trailing_semi"; +pub const FILTER_UNUSED_ATTRIBUTE: &str = "unused_attribute"; +pub const FILTER_UNUSED_TYPE_PARAMETER: &str = "unused_type_parameter"; +pub const FILTER_UNUSED_FUNCTION: &str = "unused_function"; +pub const FILTER_UNUSED_STRUCT_FIELD: &str = "unused_field"; +pub const FILTER_UNUSED_CONST: &str = "unused_const"; +pub const FILTER_DEAD_CODE: &str = "dead_code"; +pub const FILTER_UNUSED_LET_MUT: &str = "unused_let_mut"; +pub const FILTER_UNUSED_MUT_REF: &str = "unused_mut_ref"; +pub const FILTER_UNUSED_MUT_PARAM: &str = "unused_mut_parameter"; +pub const FILTER_IMPLICIT_CONST_COPY: &str = "implicit_const_copy"; +pub const FILTER_DUPLICATE_ALIAS: &str = "duplicate_alias"; +pub const FILTER_DEPRECATED: &str = "deprecated_usage"; +pub const FILTER_IDE_PATH_AUTOCOMPLETE: &str = "ide_path_autocomplete"; +pub const FILTER_IDE_DOT_AUTOCOMPLETE: &str = "ide_dot_autocomplete"; + +macro_rules! known_code_filter { + ($name:ident, $category:ident::$code:ident) => {{ + use crate::diagnostics::codes::*; + ( + move_symbol_pool::Symbol::from($name), + std::collections::BTreeSet::from([ + crate::diagnostics::warning_filters::WarningFilter::Code { + prefix: None, + category: Category::$category as u8, + code: $category::$code as u8, + name: Some($name), + }, + ]), + ) + }}; +} +pub(crate) use known_code_filter; + +//************************************************************************************************** +// Types +//************************************************************************************************** + +/// None for the default 'allow'. +/// Some(prefix) for a custom set of warnings, e.g. 'allow(lint(_))'. +pub type FilterPrefix = Option; +pub type FilterName = Symbol; + +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct WarningFiltersScope(WarningFiltersScope_); + +#[derive(PartialEq, Eq, Clone, Debug)] +enum WarningFiltersScope_ { + /// Unsafe and should be used only for internal purposes, such as ide annotations + Empty, + /// The top-level warning filters given to the compiler instance. They are leaked as they will + /// be needed for the lifetime of the compiler instance. + Static(&'static WarningFiltersBuilder), + /// A user-defined warning filter scope, with a reference to the previous scope + Node(Arc), +} + +#[derive(PartialEq, Eq, Clone, Debug)] +struct WarningFiltersScopeNode { + /// The warning filters for this scope + filters: WarningFilters, + /// The previous scope + prev: WarningFiltersScope_, +} + +#[derive(Debug, Clone)] +/// An intern table for warning filters. The underlying `Box` is not moved, so the pointer to the +/// filter is stable. +/// Safety: This table should not be dropped as long as any `WarningFilters` are alive +pub struct WarningFiltersTable(HashSet>); + +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +/// An unsafe pointer into the intern table for warning filters. +/// Safety: The `WarningFiltersTable` must be held as long as any `WarningFilters`s are alive. +pub struct WarningFilters(*const WarningFiltersBuilder); +unsafe impl Send for WarningFilters {} +unsafe impl Sync for WarningFilters {} + +#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)] +/// Used to filter out diagnostics, specifically used for warning suppression +pub struct WarningFiltersBuilder { + filters: BTreeMap, + for_dependency: bool, // if false, the filters are used for source code +} + +#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)] +/// Filters split by category and code +enum UnprefixedWarningFilters { + /// Remove all warnings + All, + Specified { + /// Remove all diags of this category with optional known name + categories: BTreeMap>, + /// Remove specific diags with optional known filter name + codes: BTreeMap<(u8, u8), Option>, + }, + /// No filter + Empty, +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug, PartialOrd, Ord)] +/// Represents a single annotation for a diagnostic filter +pub enum WarningFilter { + /// Filters all warnings + All(ExternalPrefix), + /// Filters all warnings of a specific category. Only known filters have names. + Category { + prefix: ExternalPrefix, + category: u8, + name: Option, + }, + /// Filters a single warning, as defined by codes below. Only known filters have names. + Code { + prefix: ExternalPrefix, + category: u8, + code: u8, + name: Option, + }, +} + +/// The name for a well-known filter. +pub type WellKnownFilterName = &'static str; + +//************************************************************************************************** +// impls +//************************************************************************************************** + +impl WarningFiltersScope { + /// Create a new scope with the given top-level warning filter, if any. + /// A `&'static WarningFiltersBuilder` is used to avoid cloning the filter table for each + /// new top-level scope needed + pub(crate) const fn root( + top_level_warning_filter_opt: Option<&'static WarningFiltersBuilder>, + ) -> Self { + match top_level_warning_filter_opt { + None => WarningFiltersScope(WarningFiltersScope_::Empty), + Some(top_level_warning_filter) => { + WarningFiltersScope(WarningFiltersScope_::Static(top_level_warning_filter)) + } + } + } + + pub fn push(&mut self, filters: WarningFilters) { + let node = Arc::new(WarningFiltersScopeNode { + filters, + prev: self.0.clone(), + }); + *self = WarningFiltersScope(WarningFiltersScope_::Node(node)) + } + + pub fn pop(&mut self) { + match std::mem::replace(&mut self.0, WarningFiltersScope_::Empty) { + WarningFiltersScope_::Empty => panic!("pop on empty scope"), + WarningFiltersScope_::Static(_) => panic!("pop on top level scope"), + WarningFiltersScope_::Node(node) => self.0 = node.prev.clone(), + } + } + + pub fn is_filtered(&self, diag: &Diagnostic) -> bool { + let mut scope = &self.0; + loop { + match scope { + WarningFiltersScope_::Empty => return false, + WarningFiltersScope_::Static(filters) => return filters.is_filtered(diag), + WarningFiltersScope_::Node(node) => { + if node.filters.is_filtered(diag) { + return true; + } + scope = &node.prev; + } + } + } + } + + pub fn is_filtered_for_dependency(&self) -> bool { + let mut scope = &self.0; + loop { + match scope { + WarningFiltersScope_::Empty => return false, + WarningFiltersScope_::Static(filters) => return filters.for_dependency(), + WarningFiltersScope_::Node(node) => { + if node.filters.for_dependency() { + return true; + } + scope = &node.prev; + } + } + } + } +} + +impl WarningFiltersTable { + pub fn new() -> Self { + Self(HashSet::new()) + } + + pub fn add(&mut self, filters: WarningFiltersBuilder) -> WarningFilters { + let boxed = Box::new(filters); + let wf = { + let pinned_ref: &WarningFiltersBuilder = &boxed; + WarningFilters(pinned_ref as *const WarningFiltersBuilder) + }; + match self.0.get(&boxed) { + Some(existing) => { + let existing_ref: &WarningFiltersBuilder = existing; + WarningFilters(existing_ref as *const WarningFiltersBuilder) + } + None => { + self.0.insert(boxed); + wf + } + } + } +} + +impl WarningFilters { + pub fn is_filtered(&self, diag: &Diagnostic) -> bool { + self.borrow().is_filtered(diag) + } + + pub fn for_dependency(&self) -> bool { + self.borrow().for_dependency() + } + + fn borrow(&self) -> &WarningFiltersBuilder { + unsafe { &*self.0 } + } +} + +impl WarningFiltersBuilder { + pub const fn new_for_source() -> Self { + Self { + filters: BTreeMap::new(), + for_dependency: false, + } + } + + pub const fn new_for_dependency() -> Self { + Self { + filters: BTreeMap::new(), + for_dependency: true, + } + } + + pub fn is_filtered(&self, diag: &Diagnostic) -> bool { + self.is_filtered_by_info(&diag.info) + } + + fn is_filtered_by_info(&self, info: &DiagnosticInfo) -> bool { + let prefix = info.external_prefix(); + self.filters + .get(&prefix) + .is_some_and(|filters| filters.is_filtered_by_info(info)) + } + + pub fn union(&mut self, other: &Self) { + for (prefix, filters) in &other.filters { + self.filters + .entry(*prefix) + .or_insert_with(UnprefixedWarningFilters::new) + .union(filters); + } + // if there is a dependency code filter on the stack, it means we are filtering dependent + // code and this information must be preserved when stacking up additional filters (which + // involves union of the current filter with the new one) + self.for_dependency = self.for_dependency || other.for_dependency; + } + + pub fn add(&mut self, filter: WarningFilter) { + let (prefix, category, code, name) = match filter { + WarningFilter::All(prefix) => { + self.filters.insert(prefix, UnprefixedWarningFilters::All); + return; + } + WarningFilter::Category { + prefix, + category, + name, + } => (prefix, category, None, name), + WarningFilter::Code { + prefix, + category, + code, + name, + } => (prefix, category, Some(code), name), + }; + self.filters + .entry(prefix) + .or_insert(UnprefixedWarningFilters::Empty) + .add(category, code, name) + } + + pub fn unused_warnings_filter_for_test() -> Self { + Self { + filters: BTreeMap::from([( + None, + UnprefixedWarningFilters::unused_warnings_filter_for_test(), + )]), + for_dependency: false, + } + } + + pub fn for_dependency(&self) -> bool { + self.for_dependency + } +} + +impl UnprefixedWarningFilters { + pub fn new() -> Self { + Self::Empty + } + + fn is_filtered_by_info(&self, info: &DiagnosticInfo) -> bool { + match self { + Self::All => info.severity() <= Severity::Warning, + Self::Specified { categories, codes } => { + info.severity() <= Severity::Warning + && (categories.contains_key(&info.category()) + || codes.contains_key(&(info.category(), info.code()))) + } + Self::Empty => false, + } + } + + pub fn union(&mut self, other: &Self) { + match (self, other) { + // if self is empty, just take the other filter + (s @ Self::Empty, _) => *s = other.clone(), + // if other is empty, or self is ALL, no change to the filter + (_, Self::Empty) => (), + (Self::All, _) => (), + // if other is all, self is now all + (s, Self::All) => *s = Self::All, + // category and code level union + ( + Self::Specified { categories, codes }, + Self::Specified { + categories: other_categories, + codes: other_codes, + }, + ) => { + categories.extend(other_categories); + // remove any codes covered by the category level filter + codes.extend( + other_codes + .iter() + .filter(|((category, _), _)| !categories.contains_key(category)), + ); + } + } + } + + /// Add a specific filter to the filter map. + /// If filter_code is None, then the filter applies to all codes in the filter_category. + fn add( + &mut self, + filter_category: u8, + filter_code: Option, + filter_name: Option, + ) { + match self { + Self::All => (), + Self::Empty => { + *self = Self::Specified { + categories: BTreeMap::new(), + codes: BTreeMap::new(), + }; + self.add(filter_category, filter_code, filter_name) + } + Self::Specified { categories, .. } if categories.contains_key(&filter_category) => (), + Self::Specified { categories, codes } => { + if let Some(filter_code) = filter_code { + codes.insert((filter_category, filter_code), filter_name); + } else { + categories.insert(filter_category, filter_name); + codes.retain(|(category, _), _| *category != filter_category); + } + } + } + } + + pub fn unused_warnings_filter_for_test() -> Self { + let filtered_codes = [ + (UnusedItem::Function, FILTER_UNUSED_FUNCTION), + (UnusedItem::StructField, FILTER_UNUSED_STRUCT_FIELD), + (UnusedItem::FunTypeParam, FILTER_UNUSED_TYPE_PARAMETER), + (UnusedItem::Constant, FILTER_UNUSED_CONST), + (UnusedItem::MutReference, FILTER_UNUSED_MUT_REF), + (UnusedItem::MutParam, FILTER_UNUSED_MUT_PARAM), + ] + .into_iter() + .map(|(item, filter)| { + let info = item.into_info(); + ((info.category(), info.code()), Some(filter)) + }) + .collect(); + Self::Specified { + categories: BTreeMap::new(), + codes: filtered_codes, + } + } +} + +impl WarningFilter { + pub fn to_str(self) -> Option<&'static str> { + match self { + Self::All(_) => Some(FILTER_ALL), + Self::Category { name, .. } | Self::Code { name, .. } => name, + } + } + + pub fn code( + prefix: ExternalPrefix, + category: u8, + code: u8, + name: Option, + ) -> Self { + Self::Code { + prefix, + category, + code, + name, + } + } + + pub fn category( + prefix: ExternalPrefix, + category: u8, + name: Option, + ) -> Self { + Self::Category { + prefix, + category, + name, + } + } + + pub fn compiler_known_filters() -> BTreeMap> { + BTreeMap::from([ + ( + FILTER_ALL.into(), + BTreeSet::from([WarningFilter::All(None)]), + ), + ( + FILTER_UNUSED.into(), + BTreeSet::from([WarningFilter::Category { + prefix: None, + category: Category::UnusedItem as u8, + name: Some(FILTER_UNUSED), + }]), + ), + known_code_filter!(FILTER_MISSING_PHANTOM, Declarations::InvalidNonPhantomUse), + known_code_filter!(FILTER_UNUSED_USE, UnusedItem::Alias), + known_code_filter!(FILTER_UNUSED_VARIABLE, UnusedItem::Variable), + known_code_filter!(FILTER_UNUSED_ASSIGNMENT, UnusedItem::Assignment), + known_code_filter!(FILTER_UNUSED_TRAILING_SEMI, UnusedItem::TrailingSemi), + known_code_filter!(FILTER_UNUSED_ATTRIBUTE, UnusedItem::Attribute), + known_code_filter!(FILTER_UNUSED_FUNCTION, UnusedItem::Function), + known_code_filter!(FILTER_UNUSED_STRUCT_FIELD, UnusedItem::StructField), + ( + FILTER_UNUSED_TYPE_PARAMETER.into(), + BTreeSet::from([ + WarningFilter::Code { + prefix: None, + category: Category::UnusedItem as u8, + code: UnusedItem::StructTypeParam as u8, + name: Some(FILTER_UNUSED_TYPE_PARAMETER), + }, + WarningFilter::Code { + prefix: None, + category: Category::UnusedItem as u8, + code: UnusedItem::FunTypeParam as u8, + name: Some(FILTER_UNUSED_TYPE_PARAMETER), + }, + ]), + ), + known_code_filter!(FILTER_UNUSED_CONST, UnusedItem::Constant), + known_code_filter!(FILTER_DEAD_CODE, UnusedItem::DeadCode), + known_code_filter!(FILTER_UNUSED_LET_MUT, UnusedItem::MutModifier), + known_code_filter!(FILTER_UNUSED_MUT_REF, UnusedItem::MutReference), + known_code_filter!(FILTER_UNUSED_MUT_PARAM, UnusedItem::MutParam), + known_code_filter!(FILTER_IMPLICIT_CONST_COPY, TypeSafety::ImplicitConstantCopy), + known_code_filter!(FILTER_DUPLICATE_ALIAS, Declarations::DuplicateAlias), + known_code_filter!(FILTER_DEPRECATED, TypeSafety::DeprecatedUsage), + ]) + } + + pub fn ide_known_filters() -> BTreeMap> { + BTreeMap::from([ + known_code_filter!(FILTER_IDE_PATH_AUTOCOMPLETE, IDE::PathAutocomplete), + known_code_filter!(FILTER_IDE_DOT_AUTOCOMPLETE, IDE::DotAutocomplete), + ]) + } +} + +impl AstDebug for WarningFilters { + fn ast_debug(&self, w: &mut crate::shared::ast_debug::AstWriter) { + self.borrow().ast_debug(w); + } +} + +impl AstDebug for WarningFiltersBuilder { + fn ast_debug(&self, w: &mut crate::shared::ast_debug::AstWriter) { + for (prefix, filters) in &self.filters { + let prefix_str = prefix.unwrap_or(known_attributes::DiagnosticAttribute::ALLOW); + match filters { + UnprefixedWarningFilters::All => w.write(format!( + "#[{}({})]", + prefix_str, + WarningFilter::All(*prefix).to_str().unwrap(), + )), + UnprefixedWarningFilters::Specified { categories, codes } => { + w.write(format!("#[{}(", prefix_str)); + let items = categories + .iter() + .map(|(cat, n)| WarningFilter::Category { + prefix: *prefix, + category: *cat, + name: *n, + }) + .chain(codes.iter().map(|((cat, code), n)| WarningFilter::Code { + prefix: *prefix, + category: *cat, + code: *code, + name: *n, + })); + w.list(items, ",", |w, filter| { + w.write(filter.to_str().unwrap()); + false + }); + w.write(")]") + } + UnprefixedWarningFilters::Empty => (), + } + } + } +} diff --git a/external-crates/move/crates/move-compiler/src/editions/mod.rs b/external-crates/move/crates/move-compiler/src/editions/mod.rs index 95055b630a8..1ac4bbac64a 100644 --- a/external-crates/move/crates/move-compiler/src/editions/mod.rs +++ b/external-crates/move/crates/move-compiler/src/editions/mod.rs @@ -18,8 +18,8 @@ use serde::{Deserialize, Serialize}; use crate::{ diag, - diagnostics::Diagnostic, - shared::{string_utils::format_oxford_list, CompilationEnv}, + diagnostics::{Diagnostic, DiagnosticReporter}, + shared::string_utils::format_oxford_list, }; //************************************************************************************************** @@ -74,13 +74,13 @@ pub const UPGRADE_NOTE: &str = "You can update the edition in the 'Move.toml', o /// Returns true if the feature is present in the given edition. /// Adds an error to the environment. pub fn check_feature_or_error( - env: &mut CompilationEnv, + reporter: &DiagnosticReporter, edition: Edition, feature: FeatureGate, loc: Loc, ) -> bool { if !edition.supports(feature) { - env.add_diag(create_feature_error(edition, feature, loc)); + reporter.add_diag(create_feature_error(edition, feature, loc)); false } else { true @@ -98,11 +98,19 @@ pub fn feature_edition_error_msg(edition: Edition, feature: FeatureGate) -> Opti feature.error_prefix() ) } else { - format!( - "{} not supported by current edition '{edition}', \ - only {} support this feature", - feature.error_prefix(), - format_oxford_list!("and", "'{}'", valid_editions) + valid_editions.last().map_or( + format!( + "{} not supported by any current edition '{edition}', \ + the feature is still in development", + feature.error_prefix() + ), + |supporting_edition| { + format!( + "{} not supported by current edition '{edition}'; \ + the '{supporting_edition}' edition supports this feature", + feature.error_prefix(), + ) + }, ) }; Some(message) @@ -138,7 +146,13 @@ static SUPPORTED_FEATURES: Lazy>> = const E2024_ALPHA_FEATURES: &[FeatureGate] = &[]; -const E2024_BETA_FEATURES: &[FeatureGate] = &[ +const E2024_BETA_FEATURES: &[FeatureGate] = &[]; + +const DEVELOPMENT_FEATURES: &[FeatureGate] = &[]; + +const E2024_MIGRATION_FEATURES: &[FeatureGate] = &[FeatureGate::Move2024Migration]; + +const E2024_FEATURES: &[FeatureGate] = &[ FeatureGate::NestedUse, FeatureGate::PublicPackage, FeatureGate::PostFixAbilities, @@ -161,10 +175,6 @@ const E2024_BETA_FEATURES: &[FeatureGate] = &[ FeatureGate::Enums, ]; -const DEVELOPMENT_FEATURES: &[FeatureGate] = &[]; - -const E2024_MIGRATION_FEATURES: &[FeatureGate] = &[FeatureGate::Move2024Migration]; - impl Edition { pub const LEGACY: Self = Self { edition: symbol!("legacy"), @@ -186,6 +196,10 @@ impl Edition { edition: symbol!("development"), release: None, }; + pub const E2024: Self = Self { + edition: symbol!("2024"), + release: None, + }; const SEP: &'static str = "."; @@ -195,8 +209,16 @@ impl Edition { Self::E2024_BETA, Self::E2024_MIGRATION, Self::DEVELOPMENT, + Self::E2024, + ]; + // NB: This is the list of editions that are considered "valid" for the purposes of the Move. + // This list should be kept in order from oldest edition to newest. + pub const VALID: &'static [Self] = &[ + Self::LEGACY, + Self::E2024_ALPHA, + Self::E2024_BETA, + Self::E2024, ]; - pub const VALID: &'static [Self] = &[Self::LEGACY, Self::E2024_ALPHA, Self::E2024_BETA]; pub fn supports(&self, feature: FeatureGate) -> bool { SUPPORTED_FEATURES.get(self).unwrap().contains(&feature) @@ -207,8 +229,9 @@ impl Edition { match *self { Self::LEGACY => None, Self::E2024_ALPHA => Some(Self::E2024_BETA), - Self::E2024_BETA => Some(Self::LEGACY), - Self::E2024_MIGRATION => Some(Self::E2024_BETA), + Self::E2024_BETA => Some(Self::E2024), + Self::E2024 => Some(Self::LEGACY), + Self::E2024_MIGRATION => Some(Self::E2024), Self::DEVELOPMENT => Some(Self::E2024_ALPHA), _ => self.unknown_edition_panic(), } @@ -229,6 +252,11 @@ impl Edition { features.extend(E2024_BETA_FEATURES); features } + Self::E2024 => { + let mut features = self.prev().unwrap().features(); + features.extend(E2024_FEATURES); + features + } Self::E2024_MIGRATION => { let mut features = self.prev().unwrap().features(); features.extend(E2024_MIGRATION_FEATURES); @@ -399,6 +427,6 @@ impl Serialize for Flavor { impl Default for Edition { fn default() -> Self { - Edition::E2024_BETA + Edition::E2024 } } diff --git a/external-crates/move/crates/move-compiler/src/expansion/alias_map_builder.rs b/external-crates/move/crates/move-compiler/src/expansion/alias_map_builder.rs index 7216834251b..2bc240b3efc 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/alias_map_builder.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/alias_map_builder.rs @@ -9,7 +9,7 @@ use move_ir_types::location::*; use crate::{ expansion::{ ast::{self as E, ModuleIdent}, - translate::ModuleMemberKind, + name_validation::ModuleMemberKind, }, parser::ast::{self as P}, shared::{unique_map::UniqueMap, *}, @@ -245,8 +245,8 @@ impl AliasMapBuilder { result } - // TODO: the functions below should take a flag indicating if they are from a `use` or local - // definition for better error reporting. + // TODO: the functions below should take a flag indicating if they are from a + // `use` or local definition for better error reporting. /// Adds a module alias to the map. /// Errors if one already bound for that alias diff --git a/external-crates/move/crates/move-compiler/src/expansion/ast.rs b/external-crates/move/crates/move-compiler/src/expansion/ast.rs index 8035559e67f..d8bd14c26dc 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/ast.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/ast.rs @@ -3,17 +3,17 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::{collections::VecDeque, fmt, hash::Hash}; +use std::{collections::VecDeque, fmt, hash::Hash, sync::Arc}; use move_ir_types::location::*; use move_symbol_pool::Symbol; use crate::{ - diagnostics::WarningFilters, + diagnostics::warning_filters::{WarningFilters, WarningFiltersTable}, parser::ast::{ - self as P, Ability, Ability_, BinOp, BlockLabel, ConstantName, DatatypeName, Field, - FunctionName, ModuleName, QuantKind, UnaryOp, Var, VariantName, ENTRY_MODIFIER, - MACRO_MODIFIER, NATIVE_MODIFIER, + self as P, Ability, Ability_, BinOp, BlockLabel, ConstantName, DatatypeName, + ENTRY_MODIFIER, Field, FunctionName, MACRO_MODIFIER, ModuleName, NATIVE_MODIFIER, + QuantKind, UnaryOp, Var, VariantName, }, shared::{ ast_debug::*, known_attributes::KnownAttribute, unique_map::UniqueMap, @@ -27,6 +27,9 @@ use crate::{ #[derive(Debug, Clone)] pub struct Program { + /// Safety: This table should not be dropped as long as any `WarningFilters` + /// are alive + pub warning_filters_table: Arc, // Map of declared named addresses, and their values if specified pub modules: UniqueMap, } @@ -340,7 +343,7 @@ pub type LambdaLValues = Spanned; #[allow(clippy::large_enum_variant)] pub enum ExpDotted_ { Exp(Box), - Dot(Box, Name), + Dot(Box, /* dot location */ Loc, Name), Index(Box, Spanned>), DotUnresolved(Loc, Box), // dot where Name could not be parsed } @@ -394,6 +397,7 @@ pub enum Exp_ { ), MethodCall( Box, + Loc, // location of the dot Name, // is_macro Option, @@ -403,7 +407,7 @@ pub enum Exp_ { Pack(ModuleAccess, Option>, Fields), Vector(Loc, Option>, Spanned>), - IfElse(Box, Box, Box), + IfElse(Box, Box, Option>), Match(Box, Spanned>), While(Option, Box, Box), Loop(Option, Box), @@ -420,7 +424,7 @@ pub enum Exp_ { Assign(LValueList, Box), FieldMutate(Box, Box), Mutate(Box, Box), - Abort(Box), + Abort(Option>), Return(Option, Box), Break(Option, Box), Continue(Option), @@ -661,12 +665,17 @@ impl Address { } } - pub fn is(&self, address: impl AsRef) -> bool { + pub fn is(&self, address: &Addr) -> bool + where + NumericalAddress: PartialEq, + { + self.numerical_value().is_some_and(|sp!(_, v)| v == address) + } + + pub fn numerical_value(&self) -> Option<&Spanned> { match self { - Self::Numerical { name: Some(n), .. } | Self::NamedUnassigned(n) => { - n.value.as_str() == address.as_ref() - } - Self::Numerical { name: None, .. } => false, + Self::Numerical { value, .. } => Some(value), + Self::NamedUnassigned(_) => None, } } } @@ -676,7 +685,10 @@ impl ModuleIdent_ { Self { address, module } } - pub fn is(&self, address: impl AsRef, module: impl AsRef) -> bool { + pub fn is(&self, address: &Addr, module: impl AsRef) -> bool + where + NumericalAddress: PartialEq, + { let Self { address: a, module: m, @@ -930,42 +942,12 @@ impl fmt::Display for ModuleAccess_ { impl fmt::Display for Visibility { fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { - write!( - f, - "{}", - match &self { - Visibility::Public(_) => Visibility::PUBLIC, - Visibility::Friend(_) => Visibility::FRIEND, - Visibility::Package(_) => Visibility::PACKAGE, - Visibility::Internal => Visibility::INTERNAL, - } - ) - } -} - -impl fmt::Display for Type_ { - fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { - use Type_::*; - match self { - UnresolvedError => write!(f, "_"), - Apply(n, tys) => { - write!(f, "{}", n)?; - if !tys.is_empty() { - write!(f, "<")?; - write!(f, "{}", format_comma(tys))?; - write!(f, ">")?; - } - Ok(()) - } - Ref(mut_, ty) => write!(f, "&{}{}", if *mut_ { "mut " } else { "" }, ty), - Fun(args, result) => write!(f, "({}):{}", format_comma(args), result), - Unit => write!(f, "()"), - Multiple(tys) => { - write!(f, "(")?; - write!(f, "{}", format_comma(tys))?; - write!(f, ")") - } - } + write!(f, "{}", match &self { + Visibility::Public(_) => Visibility::PUBLIC, + Visibility::Friend(_) => Visibility::FRIEND, + Visibility::Package(_) => Visibility::PACKAGE, + Visibility::Internal => Visibility::INTERNAL, + }) } } @@ -982,7 +964,17 @@ impl std::fmt::Display for Value_ { V::U128(u) => write!(f, "{}", u), V::U256(u) => write!(f, "{}", u), V::Bool(b) => write!(f, "{}", b), - V::Bytearray(v) => write!(f, "{:?}", v), // Good enough? + // TODO preserve the user's original string + V::Bytearray(v) => { + write!(f, "vector[")?; + for (idx, byte) in v.iter().enumerate() { + if idx != 0 { + write!(f, ", ")?; + } + write!(f, "{}", byte)?; + } + write!(f, "]") + } } } } @@ -993,9 +985,12 @@ impl std::fmt::Display for Value_ { impl AstDebug for Program { fn ast_debug(&self, w: &mut AstWriter) { - let Program { modules } = self; + let Program { + warning_filters_table: _, + modules, + } = self; for (m, mdef) in modules.key_cloned_iter() { - w.write(&format!("module {}", m)); + w.write(format!("module {}", m)); w.block(|w| mdef.ast_debug(w)); w.new_line(); } @@ -1021,7 +1016,7 @@ impl AstDebug for ExplicitUseFun { function.ast_debug(w); w.write(" as "); ty.ast_debug(w); - w.writeln(&format!(".{method};")); + w.writeln(format!(".{method};")); } } @@ -1064,9 +1059,9 @@ impl AstDebug for AttributeValue_ { fn ast_debug(&self, w: &mut AstWriter) { match self { AttributeValue_::Value(v) => v.ast_debug(w), - AttributeValue_::Module(m) => w.write(&format!("{m}")), + AttributeValue_::Module(m) => w.write(format!("{m}")), AttributeValue_::ModuleAccess(n) => n.ast_debug(w), - AttributeValue_::Address(a) => w.write(&format!("{a}")), + AttributeValue_::Address(a) => w.write(format!("{a}")), } } } @@ -1074,14 +1069,14 @@ impl AstDebug for AttributeValue_ { impl AstDebug for Attribute_ { fn ast_debug(&self, w: &mut AstWriter) { match self { - Attribute_::Name(n) => w.write(&format!("{}", n)), + Attribute_::Name(n) => w.write(format!("{}", n)), Attribute_::Assigned(n, v) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write(" = "); v.ast_debug(w); } Attribute_::Parameterized(n, inners) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write("("); w.list(inners, ", ", |w, (_, _, inner)| { inner.ast_debug(w); @@ -1132,7 +1127,7 @@ impl AstDebug for ModuleDefinition { } = self; warning_filter.ast_debug(w); if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); w.writeln(match target_kind { @@ -1146,7 +1141,7 @@ impl AstDebug for ModuleDefinition { }); use_funs.ast_debug(w); for (mident, _loc) in friends.key_cloned_iter() { - w.write(&format!("friend {};", mident)); + w.write(format!("friend {};", mident)); w.new_line(); } for sdef in structs.key_cloned_iter() { @@ -1198,21 +1193,21 @@ impl AstDebug for (DatatypeName, &StructDefinition) { w.write("native "); } - w.write(&format!("struct#{index} {name}")); + w.write(format!("struct#{index} {name}")); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); match fields { StructFields::Named(fields) => w.block(|w| { w.list(fields, ",", |w, (_, f, idx_st)| { let (idx, st) = idx_st; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); st.ast_debug(w); true }); }), StructFields::Positional(fields) => w.block(|w| { w.list(fields.iter().enumerate(), ",", |w, (idx, ty)| { - w.write(&format!("{idx}#pos{idx}: ")); + w.write(format!("{idx}#pos{idx}: ")); ty.ast_debug(w); true }); @@ -1239,7 +1234,7 @@ impl AstDebug for (DatatypeName, &EnumDefinition) { warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("enum#{index} {name}")); + w.write(format!("enum#{index} {name}")); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); w.block(|w| { @@ -1261,19 +1256,19 @@ impl AstDebug for (VariantName, &VariantDefinition) { }, ) = self; - w.write(&format!("variant#{index} {name}")); + w.write(format!("variant#{index} {name}")); match fields { VariantFields::Named(fields) => w.block(|w| { w.list(fields, ",", |w, (_, f, idx_st)| { let (idx, st) = idx_st; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); st.ast_debug(w); true }); }), VariantFields::Positional(fields) => w.block(|w| { w.list(fields.iter().enumerate(), ",", |w, (idx, ty)| { - w.write(&format!("{idx}#pos{idx}: ")); + w.write(format!("{idx}#pos{idx}: ")); ty.ast_debug(w); true }); @@ -1303,15 +1298,15 @@ impl AstDebug for (FunctionName, &Function) { attributes.ast_debug(w); visibility.ast_debug(w); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if macro_.is_some() { - w.write(&format!("{} ", MACRO_MODIFIER)); + w.write(format!("{} ", MACRO_MODIFIER)); } if let FunctionBody_::Native = &body.value { - w.write(&format!("{} ", NATIVE_MODIFIER)); + w.write(format!("{} ", NATIVE_MODIFIER)); } - w.write(&format!("fun#{index} {name}")); + w.write(format!("fun#{index} {name}")); signature.ast_debug(w); match &body.value { FunctionBody_::Defined(body) => body.ast_debug(w), @@ -1322,7 +1317,7 @@ impl AstDebug for (FunctionName, &Function) { impl AstDebug for Visibility { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{} ", self)) + w.write(format!("{} ", self)) } } @@ -1337,7 +1332,7 @@ impl AstDebug for FunctionSignature { w.write("("); w.comma(parameters, |w, (mutability, v, st)| { mutability.ast_debug(w); - w.write(&format!("{}: ", v)); + w.write(format!("{}: ", v)); st.ast_debug(w); }); w.write("): "); @@ -1360,7 +1355,7 @@ impl AstDebug for (ConstantName, &Constant) { ) = self; warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("const#{index} {}:", name)); + w.write(format!("const#{index} {}:", name)); signature.ast_debug(w); w.write(" = "); value.ast_debug(w); @@ -1504,16 +1499,16 @@ impl AstDebug for Value_ { fn ast_debug(&self, w: &mut AstWriter) { use Value_ as V; match self { - V::Address(addr) => w.write(&format!("@{}", addr)), - V::InferredNum(u) => w.write(&format!("{}", u)), - V::U8(u) => w.write(&format!("{}u8", u)), - V::U16(u) => w.write(&format!("{}u16", u)), - V::U32(u) => w.write(&format!("{}u32", u)), - V::U64(u) => w.write(&format!("{}u64", u)), - V::U128(u) => w.write(&format!("{}u128", u)), - V::U256(u) => w.write(&format!("{}u256", u)), - V::Bool(b) => w.write(&format!("{}", b)), - V::Bytearray(v) => w.write(&format!("{:?}", v)), + V::Address(addr) => w.write(format!("@{}", addr)), + V::InferredNum(u) => w.write(format!("{}", u)), + V::U8(u) => w.write(format!("{}u8", u)), + V::U16(u) => w.write(format!("{}u16", u)), + V::U32(u) => w.write(format!("{}u32", u)), + V::U64(u) => w.write(format!("{}u64", u)), + V::U128(u) => w.write(format!("{}u128", u)), + V::U256(u) => w.write(format!("{}u256", u)), + V::Bool(b) => w.write(format!("{}", b)), + V::Bytearray(v) => w.write(format!("{:?}", v)), } } } @@ -1549,9 +1544,9 @@ impl AstDebug for Exp_ { w.comma(rhs, |w, e| e.ast_debug(w)); w.write(")"); } - E::MethodCall(e, f, is_macro, tys_opt, sp!(_, rhs)) => { + E::MethodCall(e, _, f, is_macro, tys_opt, sp!(_, rhs)) => { e.ast_debug(w); - w.write(&format!(".{}", f)); + w.write(format!(".{}", f)); if is_macro.is_some() { w.write("!"); } @@ -1574,7 +1569,7 @@ impl AstDebug for Exp_ { w.write("{"); w.comma(fields, |w, (_, f, idx_e)| { let (idx, e) = idx_e; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); e.ast_debug(w); }); w.write("}"); @@ -1590,13 +1585,15 @@ impl AstDebug for Exp_ { w.comma(elems, |w, e| e.ast_debug(w)); w.write("]"); } - E::IfElse(b, t, f) => { + E::IfElse(b, t, f_opt) => { w.write("if ("); b.ast_debug(w); w.write(") "); t.ast_debug(w); - w.write(" else "); - f.ast_debug(w); + if let Some(f) = f_opt { + w.write(" else "); + f.ast_debug(w); + } } E::Match(subject, arms) => { w.write("match ("); @@ -1669,8 +1666,11 @@ impl AstDebug for Exp_ { } E::Abort(e) => { - w.write("abort "); - e.ast_debug(w); + w.write("abort"); + if let Some(e) = e { + w.write(" "); + e.ast_debug(w); + } } E::Return(name, e) => { w.write("return "); @@ -1744,9 +1744,9 @@ impl AstDebug for ExpDotted_ { use ExpDotted_ as D; match self { D::Exp(e) => e.ast_debug(w), - D::Dot(e, n) => { + D::Dot(e, _, n) => { e.ast_debug(w); - w.write(&format!(".{}", n)) + w.write(format!(".{}", n)) } D::Index(e, rhs) => { e.ast_debug(w); @@ -1872,7 +1872,7 @@ impl AstDebug for LValue_ { if let Some(mutability) = mutability { mutability.ast_debug(w); } - w.write(&format!("{}", v)); + w.write(format!("{}", v)); if let Some(ss) = tys_opt { w.write("<"); ss.ast_debug(w); @@ -1944,7 +1944,7 @@ impl AstDebug for FieldBindings { w.write("{"); w.comma(fields, |w, (_, f, idx_b)| { let (idx, b) = idx_b; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); b.ast_debug(w); }); if ellipsis.is_some() { @@ -1955,7 +1955,7 @@ impl AstDebug for FieldBindings { FieldBindings::Positional(vals) => { w.write("("); w.comma(vals.iter().enumerate(), |w, (idx, lval)| { - w.write(&format!("{idx}: ")); + w.write(format!("{idx}: ")); lval.ast_debug(w); }); w.write(")"); diff --git a/external-crates/move/crates/move-compiler/src/expansion/mod.rs b/external-crates/move/crates/move-compiler/src/expansion/mod.rs index e041f43acbb..18ea0b7d1a3 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/mod.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/mod.rs @@ -9,6 +9,7 @@ pub mod ast; mod byte_string; mod hex_string; mod legacy_aliases; +pub mod name_validation; mod path_expander; mod primitive_definers; pub(crate) mod translate; diff --git a/external-crates/move/crates/move-compiler/src/expansion/name_validation.rs b/external-crates/move/crates/move-compiler/src/expansion/name_validation.rs new file mode 100644 index 00000000000..363e7140d37 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/expansion/name_validation.rs @@ -0,0 +1,426 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use std::collections::BTreeSet; + +use move_ir_types::location::*; +use move_symbol_pool::Symbol; + +use crate::{ + diag, + diagnostics::{Diagnostic, DiagnosticReporter}, + parser::ast::{self as P, MACRO_MODIFIER, ModuleName, Var}, + shared::*, +}; + +// Implicit aliases for the Move Stdlib: +// use std::vector; +// use std::option::{Self, Option}; +pub const IMPLICIT_STD_MODULES: &[Symbol] = &[symbol!("option"), symbol!("vector")]; +pub const IMPLICIT_STD_MEMBERS: &[(Symbol, Symbol, ModuleMemberKind)] = &[( + symbol!("option"), + symbol!("Option"), + ModuleMemberKind::Struct, +)]; + +// Implicit aliases for Iota mode: +// use iota::object::{Self, ID, UID}; +// use iota::transfer; +// use iota::tx_context::{Self, TxContext}; +pub const IMPLICIT_IOTA_MODULES: &[Symbol] = &[ + symbol!("object"), + symbol!("transfer"), + symbol!("tx_context"), +]; +pub const IMPLICIT_IOTA_MEMBERS: &[(Symbol, Symbol, ModuleMemberKind)] = &[ + (symbol!("object"), symbol!("ID"), ModuleMemberKind::Struct), + (symbol!("object"), symbol!("UID"), ModuleMemberKind::Struct), + ( + symbol!("tx_context"), + symbol!("TxContext"), + ModuleMemberKind::Struct, + ), +]; + +#[derive(Copy, Clone, Debug)] +pub enum ModuleMemberKind { + Constant, + Function, + Struct, + Enum, +} + +#[derive(Copy, Clone, Debug)] +pub enum NameCase { + Constant, + Function, + Struct, + Enum, + Module, + ModuleMemberAlias(ModuleMemberKind), + ModuleAlias, + Variable, + Address, + TypeParameter, +} + +//************************************************************************************************** +// impls +//************************************************************************************************** + +impl ModuleMemberKind { + pub fn case(self) -> NameCase { + match self { + ModuleMemberKind::Constant => NameCase::Constant, + ModuleMemberKind::Function => NameCase::Function, + ModuleMemberKind::Struct => NameCase::Struct, + ModuleMemberKind::Enum => NameCase::Enum, + } + } +} + +impl NameCase { + pub const fn name(&self) -> &'static str { + match self { + NameCase::Constant => "constant", + NameCase::Function => "function", + NameCase::Struct => "struct", + NameCase::Enum => "enum", + NameCase::Module => "module", + NameCase::ModuleMemberAlias(ModuleMemberKind::Function) => "function alias", + NameCase::ModuleMemberAlias(ModuleMemberKind::Constant) => "constant alias", + NameCase::ModuleMemberAlias(ModuleMemberKind::Struct) => "struct alias", + NameCase::ModuleMemberAlias(ModuleMemberKind::Enum) => "enum alias", + NameCase::ModuleAlias => "module alias", + NameCase::Variable => "variable", + NameCase::Address => "address", + NameCase::TypeParameter => "type parameter", + } + } +} + +//************************************************************************************************** +// Valid names +//************************************************************************************************** + +#[allow(clippy::result_unit_err)] +pub fn check_valid_address_name( + reporter: &DiagnosticReporter, + sp!(_, ln_): &P::LeadingNameAccess, +) -> Result<(), ()> { + use P::LeadingNameAccess_ as LN; + match ln_ { + LN::AnonymousAddress(_) => Ok(()), + LN::GlobalAddress(n) | LN::Name(n) => { + check_restricted_name_all_cases(reporter, NameCase::Address, n) + } + } +} + +pub fn valid_local_variable_name(s: Symbol) -> bool { + s.starts_with('_') || s.starts_with(|c: char| c.is_ascii_lowercase()) +} + +#[allow(clippy::result_unit_err)] +pub fn check_valid_function_parameter_name( + reporter: &DiagnosticReporter, + is_macro: Option, + v: &Var, +) { + const SYNTAX_IDENTIFIER_NOTE: &str = "'macro' parameters start with '$' to indicate that their arguments are not evaluated \ + before the macro is expanded, meaning the entire expression is substituted. \ + This is different from regular function parameters that are evaluated before the \ + function is called."; + let is_syntax_identifier = v.is_syntax_identifier(); + if let Some(macro_loc) = is_macro { + if !is_syntax_identifier && !v.is_underscore() { + let msg = format!( + "Invalid parameter name '{}'. '{}' parameter names must start with '$' (or must be '_')", + v, MACRO_MODIFIER, + ); + let macro_msg = format!("Declared '{}' here", MACRO_MODIFIER); + let mut diag = diag!( + Declarations::InvalidName, + (v.loc(), msg), + (macro_loc, macro_msg), + ); + diag.add_note(SYNTAX_IDENTIFIER_NOTE); + reporter.add_diag(diag); + } + } else if is_syntax_identifier { + let msg = format!( + "Invalid parameter name '{}'. Non-'{}' parameter names cannot start with '$'", + v, MACRO_MODIFIER, + ); + let mut diag = diag!(Declarations::InvalidName, (v.loc(), msg)); + diag.add_note(SYNTAX_IDENTIFIER_NOTE); + reporter.add_diag(diag); + } else if !is_valid_local_variable_name(v.value()) { + let msg = format!( + "Invalid parameter name '{}'. Local variable names must start with 'a'..'z', '_', \ + or be a valid name quoted with backticks (`name`)", + v, + ); + reporter.add_diag(diag!(Declarations::InvalidName, (v.loc(), msg))); + } + let _ = check_restricted_name_all_cases(reporter, NameCase::Variable, &v.0); +} + +pub fn check_valid_local_name(reporter: &DiagnosticReporter, v: &Var) { + if !is_valid_local_variable_name(v.value()) { + let msg = format!( + "Invalid local name '{}'. Local variable names must start with 'a'..'z', '_', \ + or be a valid name quoted with backticks (`name`)", + v, + ); + reporter.add_diag(diag!(Declarations::InvalidName, (v.loc(), msg))); + } + let _ = check_restricted_name_all_cases(reporter, NameCase::Variable, &v.0); +} + +fn is_valid_local_variable_name(s: Symbol) -> bool { + Var::is_valid_name(s) && !Var::is_syntax_identifier_name(s) +} + +pub fn check_valid_module_member_name( + reporter: &DiagnosticReporter, + member: ModuleMemberKind, + name: Name, +) -> Option { + match check_valid_module_member_name_impl(reporter, member, &name, member.case()) { + Err(()) => None, + Ok(()) => Some(name), + } +} + +pub fn check_valid_module_member_alias( + reporter: &DiagnosticReporter, + member: ModuleMemberKind, + alias: Name, +) -> Option { + match check_valid_module_member_name_impl( + reporter, + member, + &alias, + NameCase::ModuleMemberAlias(member), + ) { + Err(()) => None, + Ok(()) => Some(alias), + } +} + +fn check_valid_module_member_name_impl( + reporter: &DiagnosticReporter, + member: ModuleMemberKind, + n: &Name, + case: NameCase, +) -> Result<(), ()> { + use ModuleMemberKind as M; + fn upper_first_letter(s: &str) -> String { + let mut chars = s.chars(); + match chars.next() { + None => String::new(), + Some(c) => c.to_uppercase().collect::() + chars.as_str(), + } + } + match member { + M::Function => { + if n.value.starts_with('_') { + let msg = format!( + "Invalid {} name '{}'. {} names cannot start with '_'", + case.name(), + n, + upper_first_letter(case.name()), + ); + reporter.add_diag(diag!(Declarations::InvalidName, (n.loc, msg))); + return Err(()); + } + } + M::Constant | M::Struct | M::Enum => { + if !is_valid_datatype_or_constant_name(&n.value) { + let msg = format!( + "Invalid {} name '{}'. {} names must start with 'A'..'Z'", + case.name(), + n, + upper_first_letter(case.name()), + ); + reporter.add_diag(diag!(Declarations::InvalidName, (n.loc, msg))); + return Err(()); + } + } + } + + // TODO move these names to a more central place? + check_restricted_names( + reporter, + case, + n, + crate::naming::ast::BuiltinFunction_::all_names(), + )?; + check_restricted_names( + reporter, + case, + n, + crate::naming::ast::BuiltinTypeName_::all_names(), + )?; + + // Restricting Self for now in the case where we ever have impls + // Otherwise, we could allow it + check_restricted_name_all_cases(reporter, case, n)?; + + Ok(()) +} + +#[allow(clippy::result_unit_err)] +pub fn check_valid_type_parameter_name( + reporter: &DiagnosticReporter, + is_macro: Option, + n: &Name, +) -> Result<(), ()> { + // TODO move these names to a more central place? + if n.value == symbol!("_") { + let diag = restricted_name_error(NameCase::TypeParameter, n.loc, "_"); + reporter.add_diag(diag); + return Err(()); + } + + const SYNTAX_IDENTIFIER_NOTE: &str = "Type parameter names starting with '$' indicate that \ + their arguments do not have to satisfy certain constraints before the macro is expanded, \ + meaning types like '&mut u64' or '(bool, u8)' may be used as arguments."; + + let is_syntax_ident = Var::is_syntax_identifier_name(n.value); + if let Some(macro_loc) = is_macro { + if !is_syntax_ident { + let msg = format!( + "Invalid type parameter name. \ + '{} fun' type parameter names must start with '$'", + MACRO_MODIFIER + ); + let macro_msg = format!("Declared '{}' here", MACRO_MODIFIER); + let mut diag = diag!( + Declarations::InvalidName, + (n.loc, msg), + (macro_loc, macro_msg), + ); + diag.add_note(SYNTAX_IDENTIFIER_NOTE); + reporter.add_diag(diag); + } else { + let next_char = n.value.chars().nth(1).unwrap(); + if !next_char.is_ascii_alphabetic() { + let msg = format!( + "Invalid type parameter name '{}'. \ + Following the '$', the '{} fun' type parameter must be have a valid type \ + parameter name starting with a letter 'a'..'z' or 'A'..'Z'", + n, MACRO_MODIFIER + ); + let mut diag = diag!(Declarations::InvalidName, (n.loc, msg)); + diag.add_note(SYNTAX_IDENTIFIER_NOTE); + reporter.add_diag(diag); + } + } + } else if is_syntax_ident { + let msg = format!( + "Invalid type parameter name. \ + Only '{} fun' type parameter names cat start with '$'", + MACRO_MODIFIER + ); + let mut diag = diag!(Declarations::InvalidName, (n.loc, msg)); + diag.add_note(SYNTAX_IDENTIFIER_NOTE); + reporter.add_diag(diag); + } + + // TODO move these names to a more central place? + check_restricted_names( + reporter, + NameCase::TypeParameter, + n, + crate::naming::ast::BuiltinFunction_::all_names(), + )?; + check_restricted_names( + reporter, + NameCase::TypeParameter, + n, + crate::naming::ast::BuiltinTypeName_::all_names(), + )?; + + check_restricted_name_all_cases(reporter, NameCase::TypeParameter, n) +} + +pub fn is_valid_datatype_or_constant_name(s: &str) -> bool { + s.starts_with(|c: char| c.is_ascii_uppercase()) +} + +#[allow(clippy::result_unit_err)] +// Checks for a restricted name in any decl case +// Self and vector are not allowed +pub fn check_restricted_name_all_cases( + reporter: &DiagnosticReporter, + case: NameCase, + n: &Name, +) -> Result<(), ()> { + match case { + NameCase::Constant + | NameCase::Function + | NameCase::Struct + | NameCase::Enum + | NameCase::Module + | NameCase::ModuleMemberAlias(_) + | NameCase::ModuleAlias + | NameCase::Address => { + if Var::is_syntax_identifier_name(n.value) { + let msg = format!( + "Invalid {} name '{}'. Identifiers starting with '$' can be used only for \ + parameters and type parameters", + case.name(), + n, + ); + reporter.add_diag(diag!(Declarations::InvalidName, (n.loc, msg))); + return Err(()); + } + } + NameCase::Variable | NameCase::TypeParameter => (), + } + + let n_str = n.value.as_str(); + let can_be_vector = matches!(case, NameCase::Module | NameCase::ModuleAlias); + if n_str == ModuleName::SELF_NAME + || (!can_be_vector && n_str == crate::naming::ast::BuiltinTypeName_::VECTOR) + { + reporter.add_diag(restricted_name_error(case, n.loc, n_str)); + Err(()) + } else { + Ok(()) + } +} + +fn check_restricted_names( + reporter: &DiagnosticReporter, + case: NameCase, + sp!(loc, n_): &Name, + all_names: &BTreeSet, +) -> Result<(), ()> { + if all_names.contains(n_) { + reporter.add_diag(restricted_name_error(case, *loc, n_)); + Err(()) + } else { + Ok(()) + } +} + +fn restricted_name_error(case: NameCase, loc: Loc, restricted: &str) -> Diagnostic { + let a_or_an = match case.name().chars().next().unwrap() { + // TODO this is not exhaustive to the indefinite article rules in English + // but 'case' is never user generated, so it should be okay for a while/forever... + 'a' | 'e' | 'i' | 'o' | 'u' => "an", + _ => "a", + }; + let msg = format!( + "Invalid {case} name '{restricted}'. '{restricted}' is restricted and cannot be used to \ + name {a_or_an} {case}", + a_or_an = a_or_an, + case = case.name(), + restricted = restricted, + ); + diag!(NameResolution::ReservedName, (loc, msg)) +} diff --git a/external-crates/move/crates/move-compiler/src/expansion/path_expander.rs b/external-crates/move/crates/move-compiler/src/expansion/path_expander.rs index 435732ef5a1..02b77e286b8 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/path_expander.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/path_expander.rs @@ -13,9 +13,10 @@ use crate::{ aliases::{AliasMap, AliasSet}, ast::{self as E, Address, ModuleIdent, ModuleIdent_}, legacy_aliases, + name_validation::is_valid_datatype_or_constant_name, translate::{ - is_valid_datatype_or_constant_name, make_address, module_ident, top_level_address, - top_level_address_opt, value, DefnContext, + make_address, module_ident, top_level_address, top_level_address_opt, value, + DefnContext, }, }, ice, ice_assert, @@ -247,7 +248,7 @@ impl Move2024PathExpander { NR::Address(name.loc, make_address(context, name, name.loc, address)) } Some(AliasEntry::TypeParam(_)) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( name.loc, "ICE alias map misresolved name as type param" ))); @@ -270,7 +271,7 @@ impl Move2024PathExpander { NR::ModuleAccess(name.loc, mident, mem) } AliasEntry::TypeParam(_) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( name.loc, "ICE alias map misresolved name as type param" ))); @@ -318,7 +319,7 @@ impl Move2024PathExpander { .join(","); diag.add_note(format!("Type arguments are used with the enum, as '{mident}::{name}<{tys}>::{variant}'")) } - context.env.add_diag(diag); + context.add_diag(diag); } } } @@ -326,7 +327,7 @@ impl Move2024PathExpander { fn check_is_macro(context: &mut DefnContext, is_macro: &Option, result: &NR) { if let NR::Address(_, _) | NR::ModuleIdent(_, _) = result { if let Some(loc) = is_macro { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::InvalidTypeParameter, ( *loc, @@ -385,7 +386,7 @@ impl Move2024PathExpander { && root.tyargs.is_none() => { if let Some(address) = top_level_address_opt(context, root.name) { - context.env.add_diag(diag!( + context.add_diag(diag!( Migration::NeedsGlobalQualification, (root.name.loc, "Must globally qualify name") )); @@ -467,9 +468,7 @@ impl Move2024PathExpander { is_macro = entry.is_macro; } NR::UnresolvedName(_, _) => { - context - .env - .add_diag(ice!((loc, "ICE access chain expansion failed"))); + context.add_diag(ice!((loc, "ICE access chain expansion failed"))); break; } NR::ResolutionFailure(_, _) => break, @@ -523,13 +522,13 @@ impl PathExpander for Move2024PathExpander { // an error if they both resolve (to different things) PV::ModuleAccess(access_chain) => { ice_assert!( - context.env, + context.reporter, access_chain.value.tyargs().is_none(), loc, "Found tyargs" ); ice_assert!( - context.env, + context.reporter, access_chain.value.is_macro().is_none(), loc, "Found macro" @@ -553,7 +552,6 @@ impl PathExpander for Move2024PathExpander { m_res.err_name() ); context - .env .add_diag(diag!(Attributes::AmbiguousAttributeValue, (loc, msg))); return None; } @@ -561,7 +559,7 @@ impl PathExpander for Move2024PathExpander { match result { NR::ModuleIdent(_, mident) => { if context.module_members.get(&mident).is_none() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModule, (loc, format!("Unbound module '{}'", mident)) )); @@ -581,11 +579,11 @@ impl PathExpander for Move2024PathExpander { } NR::Address(_, a) => EV::Address(a), result @ NR::ResolutionFailure(_, _) => { - context.env.add_diag(access_chain_resolution_error(result)); + context.add_diag(access_chain_resolution_error(result)); return None; } NR::IncompleteChain(loc) => { - context.env.add_diag(access_chain_incomplete_error(loc)); + context.add_diag(access_chain_incomplete_error(loc)); return None; } } @@ -628,7 +626,7 @@ impl PathExpander for Move2024PathExpander { access, ); diag.add_note("Variants may not be used as types. Use the enum instead."); - context.env.add_diag(diag); + context.add_diag(diag); // We could try to use the member access to try to keep going. return None; } @@ -637,7 +635,7 @@ impl PathExpander for Move2024PathExpander { (access, tyargs, is_macro) } NR::Address(_, _) => { - context.env.add_diag(unexpected_access_error( + context.add_diag(unexpected_access_error( resolved_name.loc(), resolved_name.name(), access, @@ -658,15 +656,15 @@ impl PathExpander for Move2024PathExpander { base_str, realized_str )); } - context.env.add_diag(diag); + context.add_diag(diag); return None; } result @ NR::ResolutionFailure(_, _) => { - context.env.add_diag(access_chain_resolution_error(result)); + context.add_diag(access_chain_resolution_error(result)); return None; } NR::IncompleteChain(loc) => { - context.env.add_diag(access_chain_incomplete_error(loc)); + context.add_diag(access_chain_incomplete_error(loc)); return None; } } @@ -675,6 +673,7 @@ impl PathExpander for Move2024PathExpander { PN::Single(path_entry!(name, tyargs, is_macro)) if !is_valid_datatype_or_constant_name(&name.to_string()) => { + self.ide_autocomplete_suggestion(context, loc); (EN::Name(name), tyargs, is_macro) } _ => { @@ -691,7 +690,7 @@ impl PathExpander for Move2024PathExpander { (access, tyargs, is_macro) } NR::Address(_, _) | NR::ModuleIdent(_, _) => { - context.env.add_diag(unexpected_access_error( + context.add_diag(unexpected_access_error( resolved_name.loc(), resolved_name.name(), access, @@ -699,18 +698,18 @@ impl PathExpander for Move2024PathExpander { return None; } result @ NR::ResolutionFailure(_, _) => { - context.env.add_diag(access_chain_resolution_error(result)); + context.add_diag(access_chain_resolution_error(result)); return None; } NR::IncompleteChain(loc) => { - context.env.add_diag(access_chain_incomplete_error(loc)); + context.add_diag(access_chain_incomplete_error(loc)); return None; } } } }, Access::Module => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "ICE module access should never resolve to a module member" ))); @@ -733,11 +732,11 @@ impl PathExpander for Move2024PathExpander { match resolved_name { NR::ModuleIdent(_, mident) => Some(mident), NR::UnresolvedName(_, name) => { - context.env.add_diag(unbound_module_error(name)); + context.add_diag(unbound_module_error(name)); None } NR::Address(_, _) => { - context.env.add_diag(unexpected_access_error( + context.add_diag(unexpected_access_error( resolved_name.loc(), "address".to_string(), Access::Module, @@ -745,7 +744,7 @@ impl PathExpander for Move2024PathExpander { None } NR::ModuleAccess(_, _, _) | NR::Variant(_, _, _) => { - context.env.add_diag(unexpected_access_error( + context.add_diag(unexpected_access_error( resolved_name.loc(), "module member".to_string(), Access::Module, @@ -753,11 +752,11 @@ impl PathExpander for Move2024PathExpander { None } result @ NR::ResolutionFailure(_, _) => { - context.env.add_diag(access_chain_resolution_error(result)); + context.add_diag(access_chain_resolution_error(result)); None } NR::IncompleteChain(loc) => { - context.env.add_diag(access_chain_incomplete_error(loc)); + context.add_diag(access_chain_incomplete_error(loc)); None } } @@ -766,9 +765,7 @@ impl PathExpander for Move2024PathExpander { fn ide_autocomplete_suggestion(&mut self, context: &mut DefnContext, loc: Loc) { if context.env.ide_mode() { let info = self.aliases.get_ide_alias_information(); - context - .env - .add_ide_annotation(loc, IDEAnnotation::PathAutocompleteInfo(Box::new(info))); + context.add_ide_annotation(loc, IDEAnnotation::PathAutocompleteInfo(Box::new(info))); } } } @@ -928,12 +925,12 @@ impl PathExpander for LegacyPathExpander { if self.aliases.module_alias_get(&name).is_some() => { self.ide_autocomplete_suggestion(context, loc); - ice_assert!(context.env, tyargs.is_none(), loc, "Found tyargs"); - ice_assert!(context.env, is_macro.is_none(), loc, "Found macro"); + ice_assert!(context.reporter, tyargs.is_none(), loc, "Found tyargs"); + ice_assert!(context.reporter, is_macro.is_none(), loc, "Found macro"); let sp!(_, mident_) = self.aliases.module_alias_get(&name).unwrap(); let mident = sp(ident_loc, mident_); if context.module_members.get(&mident).is_none() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModule, (ident_loc, format!("Unbound module '{}'", mident)) )); @@ -941,14 +938,19 @@ impl PathExpander for LegacyPathExpander { EV::Module(mident) } PV::ModuleAccess(sp!(ident_loc, PN::Path(path))) => { - ice_assert!(context.env, !path.has_tyargs(), loc, "Found tyargs"); - ice_assert!(context.env, path.is_macro().is_none(), loc, "Found macro"); + ice_assert!(context.reporter, !path.has_tyargs(), loc, "Found tyargs"); + ice_assert!( + context.reporter, + path.is_macro().is_none(), + loc, + "Found macro" + ); match (&path.root.name, &path.entries[..]) { (sp!(aloc, LN::AnonymousAddress(a)), [n]) => { let addr = Address::anonymous(*aloc, *a); let mident = sp(ident_loc, ModuleIdent_::new(addr, ModuleName(n.name))); if context.module_members.get(&mident).is_none() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModule, (ident_loc, format!("Unbound module '{}'", mident)) )); @@ -970,7 +972,7 @@ impl PathExpander for LegacyPathExpander { let mident = sp(ident_loc, ModuleIdent_::new(addr, ModuleName(n2.name))); if context.module_members.get(&mident).is_none() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModule, (ident_loc, format!("Unbound module '{}'", mident)) )); @@ -1006,7 +1008,7 @@ impl PathExpander for LegacyPathExpander { let tn_: ModuleAccessResult = match (access, ptn_) { (Access::Pattern, _) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Attempted to expand a variant with the legacy path expander" ))); @@ -1017,7 +1019,7 @@ impl PathExpander for LegacyPathExpander { single_entry!(name, tyargs, is_macro), ) => { if access == Access::Type { - ice_assert!(context.env, is_macro.is_none(), loc, "Found macro"); + ice_assert!(context.reporter, is_macro.is_none(), loc, "Found macro"); } self.ide_autocomplete_suggestion(context, loc); let access = match self.aliases.member_alias_get(&name) { @@ -1037,10 +1039,11 @@ impl PathExpander for LegacyPathExpander { make_access_result(sp(name.loc, access), tyargs, is_macro) } (Access::Term, single_entry!(name, tyargs, is_macro)) => { + self.ide_autocomplete_suggestion(context, loc); make_access_result(sp(name.loc, EN::Name(name)), tyargs, is_macro) } (Access::Module, single_entry!(_name, _tyargs, _is_macro)) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "ICE path resolution produced an impossible path for a module" ))); @@ -1048,13 +1051,18 @@ impl PathExpander for LegacyPathExpander { } (_, PN::Path(mut path)) => { if access == Access::Type { - ice_assert!(context.env, path.is_macro().is_none(), loc, "Found macro"); + ice_assert!( + context.reporter, + path.is_macro().is_none(), + loc, + "Found macro" + ); } match (&path.root.name, &path.entries[..]) { // Error cases (sp!(aloc, LN::AnonymousAddress(_)), [_]) => { let diag = unexpected_address_module_error(loc, *aloc, access); - context.env.add_diag(diag); + context.add_diag(diag); return None; } (sp!(_aloc, LN::GlobalAddress(_)), [_]) => { @@ -1067,7 +1075,7 @@ impl PathExpander for LegacyPathExpander { loc, "Paths that start with `::` are not valid in legacy move.", )); - context.env.add_diag(diag); + context.add_diag(diag); return None; } // Others @@ -1075,7 +1083,7 @@ impl PathExpander for LegacyPathExpander { self.ide_autocomplete_suggestion(context, n1.loc); if let Some(mident) = self.aliases.module_alias_get(n1) { let n2_name = n2.name; - let (tyargs, is_macro) = if !(path.has_tyargs_last()) { + let (tyargs, is_macro) = if !path.has_tyargs_last() { let mut diag = diag!( Syntax::InvalidName, (path.tyargs_loc().unwrap(), "Invalid type argument position") @@ -1083,7 +1091,7 @@ impl PathExpander for LegacyPathExpander { diag.add_note( "Type arguments may only be used with module members", ); - context.env.add_diag(diag); + context.add_diag(diag); (None, path.is_macro()) } else { (path.take_tyargs(), path.is_macro()) @@ -1094,7 +1102,7 @@ impl PathExpander for LegacyPathExpander { is_macro.copied(), ) } else { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModule, (n1.loc, format!("Unbound module alias '{}'", n1)) )); @@ -1118,7 +1126,7 @@ impl PathExpander for LegacyPathExpander { (path.tyargs_loc().unwrap(), "Invalid type argument position") ); diag.add_note("Type arguments may only be used with module members"); - context.env.add_diag(diag); + context.add_diag(diag); (None, path.is_macro()) } else { (path.take_tyargs(), path.is_macro()) @@ -1127,14 +1135,14 @@ impl PathExpander for LegacyPathExpander { } (_ln, []) => { let diag = ice!((loc, "Found a root path with no additional entries")); - context.env.add_diag(diag); + context.add_diag(diag); return None; } (ln, [_n1, _n2, ..]) => { self.ide_autocomplete_suggestion(context, ln.loc); let mut diag = diag!(Syntax::InvalidName, (loc, "Too many name segments")); diag.add_note("Names may only have 0, 1, or 2 segments separated by '::'"); - context.env.add_diag(diag); + context.add_diag(diag); return None; } } @@ -1151,11 +1159,21 @@ impl PathExpander for LegacyPathExpander { use P::NameAccessChain_ as PN; match pn_ { PN::Single(single) => { - ice_assert!(context.env, single.tyargs.is_none(), loc, "Found tyargs"); - ice_assert!(context.env, single.is_macro.is_none(), loc, "Found macro"); + ice_assert!( + context.reporter, + single.tyargs.is_none(), + loc, + "Found tyargs" + ); + ice_assert!( + context.reporter, + single.is_macro.is_none(), + loc, + "Found macro" + ); match self.aliases.module_alias_get(&single.name) { None => { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModule, ( single.name.loc, @@ -1168,8 +1186,13 @@ impl PathExpander for LegacyPathExpander { } } PN::Path(path) => { - ice_assert!(context.env, !path.has_tyargs(), loc, "Found tyargs"); - ice_assert!(context.env, path.is_macro().is_none(), loc, "Found macro"); + ice_assert!(context.reporter, !path.has_tyargs(), loc, "Found tyargs"); + ice_assert!( + context.reporter, + path.is_macro().is_none(), + loc, + "Found macro" + ); match (&path.root.name, &path.entries[..]) { (ln, [n]) => { let pmident_ = P::ModuleIdent_ { @@ -1180,9 +1203,7 @@ impl PathExpander for LegacyPathExpander { } // Error cases (_ln, []) => { - context - .env - .add_diag(ice!((loc, "Found path with no path entries"))); + context.add_diag(ice!((loc, "Found path with no path entries"))); None } (ln, [n, m, ..]) => { @@ -1197,7 +1218,7 @@ impl PathExpander for LegacyPathExpander { module: ModuleName(n.name), }; let _ = module_ident(context, sp(ident_loc, pmident_)); - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::NamePositionMismatch, if path.entries.len() < 3 { (m.name.loc, "Unexpected module member access. Expected a module identifier only") @@ -1225,7 +1246,7 @@ impl PathExpander for LegacyPathExpander { info.members.insert((*name, *mident, *member)); } let annotation = IDEAnnotation::PathAutocompleteInfo(Box::new(info)); - context.env.add_ide_annotation(loc, annotation) + context.add_ide_annotation(loc, annotation) } } } diff --git a/external-crates/move/crates/move-compiler/src/expansion/primitive_definers.rs b/external-crates/move/crates/move-compiler/src/expansion/primitive_definers.rs index 299455a1f0e..a6e4538223c 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/primitive_definers.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/primitive_definers.rs @@ -4,30 +4,30 @@ use std::{collections::BTreeMap, sync::Arc}; -use super::ast::Attribute_; use crate::{ - diag, - expansion::ast::{ModuleDefinition, ModuleIdent}, + FullyCompiledProgram, diag, + diagnostics::DiagnosticReporter, + expansion::ast::{Attribute_, ModuleDefinition, ModuleIdent}, naming::ast::BuiltinTypeName_, shared::{ + CompilationEnv, known_attributes::{DefinesPrimitive, KnownAttribute}, unique_map::UniqueMap, - CompilationEnv, }, - FullyCompiledProgram, }; /// Gather primitive defines from module declarations, erroring on duplicates /// for a given base type or for unknown base types. pub fn modules( - env: &mut CompilationEnv, + env: &CompilationEnv, pre_compiled_lib_opt: Option>, modules: &UniqueMap, ) { + let reporter = env.diagnostic_reporter_at_top_level(); let mut definers = BTreeMap::new(); for (mident, m) in modules.key_cloned_iter() { check_prim_definer( - env, + &reporter, // allow shadowing false, &mut definers, @@ -38,7 +38,7 @@ pub fn modules( if let Some(pre_compiled_lib) = pre_compiled_lib_opt { for (mident, m) in pre_compiled_lib.expansion.modules.key_cloned_iter() { check_prim_definer( - env, + &reporter, // allow shadowing true, &mut definers, @@ -51,7 +51,7 @@ pub fn modules( } fn check_prim_definer( - env: &mut CompilationEnv, + reporter: &DiagnosticReporter, allow_shadowing: bool, definers: &mut BTreeMap, mident: ModuleIdent, @@ -68,7 +68,7 @@ fn check_prim_definer( "Expected a primitive type parameterization, e.g. '{}()'", DefinesPrimitive::DEFINES_PRIM ); - env.add_diag(diag!(Attributes::InvalidUsage, (*attr_loc, msg))); + reporter.add_diag(diag!(Attributes::InvalidUsage, (*attr_loc, msg))); return; }; if params.len() != 1 { @@ -76,7 +76,7 @@ fn check_prim_definer( "Expected a single primitive type parameterization, e.g. '{}()'", DefinesPrimitive::DEFINES_PRIM ); - env.add_diag(diag!(Attributes::InvalidUsage, (*attr_loc, msg))); + reporter.add_diag(diag!(Attributes::InvalidUsage, (*attr_loc, msg))); return; } let (_, _, sp!(param_loc, param_)) = params.into_iter().next().unwrap(); @@ -85,7 +85,7 @@ fn check_prim_definer( "Expected a primitive type parameterization, e.g. '{}()'", DefinesPrimitive::DEFINES_PRIM ); - env.add_diag(diag!(Attributes::InvalidUsage, (*param_loc, msg))); + reporter.add_diag(diag!(Attributes::InvalidUsage, (*param_loc, msg))); return; }; let Some(prim) = BuiltinTypeName_::resolve(name.value.as_str()) else { @@ -94,14 +94,14 @@ fn check_prim_definer( DefinesPrimitive::DEFINES_PRIM, name, ); - env.add_diag(diag!(Attributes::InvalidUsage, (name.loc, msg))); + reporter.add_diag(diag!(Attributes::InvalidUsage, (name.loc, msg))); return; }; if let Some(prev) = definers.get(&prim) { if !allow_shadowing { let msg = format!("Duplicate definer annotated for primitive type '{}'", prim); - env.add_diag(diag!( + reporter.add_diag(diag!( Attributes::InvalidUsage, (*attr_loc, msg), (prev.loc, "Previously declared here") diff --git a/external-crates/move/crates/move-compiler/src/expansion/translate.rs b/external-crates/move/crates/move-compiler/src/expansion/translate.rs index 52da52cbe4b..b44e096c2e4 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/translate.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/translate.rs @@ -6,18 +6,26 @@ use std::{ collections::{BTreeMap, BTreeSet, VecDeque}, iter::IntoIterator, - sync::Arc, + sync::{Arc, Mutex}, }; -use move_command_line_common::parser::{parse_u16, parse_u256, parse_u32}; -use move_core_types::account_address::AccountAddress; +use move_core_types::{ + account_address::AccountAddress, + parsing::parser::{parse_u16, parse_u32, parse_u256}, +}; use move_ir_types::location::*; use move_proc_macros::growing_stack; use move_symbol_pool::Symbol; use crate::{ - diag, - diagnostics::{codes::WarningFilter, Diagnostic, WarningFilters}, + FullyCompiledProgram, diag, + diagnostics::{ + Diagnostic, DiagnosticReporter, Diagnostics, + warning_filters::{ + FILTER_ALL, FILTER_UNUSED, WarningFilter, WarningFilters, WarningFiltersBuilder, + WarningFiltersTable, + }, + }, editions::{self, Edition, FeatureGate, Flavor}, expansion::{ alias_map_builder::{ @@ -26,25 +34,32 @@ use crate::{ aliases::AliasSet, ast::{self as E, Address, Fields, ModuleIdent, ModuleIdent_, TargetKind}, byte_string, hex_string, + name_validation::{ + IMPLICIT_IOTA_MEMBERS, IMPLICIT_IOTA_MODULES, IMPLICIT_STD_MEMBERS, + IMPLICIT_STD_MODULES, ModuleMemberKind, NameCase, check_restricted_name_all_cases, + check_valid_address_name, check_valid_function_parameter_name, check_valid_local_name, + check_valid_module_member_alias, check_valid_module_member_name, + check_valid_type_parameter_name, valid_local_variable_name, + }, path_expander::{ - access_result, Access, LegacyPathExpander, ModuleAccessResult, Move2024PathExpander, - PathExpander, + Access, LegacyPathExpander, ModuleAccessResult, Move2024PathExpander, PathExpander, + access_result, }, translate::known_attributes::{DiagnosticAttribute, KnownAttribute}, }, ice, ice_assert, parser::ast::{ - self as P, Ability, BlockLabel, ConstantName, DatatypeName, Field, FieldBindings, - FunctionName, ModuleName, NameAccess, Var, VariantName, ENTRY_MODIFIER, MACRO_MODIFIER, - NATIVE_MODIFIER, + self as P, Ability, BlockLabel, ConstantName, DatatypeName, ENTRY_MODIFIER, Field, + FieldBindings, FunctionName, MACRO_MODIFIER, ModuleName, NATIVE_MODIFIER, NameAccess, Var, + VariantName, }, shared::{ + ide::{IDEAnnotation, IDEInfo}, known_attributes::AttributePosition, string_utils::{is_pascal_case, is_upper_snake_case}, unique_map::UniqueMap, *, }, - FullyCompiledProgram, }; //************************************************************************************************** @@ -61,15 +76,17 @@ type ModuleMembers = BTreeMap; pub(super) struct DefnContext<'env, 'map> { pub(super) named_address_mapping: Option<&'map NamedAddressMap>, pub(super) module_members: UniqueMap, - pub(super) env: &'env mut CompilationEnv, + pub(super) env: &'env CompilationEnv, pub(super) address_conflicts: BTreeSet, pub(super) current_package: Option, pub(super) is_source_definition: bool, + pub(super) reporter: DiagnosticReporter<'env>, } struct Context<'env, 'map> { defn_context: DefnContext<'env, 'map>, address: Option

, + warning_filters_table: Mutex, // Cached warning filters for all available prefixes. Used by non-source defs // and dependency packages all_filter_alls: WarningFilters, @@ -78,16 +95,19 @@ struct Context<'env, 'map> { impl<'env, 'map> Context<'env, 'map> { fn new( - compilation_env: &'env mut CompilationEnv, + compilation_env: &'env CompilationEnv, module_members: UniqueMap, address_conflicts: BTreeSet, ) -> Self { - let mut all_filter_alls = WarningFilters::new_for_dependency(); + let mut warning_filters_table = WarningFiltersTable::new(); + let mut all_filter_alls = WarningFiltersBuilder::new_for_dependency(); for prefix in compilation_env.known_filter_names() { for f in compilation_env.filter_from_str(prefix, FILTER_ALL) { all_filter_alls.add(f); } } + let all_filter_alls = warning_filters_table.add(all_filter_alls); + let reporter = compilation_env.diagnostic_reporter_at_top_level(); let defn_context = DefnContext { env: compilation_env, named_address_mapping: None, @@ -95,19 +115,29 @@ impl<'env, 'map> Context<'env, 'map> { module_members, current_package: None, is_source_definition: false, + reporter, }; Context { defn_context, address: None, + warning_filters_table: Mutex::new(warning_filters_table), all_filter_alls, path_expander: None, } } - fn env(&mut self) -> &mut CompilationEnv { + fn finish(self) -> WarningFiltersTable { + self.warning_filters_table.into_inner().unwrap() + } + + fn env(&self) -> &CompilationEnv { self.defn_context.env } + fn reporter(&self) -> &DiagnosticReporter { + &self.defn_context.reporter + } + fn current_package(&mut self) -> Option { self.defn_context.current_package } @@ -137,7 +167,7 @@ impl<'env, 'map> Context<'env, 'map> { .unwrap() .push_alias_scope(loc, new_scope); match res { - Err(diag) => self.env().add_diag(*diag), + Err(diag) => self.add_diag(*diag), Ok(unnecessaries) => unnecessary_alias_errors(self, unnecessaries), } } @@ -240,7 +270,7 @@ impl<'env, 'map> Context<'env, 'map> { pub fn spec_deprecated(&mut self, loc: Loc, is_error: bool) { let diag = self.spec_deprecated_diag(loc, is_error); - self.env().add_diag(diag); + self.add_diag(diag); } pub fn spec_deprecated_diag(&mut self, loc: Loc, is_error: bool) -> Diagnostic { @@ -256,6 +286,64 @@ impl<'env, 'map> Context<'env, 'map> { ) ) } + + pub fn add_diag(&self, diag: Diagnostic) { + self.defn_context.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: Diagnostics) { + self.defn_context.add_diags(diags); + } + + #[allow(unused)] + pub fn extend_ide_info(&self, info: IDEInfo) { + self.defn_context.extend_ide_info(info); + } + + #[allow(unused)] + pub fn add_ide_annotation(&self, loc: Loc, info: IDEAnnotation) { + self.defn_context.add_ide_annotation(loc, info); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.defn_context.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.defn_context.pop_warning_filter_scope() + } + + pub fn check_feature(&self, package: Option, feature: FeatureGate, loc: Loc) -> bool { + self.env() + .check_feature(self.reporter(), package, feature, loc) + } +} + +impl DefnContext<'_, '_> { + pub(super) fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + pub(super) fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + pub(super) fn extend_ide_info(&self, info: IDEInfo) { + self.reporter.extend_ide_info(info); + } + + pub(super) fn add_ide_annotation(&self, loc: Loc, info: IDEAnnotation) { + self.reporter.add_ide_annotation(loc, info); + } + + pub(super) fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub(super) fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } } fn unnecessary_alias_errors(context: &mut Context, unnecessaries: Vec) { @@ -295,7 +383,7 @@ fn unnecessary_alias_error(context: &mut Context, unnecessary: UnnecessaryAlias) // nothing to point to for the default case diag.add_secondary_label((prev, "The same alias was previously declared here")) } - context.env().add_diag(diag); + context.add_diag(diag); } /// We mark named addresses as having a conflict if there is not a bidirectional @@ -332,35 +420,6 @@ fn compute_address_conflicts( .collect() } -// Implicit aliases for the Move Stdlib: -// use std::vector; -// use std::option::{Self, Option}; -const IMPLICIT_STD_MODULES: &[Symbol] = &[symbol!("option"), symbol!("vector")]; -const IMPLICIT_STD_MEMBERS: &[(Symbol, Symbol, ModuleMemberKind)] = &[( - symbol!("option"), - symbol!("Option"), - ModuleMemberKind::Struct, -)]; - -// Implicit aliases for Iota mode: -// use iota::object::{Self, ID, UID}; -// use iota::transfer; -// use iota::tx_context::{Self, TxContext}; -const IMPLICIT_IOTA_MODULES: &[Symbol] = &[ - symbol!("object"), - symbol!("transfer"), - symbol!("tx_context"), -]; -const IMPLICIT_IOTA_MEMBERS: &[(Symbol, Symbol, ModuleMemberKind)] = &[ - (symbol!("object"), symbol!("ID"), ModuleMemberKind::Struct), - (symbol!("object"), symbol!("UID"), ModuleMemberKind::Struct), - ( - symbol!("tx_context"), - symbol!("TxContext"), - ModuleMemberKind::Struct, - ), -]; - fn default_aliases(context: &mut Context) -> AliasMapBuilder { let current_package = context.current_package(); let mut builder = context.new_alias_map_builder(); @@ -432,12 +491,13 @@ fn default_aliases(context: &mut Context) -> AliasMapBuilder { //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: P::Program, ) -> E::Program { let address_conflicts = compute_address_conflicts(pre_compiled_lib.clone(), &prog); + let reporter = compilation_env.diagnostic_reporter_at_top_level(); let mut member_computation_context = DefnContext { env: compilation_env, named_address_mapping: None, @@ -445,6 +505,7 @@ pub fn program( address_conflicts, current_package: None, is_source_definition: false, + reporter, }; let module_members = { @@ -507,7 +568,7 @@ pub fn program( // should never fail if let Err(diag) = path_expander.push_alias_scope(Loc::invalid(), aliases) { - context.env().add_diag(*diag); + context.add_diag(*diag); } context.defn_context.named_address_mapping = Some(named_address_map); @@ -541,7 +602,7 @@ pub fn program( let aliases = named_addr_map_to_alias_map_builder(&mut context, named_address_map); // should never fail if let Err(diag) = path_expander.push_alias_scope(Loc::invalid(), aliases) { - context.env().add_diag(*diag); + context.add_diag(*diag); } context.defn_context.named_address_mapping = Some(named_address_map); context.path_expander = Some(Box::new(path_expander)); @@ -571,6 +632,7 @@ pub fn program( super::primitive_definers::modules(context.env(), pre_compiled_lib, &module_map); E::Program { + warning_filters_table: Arc::new(context.finish()), modules: module_map, } } @@ -634,7 +696,7 @@ fn top_level_address_( suggest_declaration: bool, ln: P::LeadingNameAccess, ) -> Address { - let name_res = check_valid_address_name(context, &ln); + let name_res = check_valid_address_name(&context.reporter, &ln); let sp!(loc, ln_) = ln; match ln_ { P::LeadingNameAccess_::AnonymousAddress(bytes) => { @@ -644,7 +706,7 @@ fn top_level_address_( // This should have been handled elsewhere in alias resolution for user-provided paths, and // should never occur in compiler-generated ones. P::LeadingNameAccess_::GlobalAddress(name) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Found an address in top-level address position that uses a global name" ))); @@ -655,7 +717,7 @@ fn top_level_address_( Some(addr) => make_address(context, name, loc, addr), None => { if name_res.is_ok() { - context.env.add_diag(address_without_value_error( + context.add_diag(address_without_value_error( suggest_declaration, loc, &name, @@ -672,7 +734,7 @@ pub(super) fn top_level_address_opt( context: &mut DefnContext, ln: P::LeadingNameAccess, ) -> Option
{ - let name_res = check_valid_address_name(context, &ln); + let name_res = check_valid_address_name(&context.reporter, &ln); let named_address_mapping = context.named_address_mapping.as_ref().unwrap(); let sp!(loc, ln_) = ln; match ln_ { @@ -683,7 +745,7 @@ pub(super) fn top_level_address_opt( // This should have been handled elsewhere in alias resolution for user-provided paths, and // should never occur in compiler-generated ones. P::LeadingNameAccess_::GlobalAddress(_) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Found an address in top-level address position that uses a global name" ))); @@ -764,7 +826,7 @@ fn check_module_address( } else { "Multiple addresses specified for module" }; - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (other_loc, msg), (loc, "Address previously specified here") @@ -784,7 +846,7 @@ fn duplicate_module( let old_mident = module_map.get_key(&mident).unwrap(); let dup_msg = format!("Duplicate definition for module '{}'", mident); let prev_msg = format!("Module previously defined here, with '{}'", old_mident); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (mident.loc, dup_msg), (old_loc, prev_msg), @@ -825,9 +887,7 @@ fn set_module_address( address 'module
::{}''", module_name ); - context - .env() - .add_diag(diag!(Declarations::InvalidModule, (loc, msg))); + context.add_diag(diag!(Declarations::InvalidModule, (loc, msg))); Address::anonymous(loc, NumericalAddress::DEFAULT_ERROR_ADDRESS) } }) @@ -849,25 +909,19 @@ fn module_( definition_mode: _, } = mdef; let attributes = flatten_attributes(context, AttributePosition::Module, attributes); - let mut warning_filter = module_warning_filter(context, &attributes); - let config = context.env().package_config(package_name); - warning_filter.union(&config.warning_filter); - - context - .env() - .add_warning_filter_scope(warning_filter.clone()); + let warning_filter = module_warning_filter(context, package_name, &attributes); + context.push_warning_filter_scope(warning_filter); assert!(context.address.is_none()); assert!(address.is_none()); set_module_address(context, &name, module_address); - let _ = check_restricted_name_all_cases(&mut context.defn_context, NameCase::Module, &name.0); - if name.value().starts_with(|c| c == '_') { + let _ = + check_restricted_name_all_cases(&context.defn_context.reporter, NameCase::Module, &name.0); + if name.value().starts_with('_') { let msg = format!( "Invalid module name '{}'. Module names cannot start with '_'", name, ); - context - .env() - .add_diag(diag!(Declarations::InvalidName, (name.loc(), msg))); + context.add_diag(diag!(Declarations::InvalidName, (name.loc(), msg))); } let name_loc = name.0.loc; @@ -940,7 +994,7 @@ fn module_( functions, warning_filter, }; - context.env().pop_warning_filter_scope(); + context.pop_warning_filter_scope(); (current_module, def) } @@ -970,15 +1024,13 @@ fn check_visibility_modifiers( let loc = friend_decl.loc; let diag = if edition == Edition::E2024_MIGRATION { for aloc in &friend_decl.attr_locs { - context - .env() - .add_diag(diag!(Migration::RemoveFriend, (*aloc, friend_msg))); + context.add_diag(diag!(Migration::RemoveFriend, (*aloc, friend_msg))); } diag!(Migration::RemoveFriend, (loc, friend_msg)) } else { diag!(Editions::DeprecatedFeature, (loc, friend_msg)) }; - context.env().add_diag(diag); + context.add_diag(diag); } for (_, _, function) in functions { let E::Visibility::Friend(loc) = function.visibility else { @@ -989,7 +1041,7 @@ fn check_visibility_modifiers( } else { diag!(Editions::DeprecatedFeature, (loc, pub_msg)) }; - context.env().add_diag(diag); + context.add_diag(diag); } } @@ -1002,9 +1054,7 @@ fn check_visibility_modifiers( friend_usage = Some(loc); } E::Visibility::Package(loc) => { - context - .env() - .check_feature(package_name, FeatureGate::PublicPackage, loc); + context.check_feature(package_name, FeatureGate::PublicPackage, loc); public_package_usage = Some(loc); } _ => (), @@ -1019,7 +1069,7 @@ fn check_visibility_modifiers( ); let package_definition_msg = format!("'{}' visibility used here", E::Visibility::PACKAGE); for (_, _, friend) in friends { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidVisibilityModifier, (friend.loc, friend_error_msg.clone()), ( @@ -1041,7 +1091,7 @@ fn check_visibility_modifiers( for (_, _, function) in functions { match function.visibility { E::Visibility::Friend(loc) => { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidVisibilityModifier, (loc, friend_error_msg.clone()), ( @@ -1051,7 +1101,7 @@ fn check_visibility_modifiers( )); } E::Visibility::Package(loc) => { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidVisibilityModifier, (loc, package_error_msg.clone()), ( @@ -1092,9 +1142,7 @@ fn known_attributes( e.g. #[{ext}({n})]", ext = known_attributes::ExternalAttribute::EXTERNAL ); - context - .env() - .add_diag(diag!(Declarations::UnknownAttribute, (loc, msg))); + context.add_diag(diag!(Declarations::UnknownAttribute, (loc, msg))); None } sp!(loc, E::AttributeName_::Known(n)) => { @@ -1117,9 +1165,7 @@ fn gate_known_attribute(context: &mut Context, loc: Loc, known: &KnownAttribute) | KnownAttribute::Deprecation(_) => (), KnownAttribute::Error(_) => { let pkg = context.current_package(); - context - .env() - .check_feature(pkg, FeatureGate::CleverAssertions, loc); + context.check_feature(pkg, FeatureGate::CleverAssertions, loc); } } } @@ -1145,9 +1191,7 @@ fn unique_attributes( let msg = format!( "Known attribute '{known}' is not expected in a nested attribute position" ); - context - .env() - .add_diag(diag!(Declarations::InvalidAttribute, (nloc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (nloc, msg))); continue; } @@ -1167,7 +1211,7 @@ fn unique_attributes( "Expected to be used with one of the following: {}", all_expected ); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidAttribute, (nloc, msg), (nloc, expected_msg) @@ -1185,7 +1229,7 @@ fn unique_attributes( } if let Err((_, old_loc)) = attr_map.add(sp(nloc, name_), sp(loc, attr_)) { let msg = format!("Duplicate attribute '{}' attached to the same item", name_); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (loc, msg), (old_loc, "Attribute previously given here"), @@ -1202,26 +1246,27 @@ fn attribute( ) -> Option { use E::Attribute_ as EA; use P::Attribute_ as PA; - Some(sp( - loc, - match attribute_ { - PA::Name(n) => EA::Name(n), - PA::Assigned(n, v) => EA::Assigned(n, Box::new(context.attribute_value(*v)?)), - PA::Parameterized(n, sp!(_, pattrs_)) => { - let attrs = pattrs_ - .into_iter() - .map(|a| attribute(context, attr_position, a)) - .collect::>>()?; - EA::Parameterized(n, unique_attributes(context, attr_position, true, attrs)) - } - }, - )) + Some(sp(loc, match attribute_ { + PA::Name(n) => EA::Name(n), + PA::Assigned(n, v) => EA::Assigned(n, Box::new(context.attribute_value(*v)?)), + PA::Parameterized(n, sp!(_, pattrs_)) => { + let attrs = pattrs_ + .into_iter() + .map(|a| attribute(context, attr_position, a)) + .collect::>>()?; + EA::Parameterized(n, unique_attributes(context, attr_position, true, attrs)) + } + })) } /// Like warning_filter, but it will filter _all_ warnings for non-source /// definitions (or for any dependency packages) -fn module_warning_filter(context: &mut Context, attributes: &E::Attributes) -> WarningFilters { - let filters = warning_filter(context, attributes); +fn module_warning_filter( + context: &mut Context, + package: Option, + attributes: &E::Attributes, +) -> WarningFilters { + let mut filters = warning_filter_(context, attributes); let is_dep = !context.defn_context.is_source_definition || { let pkg = context.current_package(); context.env().package_config(pkg).is_dependency @@ -1229,16 +1274,27 @@ fn module_warning_filter(context: &mut Context, attributes: &E::Attributes) -> W if is_dep { // For dependencies (non source defs or package deps), we check the filters for // errors but then throw them away and actually ignore _all_ warnings - context.all_filter_alls.clone() + context.all_filter_alls } else { - filters + let config = context.env().package_config(package); + filters.union(&config.warning_filter); + context + .warning_filters_table + .get_mut() + .unwrap() + .add(filters) } } +fn warning_filter(context: &mut Context, attributes: &E::Attributes) -> WarningFilters { + let wf = warning_filter_(context, attributes); + context.warning_filters_table.get_mut().unwrap().add(wf) +} + /// Finds the warning filters from the #[allow(_)] attribute and the deprecated /// #[lint_allow(_)] attribute. -fn warning_filter(context: &mut Context, attributes: &E::Attributes) -> WarningFilters { - let mut warning_filters = WarningFilters::new_for_source(); +fn warning_filter_(context: &Context, attributes: &E::Attributes) -> WarningFiltersBuilder { + let mut warning_filters = WarningFiltersBuilder::new_for_source(); let mut prefixed_filters: Vec<(DiagnosticAttribute, Option, Vec)> = vec![]; // Gather lint_allow warnings if let Some(lint_allow_attr) = attributes.get_(&DiagnosticAttribute::LintAllow.into()) { @@ -1269,9 +1325,7 @@ fn warning_filter(context: &mut Context, attributes: &E::Attributes) -> WarningF DiagnosticAttribute::ALLOW, n ); - context - .env() - .add_diag(diag!(Declarations::InvalidAttribute, (inner_attr_loc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (inner_attr_loc, msg))); (None, vec![*n]) } }; @@ -1296,9 +1350,7 @@ fn warning_filter(context: &mut Context, attributes: &E::Attributes) -> WarningF ) } }; - context - .env() - .add_diag(diag!(Attributes::ValueWarning, (nloc, msg))); + context.add_diag(diag!(Attributes::ValueWarning, (nloc, msg))); continue; }; for f in filters { @@ -1310,7 +1362,7 @@ fn warning_filter(context: &mut Context, attributes: &E::Attributes) -> WarningF } fn get_allow_attribute_inners<'a>( - context: &mut Context, + context: &Context, name: &'static str, allow_attr: &'a E::Attribute, ) -> Option<&'a E::InnerAttributes> { @@ -1329,16 +1381,14 @@ fn get_allow_attribute_inners<'a>( .to_str() .unwrap(), ); - context - .env() - .add_diag(diag!(Attributes::ValueWarning, (allow_attr.loc, msg))); + context.add_diag(diag!(Attributes::ValueWarning, (allow_attr.loc, msg))); None } } } fn prefixed_warning_filters( - context: &mut Context, + context: &Context, prefix: impl std::fmt::Display, inners: &E::InnerAttributes, ) -> Vec { @@ -1356,9 +1406,7 @@ fn prefixed_warning_filters( prefix, n ); - context - .env() - .add_diag(diag!(Attributes::ValueWarning, (*loc, msg))); + context.add_diag(diag!(Attributes::ValueWarning, (*loc, msg))); *n } }) @@ -1476,7 +1524,7 @@ fn aliases_from_member( ) -> Option { macro_rules! check_name_and_add_implicit_alias { ($kind:expr, $name:expr) => {{ - if let Some(n) = check_valid_module_member_name(context, $kind, $name) { + if let Some(n) = check_valid_module_member_name(context.reporter(), $kind, $name) { if let Err(loc) = acc.add_implicit_member_alias( n.clone(), current_module.clone(), @@ -1560,7 +1608,7 @@ fn use_( method, } => { let pkg = context.current_package(); - context.env().check_feature(pkg, FeatureGate::DotCall, loc); + context.check_feature(pkg, FeatureGate::DotCall, loc); let is_public = match visibility { P::Visibility::Public(vis_loc) => Some(vis_loc), P::Visibility::Internal => None, @@ -1571,7 +1619,7 @@ fn use_( otherwise they must internal to declared scope.", P::Visibility::PUBLIC ); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidUseFun, (loc, msg), (vis_loc, vis_msg) @@ -1612,11 +1660,9 @@ fn module_use( }; macro_rules! add_module_alias { ($ident:expr, $alias:expr) => {{ - if let Err(()) = check_restricted_name_all_cases( - &mut context.defn_context, - NameCase::ModuleAlias, - &$alias, - ) { + if let Err(()) = + check_restricted_name_all_cases(context.reporter(), NameCase::ModuleAlias, &$alias) + { return; } @@ -1629,7 +1675,7 @@ fn module_use( P::ModuleUse::Module(alias_opt) => { let mident = module_ident(&mut context.defn_context, in_mident); if !context.defn_context.module_members.contains_key(&mident) { - context.env().add_diag(unbound_module(&mident)); + context.add_diag(unbound_module(&mident)); return; }; let alias = alias_opt @@ -1642,7 +1688,7 @@ fn module_use( let members = match context.defn_context.module_members.get(&mident) { Some(members) => members, None => { - context.env().add_diag(unbound_module(&mident)); + context.add_diag(unbound_module(&mident)); return; } }; @@ -1681,7 +1727,7 @@ fn module_use( "Invalid 'use'. Unbound member '{}' in module '{}'", member, mident ); - context.env().add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundModuleMember, (member.loc, msg), (mloc, format!("Module '{}' declared here", mident)), @@ -1693,10 +1739,11 @@ fn module_use( let alias = alias_opt.unwrap_or(member); - let alias = match check_valid_module_member_alias(context, member_kind, alias) { - None => continue, - Some(alias) => alias, - }; + let alias = + match check_valid_module_member_alias(context.reporter(), member_kind, alias) { + None => continue, + Some(alias) => alias, + }; if let Err(old_loc) = acc.add_member_alias(alias, mident, member, member_kind) { duplicate_module_member(context, old_loc, alias) } @@ -1722,7 +1769,7 @@ fn module_use( P::ModuleUse::Partial { .. } => { let mident = module_ident(&mut context.defn_context, in_mident); if !context.defn_context.module_members.contains_key(&mident) { - context.env().add_diag(unbound_module(&mident)); + context.add_diag(unbound_module(&mident)); return; }; add_module_alias!(mident, mident.value.module.0) @@ -1758,13 +1805,13 @@ fn explicit_use_fun( let access_result!(function, tyargs, is_macro) = context.name_access_chain_to_module_access(Access::ApplyPositional, *function)?; ice_assert!( - context.env(), + context.reporter(), tyargs.is_none(), loc, "'use fun' with tyargs" ); ice_assert!( - context.env(), + context.reporter(), is_macro.is_none(), loc, "Found a 'use fun' as a macro" @@ -1772,13 +1819,13 @@ fn explicit_use_fun( let access_result!(ty, tyargs, is_macro) = context.name_access_chain_to_module_access(Access::Type, *ty)?; ice_assert!( - context.env(), + context.reporter(), tyargs.is_none(), loc, "'use fun' with tyargs" ); ice_assert!( - context.env(), + context.reporter(), is_macro.is_none(), loc, "Found a 'use fun' as a macro" @@ -1798,7 +1845,7 @@ fn duplicate_module_alias(context: &mut Context, old_loc: Loc, alias: Name) { "Duplicate module alias '{}'. Module aliases must be unique within a given namespace", alias ); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (alias.loc, msg), (old_loc, "Alias previously defined here"), @@ -1810,7 +1857,7 @@ fn duplicate_module_member(context: &mut Context, old_loc: Loc, alias: Name) { "Duplicate module member or alias '{}'. Top level names in a namespace must be unique", alias ); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (alias.loc, msg), (old_loc, "Alias previously defined here"), @@ -1839,7 +1886,7 @@ fn unused_alias(context: &mut Context, _kind: &str, alias: Name) { alias )); } - context.env().add_diag(diag); + context.add_diag(diag); } //************************************************************************************************** @@ -1872,9 +1919,7 @@ fn struct_def_( } = pstruct; let attributes = flatten_attributes(context, AttributePosition::Struct, attributes); let warning_filter = warning_filter(context, &attributes); - context - .env() - .add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let type_parameters = datatype_type_parameters(context, pty_params); context.push_type_parameters(type_parameters.iter().map(|tp| &tp.name)); let abilities = ability_set(context, "modifier", abilities_vec); @@ -1889,7 +1934,7 @@ fn struct_def_( fields, }; context.pop_alias_scope(None); - context.env().pop_warning_filter_scope(); + context.pop_warning_filter_scope(); (name, sdef) } @@ -1910,7 +1955,7 @@ fn struct_fields( for (idx, (field, pt)) in pfields_vec.into_iter().enumerate() { let t = type_(context, pt); if let Err((field, old_loc)) = field_map.add(field, (idx, t)) { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, ( field.loc(), @@ -1956,9 +2001,7 @@ fn enum_def_( } = penum; let attributes = flatten_attributes(context, AttributePosition::Enum, attributes); let warning_filter = warning_filter(context, &attributes); - context - .env() - .add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let type_parameters = datatype_type_parameters(context, pty_params); context.push_type_parameters(type_parameters.iter().map(|tp| &tp.name)); let abilities = ability_set(context, "modifier", abilities_vec); @@ -1973,7 +2016,7 @@ fn enum_def_( variants, }; context.pop_alias_scope(None); - context.env().pop_warning_filter_scope(); + context.pop_warning_filter_scope(); (name, edef) } @@ -1985,7 +2028,7 @@ fn enum_variants( ) -> UniqueMap { let mut variants = UniqueMap::new(); if pvariants.is_empty() { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidEnum, (eloc, "An 'enum' must define at least one variant") )) @@ -1998,7 +2041,7 @@ fn enum_variants( "Duplicate definition for variant '{}' in enum '{}'", vname, ename ); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (loc, msg), (old_loc.1, "Variant previously defined here") @@ -2036,7 +2079,7 @@ fn variant_fields( for (idx, (field, pt)) in pfields_vec.into_iter().enumerate() { let t = type_(context, pt); if let Err((field, old_loc)) = field_map.add(field, (idx, t)) { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, ( field.loc(), @@ -2070,7 +2113,7 @@ fn friend( unique", mident ); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (friend.loc, msg), (old_friend.loc, "Friend previously declared here"), @@ -2093,14 +2136,11 @@ fn friend_(context: &mut Context, pfriend_decl: P::FriendDecl) -> Option<(Module .map(|sp!(loc, _)| *loc) .collect::>(); let attributes = flatten_attributes(context, AttributePosition::Friend, pattributes); - Some(( - mident, - E::Friend { - attributes, - attr_locs, - loc, - }, - )) + Some((mident, E::Friend { + attributes, + attr_locs, + loc, + })) } //************************************************************************************************** @@ -2132,9 +2172,7 @@ fn constant_( } = pconstant; let attributes = flatten_attributes(context, AttributePosition::Constant, pattributes); let warning_filter = warning_filter(context, &attributes); - context - .env() - .add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let signature = type_(context, psignature); let value = *exp(context, Box::new(pvalue)); let constant = E::Constant { @@ -2145,7 +2183,7 @@ fn constant_( signature, value, }; - context.env().pop_warning_filter_scope(); + context.pop_warning_filter_scope(); (name, constant) } @@ -2183,9 +2221,7 @@ fn function_( } = pfunction; let attributes = flatten_attributes(context, AttributePosition::Function, pattributes); let warning_filter = warning_filter(context, &attributes); - context - .env() - .add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); if let (Some(entry_loc), Some(macro_loc)) = (entry, macro_) { let e_msg = format!( "Invalid function declaration. \ @@ -2193,7 +2229,7 @@ fn function_( are fully-expanded inline during compilation" ); let m_msg = format!("Function declared as '{MACRO_MODIFIER}' here"); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidFunction, (entry_loc, e_msg), (macro_loc, m_msg), @@ -2205,7 +2241,7 @@ fn function_( '{NATIVE_MODIFIER}' functions cannot be '{MACRO_MODIFIER}'", ); let m_msg = format!("Function declared as '{MACRO_MODIFIER}' here"); - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidFunction, (*native_loc, n_msg), (macro_loc, m_msg), @@ -2213,9 +2249,7 @@ fn function_( } if let Some(macro_loc) = macro_ { let current_package = context.current_package(); - context - .env() - .check_feature(current_package, FeatureGate::MacroFuns, macro_loc); + context.check_feature(current_package, FeatureGate::MacroFuns, macro_loc); } let visibility = visibility(pvisibility); let signature = function_signature(context, macro_, psignature); @@ -2244,7 +2278,7 @@ fn function_( body, }; context.pop_alias_scope(None); - context.env().pop_warning_filter_scope(); + context.pop_warning_filter_scope(); (name, fdef) } @@ -2274,7 +2308,7 @@ fn function_signature( .map(|(pmut, v, t)| (mutability(context, v.loc(), pmut), v, type_(context, t))) .collect::>(); for (_, v, _) in ¶meters { - check_valid_function_parameter_name(context, is_macro, v) + check_valid_function_parameter_name(context.reporter(), is_macro, v) } let return_type = type_(context, pret_ty); E::FunctionSignature { @@ -2303,7 +2337,7 @@ fn ability_set(context: &mut Context, case: &str, abilities_vec: Vec) - for ability in abilities_vec { let loc = ability.loc; if let Err(prev_loc) = set.add(ability) { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (loc, format!("Duplicate '{}' ability {}", ability, case)), (prev_loc, "Ability previously given here") @@ -2322,7 +2356,7 @@ fn function_type_parameters( .into_iter() .map(|(name, constraints_vec)| { let constraints = ability_set(context, "constraint", constraints_vec); - let _ = check_valid_type_parameter_name(context, is_macro, &name); + let _ = check_valid_type_parameter_name(context.reporter(), is_macro, &name); (name, constraints) }) .collect() @@ -2335,7 +2369,7 @@ fn datatype_type_parameters( pty_params .into_iter() .map(|param| { - let _ = check_valid_type_parameter_name(context, None, ¶m.name); + let _ = check_valid_type_parameter_name(context.reporter(), None, ¶m.name); E::DatatypeTypeParameter { is_phantom: param.is_phantom, name: param.name, @@ -2537,9 +2571,7 @@ fn exp(context: &mut Context, pe: Box) -> Box { PE::Name(pn) if pn.value.has_tyargs() => { let msg = "Expected name to be followed by a brace-enclosed list of field expressions \ or a parenthesized list of arguments for a function call"; - context - .env() - .add_diag(diag!(NameResolution::NamePositionMismatch, (loc, msg))); + context.add_diag(diag!(NameResolution::NamePositionMismatch, (loc, msg))); EE::UnresolvedError } PE::Name(pn) => { @@ -2584,11 +2616,8 @@ fn exp(context: &mut Context, pe: Box) -> Box { PE::IfElse(pb, pt, pf_opt) => { let eb = exp(context, pb); let et = exp(context, pt); - let ef = match pf_opt { - None => Box::new(sp(loc, EE::Unit { trailing: false })), - Some(pf) => exp(context, pf), - }; - EE::IfElse(eb, et, ef) + let ef_opt = pf_opt.map(|pf| exp(context, pf)); + EE::IfElse(eb, et, ef_opt) } PE::Match(subject, sp!(aloc, arms)) => EE::Match( exp(context, subject), @@ -2639,7 +2668,8 @@ fn exp(context: &mut Context, pe: Box) -> Box { Some(LValue::FieldMutate(edotted)) => EE::FieldMutate(edotted, er), } } - PE::Abort(pe) => EE::Abort(exp(context, pe)), + PE::Abort(None) => EE::Abort(None), + PE::Abort(Some(pe)) => EE::Abort(Some(exp(context, pe))), PE::Return(name_opt, pe_opt) => { let ev = match pe_opt { None => Box::new(sp(loc, EE::Unit { trailing: false })), @@ -2688,7 +2718,7 @@ fn exp(context: &mut Context, pe: Box) -> Box { EE::UnresolvedError } }, - pdotted_ @ (PE::Dot(_, _) | PE::DotUnresolved(_, _)) => { + pdotted_ @ (PE::Dot(_, _, _) | PE::DotUnresolved(_, _)) => { match exp_dotted(context, Box::new(sp(loc, pdotted_))) { Some(edotted) => EE::ExpDotted(E::DottedUsage::Use, edotted), None => { @@ -2719,7 +2749,7 @@ fn exp(context: &mut Context, pe: Box) -> Box { consider updating your Move edition to '{valid_editions}'" )); diag.add_note(editions::UPGRADE_NOTE); - context.env().add_diag(diag); + context.add_diag(diag); EE::UnresolvedError } else { match exp_dotted(context, Box::new(sp(loc, pdotted_))) { @@ -2732,14 +2762,14 @@ fn exp(context: &mut Context, pe: Box) -> Box { } } - PE::DotCall(pdotted, n, is_macro, ptys_opt, sp!(rloc, prs)) => { + PE::DotCall(pdotted, dot_loc, n, is_macro, ptys_opt, sp!(rloc, prs)) => { match exp_dotted(context, pdotted) { Some(edotted) => { let pkg = context.current_package(); - context.env().check_feature(pkg, FeatureGate::DotCall, loc); + context.check_feature(pkg, FeatureGate::DotCall, loc); let tys_opt = optional_types(context, ptys_opt); let ers = sp(rloc, exps(context, prs)); - EE::MethodCall(edotted, n, is_macro, tys_opt, ers) + EE::MethodCall(edotted, dot_loc, n, is_macro, tys_opt, ers) } None => { assert!(context.env().has_errors()); @@ -2794,8 +2824,8 @@ fn exp_cast(context: &mut Context, in_parens: bool, plhs: Box, pty: P::T | PE::Match(_, _) | PE::Spec(_) => true, - PE::DotCall(lhs, _, _, _, _) - | PE::Dot(lhs, _) + PE::DotCall(lhs, _, _, _, _, _) + | PE::Dot(lhs, _, _) | PE::DotUnresolved(_, lhs) | PE::Index(lhs, _) | PE::Borrow(_, lhs) @@ -2806,14 +2836,10 @@ fn exp_cast(context: &mut Context, in_parens: bool, plhs: Box, pty: P::T let current_package = context.current_package(); let loc = plhs.loc; let supports_feature = - context - .env() - .check_feature(current_package, FeatureGate::NoParensCast, loc); + context.check_feature(current_package, FeatureGate::NoParensCast, loc); if supports_feature && ambiguous_cast(&plhs) { let msg = "Potentially ambiguous 'as'. Add parentheses to disambiguate"; - context - .env() - .add_diag(diag!(Syntax::AmbiguousCast, (loc, msg))); + context.add_diag(diag!(Syntax::AmbiguousCast, (loc, msg))); } } EE::Cast(exp(context, plhs), type_(context, pty)) @@ -2843,9 +2869,7 @@ fn maybe_labeled_exp( _ => { let msg = "Invalid label. Labels can only be used on 'while', 'loop', or block '{{}}' \ expressions"; - context - .env() - .add_diag(diag!(Syntax::InvalidLabel, (loc, msg))); + context.add_diag(diag!(Syntax::InvalidLabel, (loc, msg))); E::Exp_::UnresolvedError } }; @@ -2859,7 +2883,7 @@ fn ensure_unique_label( label_opt: Option, ) { if let Some(old_label) = label_opt { - context.env().add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidLabel, (loc, "Multiple labels for a single expression"), (old_label.0.loc, "Label previously given here"), @@ -2905,7 +2929,7 @@ fn move_or_copy_path_(context: &mut Context, case: PathCase, pe: Box) -> if !matches!(&inner.value, E::Exp_::Name(_, _)) { let cmsg = format!("Invalid '{}' of expression", case.case()); let emsg = "Expected a name or path access, e.g. 'x' or 'e.f'"; - context.env().add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidMoveOrCopy, (cloc, cmsg), (inner.loc, emsg) @@ -2913,13 +2937,11 @@ fn move_or_copy_path_(context: &mut Context, case: PathCase, pe: Box) -> return None; } } - E::ExpDotted_::Dot(_, _) + E::ExpDotted_::Dot(_, _, _) | E::ExpDotted_::DotUnresolved(_, _) | E::ExpDotted_::Index(_, _) => { let current_package = context.current_package(); - context - .env() - .check_feature(current_package, FeatureGate::Move2024Paths, cloc); + context.check_feature(current_package, FeatureGate::Move2024Paths, cloc); } } Some(match case { @@ -2934,18 +2956,14 @@ fn exp_dotted(context: &mut Context, pdotted: Box) -> Option { + PE::Dot(plhs, dot_loc, field) => { let lhs = exp_dotted(context, plhs)?; - EE::Dot(lhs, field) + EE::Dot(lhs, dot_loc, field) } PE::Index(plhs, sp!(argloc, args)) => { let cur_pkg = context.current_package(); - context - .env() - .check_feature(cur_pkg, FeatureGate::Move2024Paths, loc); - context - .env() - .check_feature(cur_pkg, FeatureGate::SyntaxMethods, loc); + context.check_feature(cur_pkg, FeatureGate::Move2024Paths, loc); + context.check_feature(cur_pkg, FeatureGate::SyntaxMethods, loc); let lhs = exp_dotted(context, plhs)?; let args = args .into_iter() @@ -2976,7 +2994,7 @@ fn check_ellipsis_usage(context: &mut Context, ellipsis_locs: &[Loc]) { diag.add_secondary_label((*loc, "Ellipsis pattern used again here")); } diag.add_note("An ellipsis pattern can only appear once in a constructor's pattern."); - context.env().add_diag(diag); + context.add_diag(diag); } } @@ -3010,7 +3028,7 @@ fn match_pattern(context: &mut Context, sp!(loc, pat_): P::MatchPattern) -> E::M EM::Variant(_, _) | EM::ModuleAccess(_, _) => Some(name), EM::Name(_) if identifier_okay => Some(name), EM::Name(_) => { - context.env().add_diag(diag!( + context.add_diag(diag!( Syntax::UnexpectedToken, ( name.loc, @@ -3035,7 +3053,7 @@ fn match_pattern(context: &mut Context, sp!(loc, pat_): P::MatchPattern) -> E::M } = context.name_access_chain_to_module_access(Access::Pattern, name_chain)?; let name = head_ctor_okay(context, access, identifier_okay)?; if let Some(loc) = is_macro { - context.env().add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidMacro, (loc, "Macros are not allowed in patterns.") )); @@ -3141,14 +3159,14 @@ fn match_pattern(context: &mut Context, sp!(loc, pat_): P::MatchPattern) -> E::M resolve this constant's name", ); } - context.env().add_diag(diag); + context.add_diag(diag); error_pattern!() } else { if let Some(_tys) = pts_opt { let msg = "Invalid type arguments on a pattern variable"; let mut diag = diag!(Declarations::InvalidName, (name.loc, msg)); diag.add_note("Type arguments cannot appear on pattern variables"); - context.env().add_diag(diag); + context.add_diag(diag); } sp(loc, EP::Binder(mutability(context, loc, mut_), Var(name))) } @@ -3158,7 +3176,7 @@ fn match_pattern(context: &mut Context, sp!(loc, pat_): P::MatchPattern) -> E::M let msg = "'mut' can only be used with variable bindings in patterns"; let nmsg = "Expected a valid 'enum' variant, 'struct', or 'const', not a variable"; - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidName, (mloc, msg), (head_ctor_name.loc, nmsg) @@ -3192,7 +3210,7 @@ fn match_pattern(context: &mut Context, sp!(loc, pat_): P::MatchPattern) -> E::M ), PP::At(x, inner) => { if x.is_underscore() { - context.env().add_diag(diag!( + context.add_diag(diag!( NameResolution::InvalidPattern, (x.loc(), "Can't use '_' as a binder in an '@' pattern") )); @@ -3219,42 +3237,42 @@ pub(super) fn value(context: &mut DefnContext, sp!(loc, pvalue_): P::Value) -> O PV::Num(s) if s.ends_with("u8") => match parse_u8(&s[..s.len() - 2]) { Ok((u, _format)) => EV::U8(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u8'")); + context.add_diag(num_too_big_error(loc, "'u8'")); return None; } }, PV::Num(s) if s.ends_with("u16") => match parse_u16(&s[..s.len() - 3]) { Ok((u, _format)) => EV::U16(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u16'")); + context.add_diag(num_too_big_error(loc, "'u16'")); return None; } }, PV::Num(s) if s.ends_with("u32") => match parse_u32(&s[..s.len() - 3]) { Ok((u, _format)) => EV::U32(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u32'")); + context.add_diag(num_too_big_error(loc, "'u32'")); return None; } }, PV::Num(s) if s.ends_with("u64") => match parse_u64(&s[..s.len() - 3]) { Ok((u, _format)) => EV::U64(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u64'")); + context.add_diag(num_too_big_error(loc, "'u64'")); return None; } }, PV::Num(s) if s.ends_with("u128") => match parse_u128(&s[..s.len() - 4]) { Ok((u, _format)) => EV::U128(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u128'")); + context.add_diag(num_too_big_error(loc, "'u128'")); return None; } }, PV::Num(s) if s.ends_with("u256") => match parse_u256(&s[..s.len() - 4]) { Ok((u, _format)) => EV::U256(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u256'")); + context.add_diag(num_too_big_error(loc, "'u256'")); return None; } }, @@ -3262,7 +3280,7 @@ pub(super) fn value(context: &mut DefnContext, sp!(loc, pvalue_): P::Value) -> O PV::Num(s) => match parse_u256(&s) { Ok((u, _format)) => EV::InferredNum(u), Err(_) => { - context.env.add_diag(num_too_big_error( + context.add_diag(num_too_big_error( loc, "the largest possible integer type, 'u256'", )); @@ -3273,14 +3291,14 @@ pub(super) fn value(context: &mut DefnContext, sp!(loc, pvalue_): P::Value) -> O PV::HexString(s) => match hex_string::decode(loc, &s) { Ok(v) => EV::Bytearray(v), Err(e) => { - context.env.add_diag(*e); + context.add_diag(*e); return None; } }, PV::ByteString(s) => match byte_string::decode(loc, &s) { Ok(v) => EV::Bytearray(v), Err(e) => { - context.env.add_diags(e); + context.add_diags(e); return None; } }, @@ -3317,7 +3335,7 @@ fn named_fields( let mut fmap = UniqueMap::new(); for (idx, (field, x)) in xs.into_iter().enumerate() { if let Err((field, old_loc)) = fmap.add(field, (idx, x)) { - context.env().add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (loc, format!("Invalid {}", case)), ( @@ -3346,13 +3364,18 @@ fn bind(context: &mut Context, sp!(loc, pb_): P::Bind) -> Option { let b_ = match pb_ { PB::Var(pmut, v) => { let emut = mutability(context, v.loc(), pmut); - check_valid_local_name(context, &v); + check_valid_local_name(context.reporter(), &v); EL::Var(Some(emut), sp(loc, E::ModuleAccess_::Name(v.0)), None) } PB::Unpack(ptn, pfields) => { let access_result!(name, ptys_opt, is_macro) = context.name_access_chain_to_module_access(Access::ApplyNamed, *ptn)?; - ice_assert!(context.env(), is_macro.is_none(), loc, "Found macro in lhs"); + ice_assert!( + context.reporter(), + is_macro.is_none(), + loc, + "Found macro in lhs" + ); let tys_opt = optional_sp_types(context, ptys_opt); let fields = match pfields { FieldBindings::Named(named_bindings) => { @@ -3429,12 +3452,12 @@ fn lvalues(context: &mut Context, e: Box) -> Option { let er = exp(context, pr); L::Mutate(er) } - pdotted_ @ PE::Dot(_, _) => { + pdotted_ @ PE::Dot(_, _, _) => { let dotted = exp_dotted(context, Box::new(sp(loc, pdotted_)))?; L::FieldMutate(dotted) } PE::Index(_, _) => { - context.env().add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidLValue, ( loc, @@ -3461,14 +3484,14 @@ fn assign(context: &mut Context, sp!(loc, e_): P::Exp) -> Option { "If you are trying to unpack a struct, try adding fields, e.g.'{} {{}}'", name )); - context.env().add_diag(diag); + context.add_diag(diag); None } Some(access_result!(_, _ptys_opt, Some(_))) => { let msg = "Unexpected assignment of name with macro invocation"; let mut diag = diag!(Syntax::InvalidLValue, (loc, msg)); diag.add_note("Macro invocation '!' must appear on an invocation"); - context.env().add_diag(diag); + context.add_diag(diag); None } Some(access_result!(sp!(_, name @ M::Name(_)), None, None)) => { @@ -3481,19 +3504,16 @@ fn assign(context: &mut Context, sp!(loc, e_): P::Exp) -> Option { "If you are trying to unpack a struct, try adding fields, e.g.'{} {{}}'", name )); - context.env().add_diag(diag); + context.add_diag(diag); None } Some(access_result!(sp!(loc, M::Variant(_, _)), _tys_opt, _is_macro)) => { let cur_pkg = context.current_package(); - if context - .env() - .check_feature(cur_pkg, FeatureGate::Enums, loc) - { + if context.check_feature(cur_pkg, FeatureGate::Enums, loc) { let msg = "Unexpected assignment of variant"; let mut diag = diag!(Syntax::InvalidLValue, (loc, msg)); diag.add_note("If you are trying to unpack an enum variant, use 'match'"); - context.env().add_diag(diag); + context.add_diag(diag); None } else { assert!(context.env().has_errors()); @@ -3507,7 +3527,7 @@ fn assign(context: &mut Context, sp!(loc, e_): P::Exp) -> Option { let access_result!(name, ptys_opt, is_macro) = context.name_access_chain_to_module_access(Access::ApplyNamed, pn)?; ice_assert!( - context.env(), + context.reporter(), is_macro.is_none(), loc, "Marked a bind as a macro" @@ -3521,13 +3541,11 @@ fn assign(context: &mut Context, sp!(loc, e_): P::Exp) -> Option { } PE::Call(pn, sp!(_, exprs)) => { let pkg = context.current_package(); - context - .env() - .check_feature(pkg, FeatureGate::PositionalFields, loc); + context.check_feature(pkg, FeatureGate::PositionalFields, loc); let access_result!(name, ptys_opt, is_macro) = context.name_access_chain_to_module_access(Access::ApplyNamed, pn)?; ice_assert!( - context.env(), + context.reporter(), is_macro.is_none(), loc, "Marked a bind as a macro" @@ -3543,7 +3561,7 @@ fn assign(context: &mut Context, sp!(loc, e_): P::Exp) -> Option { )) } _ => { - context.env().add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidLValue, ( loc, @@ -3589,387 +3607,3 @@ fn mutability(context: &mut Context, _loc: Loc, pmut: P::Mutability) -> E::Mutab None => E::Mutability::Either, } } - -//************************************************************************************************** -// Valid names -//************************************************************************************************** - -fn check_valid_address_name( - context: &mut DefnContext, - sp!(_, ln_): &P::LeadingNameAccess, -) -> Result<(), ()> { - use P::LeadingNameAccess_ as LN; - match ln_ { - LN::AnonymousAddress(_) => Ok(()), - LN::GlobalAddress(n) | LN::Name(n) => { - check_restricted_name_all_cases(context, NameCase::Address, n) - } - } -} - -fn valid_local_variable_name(s: Symbol) -> bool { - s.starts_with('_') || s.starts_with(|c: char| c.is_ascii_lowercase()) -} - -fn check_valid_function_parameter_name(context: &mut Context, is_macro: Option, v: &Var) { - const SYNTAX_IDENTIFIER_NOTE: &str = "'macro' parameters start with '$' to indicate that their arguments are not evaluated \ - before the macro is expanded, meaning the entire expression is substituted. \ - This is different from regular function parameters that are evaluated before the \ - function is called."; - let is_syntax_identifier = v.is_syntax_identifier(); - if let Some(macro_loc) = is_macro { - if !is_syntax_identifier && !v.is_underscore() { - let msg = format!( - "Invalid parameter name '{}'. '{}' parameter names must start with '$' (or must be '_')", - v, MACRO_MODIFIER, - ); - let macro_msg = format!("Declared '{}' here", MACRO_MODIFIER); - let mut diag = diag!( - Declarations::InvalidName, - (v.loc(), msg), - (macro_loc, macro_msg), - ); - diag.add_note(SYNTAX_IDENTIFIER_NOTE); - context.env().add_diag(diag); - } - } else if is_syntax_identifier { - let msg = format!( - "Invalid parameter name '{}'. Non-'{}' parameter names cannot start with '$'", - v, MACRO_MODIFIER, - ); - let mut diag = diag!(Declarations::InvalidName, (v.loc(), msg)); - diag.add_note(SYNTAX_IDENTIFIER_NOTE); - context.env().add_diag(diag); - } else if !is_valid_local_variable_name(v.value()) { - let msg = format!( - "Invalid parameter name '{}'. Local variable names must start with 'a'..'z', '_', \ - or be a valid name quoted with backticks (`name`)", - v, - ); - context - .env() - .add_diag(diag!(Declarations::InvalidName, (v.loc(), msg))); - } - let _ = check_restricted_name_all_cases(&mut context.defn_context, NameCase::Variable, &v.0); -} - -fn check_valid_local_name(context: &mut Context, v: &Var) { - if !is_valid_local_variable_name(v.value()) { - let msg = format!( - "Invalid local name '{}'. Local variable names must start with 'a'..'z', '_', \ - or be a valid name quoted with backticks (`name`)", - v, - ); - context - .env() - .add_diag(diag!(Declarations::InvalidName, (v.loc(), msg))); - } - let _ = check_restricted_name_all_cases(&mut context.defn_context, NameCase::Variable, &v.0); -} - -fn is_valid_local_variable_name(s: Symbol) -> bool { - Var::is_valid_name(s) && !Var::is_syntax_identifier_name(s) -} - -#[derive(Copy, Clone, Debug)] -pub enum ModuleMemberKind { - Constant, - Function, - Struct, - Enum, -} - -impl ModuleMemberKind { - pub fn case(self) -> NameCase { - match self { - ModuleMemberKind::Constant => NameCase::Constant, - ModuleMemberKind::Function => NameCase::Function, - ModuleMemberKind::Struct => NameCase::Struct, - ModuleMemberKind::Enum => NameCase::Enum, - } - } -} - -#[derive(Copy, Clone, Debug)] -pub enum NameCase { - Constant, - Function, - Struct, - Enum, - Module, - ModuleMemberAlias(ModuleMemberKind), - ModuleAlias, - Variable, - Address, - TypeParameter, -} - -impl NameCase { - pub const fn name(&self) -> &'static str { - match self { - NameCase::Constant => "constant", - NameCase::Function => "function", - NameCase::Struct => "struct", - NameCase::Enum => "enum", - NameCase::Module => "module", - NameCase::ModuleMemberAlias(ModuleMemberKind::Function) => "function alias", - NameCase::ModuleMemberAlias(ModuleMemberKind::Constant) => "constant alias", - NameCase::ModuleMemberAlias(ModuleMemberKind::Struct) => "struct alias", - NameCase::ModuleMemberAlias(ModuleMemberKind::Enum) => "enum alias", - NameCase::ModuleAlias => "module alias", - NameCase::Variable => "variable", - NameCase::Address => "address", - NameCase::TypeParameter => "type parameter", - } - } -} - -fn check_valid_module_member_name( - context: &mut Context, - member: ModuleMemberKind, - name: Name, -) -> Option { - match check_valid_module_member_name_impl(context, member, &name, member.case()) { - Err(()) => None, - Ok(()) => Some(name), - } -} - -fn check_valid_module_member_alias( - context: &mut Context, - member: ModuleMemberKind, - alias: Name, -) -> Option { - match check_valid_module_member_name_impl( - context, - member, - &alias, - NameCase::ModuleMemberAlias(member), - ) { - Err(()) => None, - Ok(()) => Some(alias), - } -} - -fn check_valid_module_member_name_impl( - context: &mut Context, - member: ModuleMemberKind, - n: &Name, - case: NameCase, -) -> Result<(), ()> { - use ModuleMemberKind as M; - fn upper_first_letter(s: &str) -> String { - let mut chars = s.chars(); - match chars.next() { - None => String::new(), - Some(c) => c.to_uppercase().collect::() + chars.as_str(), - } - } - match member { - M::Function => { - if n.value.starts_with(|c| c == '_') { - let msg = format!( - "Invalid {} name '{}'. {} names cannot start with '_'", - case.name(), - n, - upper_first_letter(case.name()), - ); - context - .env() - .add_diag(diag!(Declarations::InvalidName, (n.loc, msg))); - return Err(()); - } - } - M::Constant | M::Struct | M::Enum => { - if !is_valid_datatype_or_constant_name(&n.value) { - let msg = format!( - "Invalid {} name '{}'. {} names must start with 'A'..'Z'", - case.name(), - n, - upper_first_letter(case.name()), - ); - context - .env() - .add_diag(diag!(Declarations::InvalidName, (n.loc, msg))); - return Err(()); - } - } - } - - // TODO move these names to a more central place? - check_restricted_names( - context, - case, - n, - crate::naming::ast::BuiltinFunction_::all_names(), - )?; - check_restricted_names( - context, - case, - n, - crate::naming::ast::BuiltinTypeName_::all_names(), - )?; - - // Restricting Self for now in the case where we ever have impls - // Otherwise, we could allow it - check_restricted_name_all_cases(&mut context.defn_context, case, n)?; - - Ok(()) -} - -fn check_valid_type_parameter_name( - context: &mut Context, - is_macro: Option, - n: &Name, -) -> Result<(), ()> { - // TODO move these names to a more central place? - if n.value == symbol!("_") { - let diag = restricted_name_error(NameCase::TypeParameter, n.loc, "_"); - context.env().add_diag(diag); - return Err(()); - } - - const SYNTAX_IDENTIFIER_NOTE: &str = "Type parameter names starting with '$' indicate that \ - their arguments do not have to satisfy certain constraints before the macro is expanded, \ - meaning types like '&mut u64' or '(bool, u8)' may be used as arguments."; - - let is_syntax_ident = Var::is_syntax_identifier_name(n.value); - if let Some(macro_loc) = is_macro { - if !is_syntax_ident { - let msg = format!( - "Invalid type parameter name. \ - '{} fun' type parameter names must start with '$'", - MACRO_MODIFIER - ); - let macro_msg = format!("Declared '{}' here", MACRO_MODIFIER); - let mut diag = diag!( - Declarations::InvalidName, - (n.loc, msg), - (macro_loc, macro_msg), - ); - diag.add_note(SYNTAX_IDENTIFIER_NOTE); - context.env().add_diag(diag); - } else { - let next_char = n.value.chars().nth(1).unwrap(); - if !next_char.is_ascii_alphabetic() { - let msg = format!( - "Invalid type parameter name '{}'. \ - Following the '$', the '{} fun' type parameter must be have a valid type \ - parameter name starting with a letter 'a'..'z' or 'A'..'Z'", - n, MACRO_MODIFIER - ); - let mut diag = diag!(Declarations::InvalidName, (n.loc, msg)); - diag.add_note(SYNTAX_IDENTIFIER_NOTE); - context.env().add_diag(diag); - } - } - } else if is_syntax_ident { - let msg = format!( - "Invalid type parameter name. \ - Only '{} fun' type parameter names cat start with '$'", - MACRO_MODIFIER - ); - let mut diag = diag!(Declarations::InvalidName, (n.loc, msg)); - diag.add_note(SYNTAX_IDENTIFIER_NOTE); - context.env().add_diag(diag); - } - - // TODO move these names to a more central place? - check_restricted_names( - context, - NameCase::TypeParameter, - n, - crate::naming::ast::BuiltinFunction_::all_names(), - )?; - check_restricted_names( - context, - NameCase::TypeParameter, - n, - crate::naming::ast::BuiltinTypeName_::all_names(), - )?; - - check_restricted_name_all_cases(&mut context.defn_context, NameCase::TypeParameter, n) -} - -pub fn is_valid_datatype_or_constant_name(s: &str) -> bool { - s.starts_with(|c: char| c.is_ascii_uppercase()) -} - -// Checks for a restricted name in any decl case -// Self and vector are not allowed -fn check_restricted_name_all_cases( - context: &mut DefnContext, - case: NameCase, - n: &Name, -) -> Result<(), ()> { - match case { - NameCase::Constant - | NameCase::Function - | NameCase::Struct - | NameCase::Enum - | NameCase::Module - | NameCase::ModuleMemberAlias(_) - | NameCase::ModuleAlias - | NameCase::Address => { - if Var::is_syntax_identifier_name(n.value) { - let msg = format!( - "Invalid {} name '{}'. Identifiers starting with '$' can be used only for \ - parameters and type parameters", - case.name(), - n, - ); - context - .env - .add_diag(diag!(Declarations::InvalidName, (n.loc, msg))); - return Err(()); - } - } - NameCase::Variable | NameCase::TypeParameter => (), - } - - let n_str = n.value.as_str(); - let can_be_vector = matches!(case, NameCase::Module | NameCase::ModuleAlias); - if n_str == ModuleName::SELF_NAME - || (!can_be_vector && n_str == crate::naming::ast::BuiltinTypeName_::VECTOR) - { - context - .env - .add_diag(restricted_name_error(case, n.loc, n_str)); - Err(()) - } else { - Ok(()) - } -} - -fn check_restricted_names( - context: &mut Context, - case: NameCase, - sp!(loc, n_): &Name, - all_names: &BTreeSet, -) -> Result<(), ()> { - if all_names.contains(n_) { - context - .env() - .add_diag(restricted_name_error(case, *loc, n_)); - Err(()) - } else { - Ok(()) - } -} - -fn restricted_name_error(case: NameCase, loc: Loc, restricted: &str) -> Diagnostic { - let a_or_an = match case.name().chars().next().unwrap() { - // TODO this is not exhaustive to the indefinite article rules in English - // but 'case' is never user generated, so it should be okay for a while/forever... - 'a' | 'e' | 'i' | 'o' | 'u' => "an", - _ => "a", - }; - let msg = format!( - "Invalid {case} name '{restricted}'. '{restricted}' is restricted and cannot be used to \ - name {a_or_an} {case}", - a_or_an = a_or_an, - case = case.name(), - restricted = restricted, - ); - diag!(NameResolution::ReservedName, (loc, msg)) -} diff --git a/external-crates/move/crates/move-compiler/src/hlir/ast.rs b/external-crates/move/crates/move-compiler/src/hlir/ast.rs index b6df517ef27..aba1efba547 100644 --- a/external-crates/move/crates/move-compiler/src/hlir/ast.rs +++ b/external-crates/move/crates/move-compiler/src/hlir/ast.rs @@ -12,7 +12,7 @@ use move_ir_types::location::*; use move_symbol_pool::Symbol; use crate::{ - diagnostics::WarningFilters, + diagnostics::warning_filters::{WarningFilters, WarningFiltersTable}, expansion::ast::{ ability_modifiers_ast_debug, AbilitySet, Attributes, Friend, ModuleIdent, Mutability, TargetKind, @@ -37,6 +37,8 @@ use crate::{ #[derive(Debug, Clone)] pub struct Program { pub info: Arc, + /// Safety: This table should not be dropped as long as any `WarningFilters` are alive + pub warning_filters_table: Arc, pub modules: UniqueMap, } @@ -151,6 +153,7 @@ pub struct Function { // index in the original order as defined in the source file pub index: usize, pub attributes: Attributes, + pub loc: Loc, /// The original, declared visibility as defined in the source file pub visibility: Visibility, /// We sometimes change the visibility of functions, e.g. `entry` is marked @@ -259,7 +262,8 @@ pub struct Label(pub usize); pub enum Command_ { Assign(AssignCase, Vec, Exp), Mutate(Box, Box), - Abort(Exp), + // Hold location of argument to abort before any inlining or value propagation + Abort(Loc, Exp), Return { from_user: bool, exp: Exp, @@ -446,6 +450,20 @@ impl FunctionSignature { } } +impl Value_ { + pub fn is_zero(&self) -> bool { + match self { + Self::U8(v) => *v == 0, + Self::U16(v) => *v == 0, + Self::U32(v) => *v == 0, + Self::U64(v) => *v == 0, + Self::U128(v) => *v == 0, + Self::U256(v) => *v == move_core_types::u256::U256::zero(), + Self::Address(_) | Self::Bool(_) | Self::Vector(_, _) => false, + } + } +} + impl Var { pub fn loc(&self) -> Loc { self.0.loc @@ -483,7 +501,9 @@ impl Command_ { match self { Break(_) | Continue(_) => panic!("ICE break/continue not translated to jumps"), Assign(_, _, _) | Mutate(_, _) | IgnoreAndPop { .. } => false, - Abort(_) | Return { .. } | Jump { .. } | JumpIf { .. } | VariantSwitch { .. } => true, + Abort(_, _) | Return { .. } | Jump { .. } | JumpIf { .. } | VariantSwitch { .. } => { + true + } } } @@ -497,7 +517,7 @@ impl Command_ { | Jump { .. } | JumpIf { .. } | VariantSwitch { .. } => false, - Abort(_) | Return { .. } => true, + Abort(_, _) | Return { .. } => true, } } @@ -510,7 +530,7 @@ impl Command_ { Mutate(_, _) | Return { .. } - | Abort(_) + | Abort(_, _) | JumpIf { .. } | Jump { .. } | VariantSwitch { .. } => false, @@ -526,7 +546,7 @@ impl Command_ { Mutate(_, _) | Assign(_, _, _) | IgnoreAndPop { .. } => { panic!("ICE Should not be last command in block") } - Abort(_) | Return { .. } => (), + Abort(_, _) | Return { .. } => (), Jump { target, .. } => { successors.insert(*target); } @@ -553,7 +573,7 @@ impl Command_ { use Command_::*; match self { Assign(_, _, _) | Mutate(_, _) | IgnoreAndPop { .. } => false, - Break(_) | Continue(_) | Abort(_) | Return { .. } => true, + Break(_) | Continue(_) | Abort(_, _) | Return { .. } => true, Jump { .. } | JumpIf { .. } | VariantSwitch { .. } => { panic!("ICE found jump/jump-if/variant-switch in hlir") } @@ -569,6 +589,10 @@ impl Exp { pub fn is_unreachable(&self) -> bool { self.exp.value.is_unreachable() } + + pub fn as_value(&self) -> Option<&Value> { + self.exp.value.as_value() + } } impl UnannotatedExp_ { @@ -579,15 +603,20 @@ impl UnannotatedExp_ { pub fn is_unreachable(&self) -> bool { matches!(self, UnannotatedExp_::Unreachable) } + + pub fn as_value(&self) -> Option<&Value> { + match self { + UnannotatedExp_::Value(v) => Some(v), + _ => None, + } + } } impl TypeName_ { - pub fn is( - &self, - address: impl AsRef, - module: impl AsRef, - name: impl AsRef, - ) -> bool { + pub fn is(&self, address: &Addr, module: impl AsRef, name: impl AsRef) -> bool + where + NumericalAddress: PartialEq, + { match self { TypeName_::Builtin(_) => false, TypeName_::ModuleType(mident, n) => { @@ -595,6 +624,13 @@ impl TypeName_ { } } } + + pub fn datatype_name(&self) -> Option<(ModuleIdent, DatatypeName)> { + match self { + TypeName_::Builtin(_) => None, + TypeName_::ModuleType(mident, n) => Some((*mident, *n)), + } + } } impl BaseType_ { @@ -663,12 +699,22 @@ impl BaseType_ { Self::builtin(loc, BuiltinTypeName_::U256, vec![]) } - pub fn is_apply( + pub fn type_name(&self) -> Option<&TypeName> { + match self { + Self::Apply(_, tn, _) => Some(tn), + _ => None, + } + } + + pub fn is_apply( &self, - address: impl AsRef, + address: &Addr, module: impl AsRef, name: impl AsRef, - ) -> Option<(&AbilitySet, &TypeName, &[BaseType])> { + ) -> Option<(&AbilitySet, &TypeName, &[BaseType])> + where + NumericalAddress: PartialEq, + { match self { Self::Apply(abs, n, tys) if n.value.is(address, module, name) => Some((abs, n, tys)), _ => None, @@ -720,12 +766,15 @@ impl SingleType_ { } } - pub fn is_apply( + pub fn is_apply( &self, - address: impl AsRef, + address: &Addr, module: impl AsRef, name: impl AsRef, - ) -> Option<(&AbilitySet, &TypeName, &[BaseType])> { + ) -> Option<(&AbilitySet, &TypeName, &[BaseType])> + where + NumericalAddress: PartialEq, + { match self { Self::Ref(_, b) | Self::Base(b) => b.value.is_apply(address, module, name), } @@ -796,12 +845,15 @@ impl Type_ { sp(loc, t_) } - pub fn is_apply( + pub fn is_apply( &self, - address: impl AsRef, + address: &Addr, module: impl AsRef, name: impl AsRef, - ) -> Option<(&AbilitySet, &TypeName, &[BaseType])> { + ) -> Option<(&AbilitySet, &TypeName, &[BaseType])> + where + NumericalAddress: PartialEq, + { match self { Type_::Unit => None, Type_::Single(t) => t.value.is_apply(address, module, name), @@ -845,12 +897,15 @@ impl TName for BlockLabel { } impl ModuleCall { - pub fn is( + pub fn is( &self, - address: impl AsRef, + address: &Addr, module: impl AsRef, function: impl AsRef, - ) -> bool { + ) -> bool + where + NumericalAddress: PartialEq, + { let Self { module: sp!(_, mident), name: f, @@ -900,10 +955,14 @@ impl std::fmt::Display for Label { impl AstDebug for Program { fn ast_debug(&self, w: &mut AstWriter) { - let Program { modules, info: _ } = self; + let Program { + modules, + info: _, + warning_filters_table: _, + } = self; for (m, mdef) in modules.key_cloned_iter() { - w.write(&format!("module {}", m)); + w.write(format!("module {}", m)); w.block(|w| mdef.ast_debug(w)); w.new_line(); } @@ -926,7 +985,7 @@ impl AstDebug for ModuleDefinition { } = self; warning_filter.ast_debug(w); if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); w.writeln(match target_kind { @@ -938,9 +997,9 @@ impl AstDebug for ModuleDefinition { } => "dependency module", TargetKind::External => "external module", }); - w.writeln(&format!("dependency order #{}", dependency_order)); + w.writeln(format!("dependency order #{}", dependency_order)); for (mident, _loc) in friends.key_cloned_iter() { - w.write(&format!("friend {};", mident)); + w.write(format!("friend {};", mident)); w.new_line(); } for sdef in structs.key_cloned_iter() { @@ -981,13 +1040,13 @@ impl AstDebug for (DatatypeName, &StructDefinition) { w.write("native "); } - w.write(&format!("struct#{index} {name}")); + w.write(format!("struct#{index} {name}")); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); if let StructFields::Defined(fields) = fields { w.block(|w| { w.list(fields, ";", |w, (f, bt)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); bt.ast_debug(w); true }) @@ -1012,12 +1071,12 @@ impl AstDebug for (DatatypeName, &EnumDefinition) { warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("struct#{index} {name}")); + w.write(format!("struct#{index} {name}")); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); w.block(|w| { w.list(variants, ";", |w, (_, v, vdef)| { - w.write(&format!("{} {{ ", v)); + w.write(format!("{} {{ ", v)); vdef.ast_debug(w); w.write(" }"); true @@ -1035,7 +1094,7 @@ impl AstDebug for VariantDefinition { } = self; w.write(format!("id:{}|", index)); w.comma(fields, |w, (f, bt)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); bt.ast_debug(w); }) } @@ -1049,6 +1108,7 @@ impl AstDebug for (FunctionName, &Function) { warning_filter, index, attributes, + loc: _, visibility, compiled_visibility, entry, @@ -1064,12 +1124,12 @@ impl AstDebug for (FunctionName, &Function) { compiled_visibility.ast_debug(w); w.write(") "); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if let FunctionBody_::Native = &body.value { w.write("native "); } - w.write(&format!("fun#{index} {name}")); + w.write(format!("fun#{index} {name}")); signature.ast_debug(w); match &body.value { FunctionBody_::Defined { locals, body } => w.block(|w| (locals, body).ast_debug(w)), @@ -1092,7 +1152,7 @@ impl AstDebug for (&UniqueMap, &Block) { w.indent(4, |w| { w.list(*locals, ",", |w, (_, v, (mut_, st))| { mut_.ast_debug(w); - w.write(&format!("{}: ", v)); + w.write(format!("{}: ", v)); st.ast_debug(w); true }) @@ -1124,19 +1184,19 @@ impl AstDebug for FunctionSignature { impl AstDebug for Visibility { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{} ", self)) + w.write(format!("{} ", self)) } } impl AstDebug for Var { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self.0)) + w.write(format!("{}", self.0)) } } impl AstDebug for BlockLabel { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("'{}", self.0)) + w.write(format!("'{}", self.0)) } } @@ -1155,7 +1215,7 @@ impl AstDebug for (ConstantName, &Constant) { ) = self; warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("const#{index} {name}:")); + w.write(format!("const#{index} {name}:")); signature.ast_debug(w); w.write(" = "); w.block(|w| value.ast_debug(w)); @@ -1167,7 +1227,7 @@ impl AstDebug for TypeName_ { fn ast_debug(&self, w: &mut AstWriter) { match self { TypeName_::Builtin(bt) => bt.ast_debug(w), - TypeName_::ModuleType(m, s) => w.write(&format!("{}::{}", m, s)), + TypeName_::ModuleType(m, s) => w.write(format!("{}::{}", m, s)), } } } @@ -1347,7 +1407,7 @@ impl AstDebug for Command_ { w.write(" = "); rhs.ast_debug(w); } - C::Abort(e) => { + C::Abort(_, e) => { w.write("abort "); e.ast_debug(w); } @@ -1373,8 +1433,8 @@ impl AstDebug for Command_ { w.write(" = "); exp.ast_debug(w); } - C::Jump { target, from_user } if *from_user => w.write(&format!("jump@{}", target.0)), - C::Jump { target, .. } => w.write(&format!("jump {}", target.0)), + C::Jump { target, from_user } if *from_user => w.write(format!("jump@{}", target.0)), + C::Jump { target, .. } => w.write(format!("jump {}", target.0)), C::JumpIf { cond, if_true, @@ -1382,7 +1442,7 @@ impl AstDebug for Command_ { } => { w.write("jump_if("); cond.ast_debug(w); - w.write(&format!(") {} else {}", if_true.0, if_false.0)); + w.write(format!(") {} else {}", if_true.0, if_false.0)); } C::VariantSwitch { subject, @@ -1406,14 +1466,14 @@ impl AstDebug for Value_ { fn ast_debug(&self, w: &mut AstWriter) { use Value_ as V; match self { - V::Address(addr) => w.write(&format!("@{}", addr)), - V::U8(u) => w.write(&format!("{}u8", u)), - V::U16(u) => w.write(&format!("{}u16", u)), - V::U32(u) => w.write(&format!("{}u32", u)), - V::U64(u) => w.write(&format!("{}u64", u)), - V::U128(u) => w.write(&format!("{}u128", u)), - V::U256(u) => w.write(&format!("{}u256", u)), - V::Bool(b) => w.write(&format!("{}", b)), + V::Address(addr) => w.write(format!("@{}", addr)), + V::U8(u) => w.write(format!("{}u8", u)), + V::U16(u) => w.write(format!("{}u16", u)), + V::U32(u) => w.write(format!("{}u32", u)), + V::U64(u) => w.write(format!("{}u64", u)), + V::U128(u) => w.write(format!("{}u128", u)), + V::U256(u) => w.write(format!("{}u256", u)), + V::Bool(b) => w.write(format!("{}", b)), V::Vector(ty, elems) => { w.write("vector#value"); w.write("<"); @@ -1460,7 +1520,7 @@ impl AstDebug for UnannotatedExp_ { MoveOpAnnotation::InferredLastUsage => "#last ", MoveOpAnnotation::InferredNoCopy => "#no-copy ", }; - w.write(&format!("move{}", case)); + w.write(format!("move{}", case)); v.ast_debug(w) } E::Copy { @@ -1477,12 +1537,12 @@ impl AstDebug for UnannotatedExp_ { w.write("copy@"); v.ast_debug(w) } - E::Constant(c) => w.write(&format!("{}", c)), + E::Constant(c) => w.write(format!("{}", c)), E::ModuleCall(mcall) => { mcall.ast_debug(w); } E::Vector(_loc, n, ty, elems) => { - w.write(&format!("vector#{}", n)); + w.write(format!("vector#{}", n)); w.write("<"); ty.ast_debug(w); w.write(">"); @@ -1496,26 +1556,26 @@ impl AstDebug for UnannotatedExp_ { w.write(")"); } E::Pack(s, tys, fields) => { - w.write(&format!("{}", s)); + w.write(format!("{}", s)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (f, bt, e)| { - w.annotate(|w| w.write(&format!("{}", f)), bt); + w.annotate(|w| w.write(format!("{}", f)), bt); w.write(": "); e.ast_debug(w); }); w.write("}"); } E::PackVariant(e, v, tys, fields) => { - w.write(&format!("{}::{}", e, v)); + w.write(format!("{}::{}", e, v)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (f, bt, e)| { - w.annotate(|w| w.write(&format!("{}", f)), bt); + w.annotate(|w| w.write(format!("{}", f)), bt); w.write(": "); e.ast_debug(w); }); @@ -1553,7 +1613,7 @@ impl AstDebug for UnannotatedExp_ { w.write("mut "); } e.ast_debug(w); - w.write(&format!(".{}", f)); + w.write(format!(".{}", f)); } E::BorrowLocal(mut_, v) => { w.write("&"); @@ -1577,7 +1637,7 @@ impl AstDebug for UnannotatedExp_ { } => { w.write("ErrorConstant"); if let Some(c) = error_constant { - w.write(&format!("({})", c)) + w.write(format!("({})", c)) } } } @@ -1592,7 +1652,7 @@ impl AstDebug for ModuleCall { type_arguments, arguments, } = self; - w.write(&format!("{}::{}", module, name)); + w.write(format!("{}::{}", module, name)); w.write("<"); type_arguments.ast_debug(w); w.write(">"); @@ -1636,19 +1696,19 @@ impl AstDebug for LValue_ { ); } L::Unpack(s, tys, fields) => { - w.write(&format!("{}", s)); + w.write(format!("{}", s)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (f, l)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); l.ast_debug(w) }); w.write("}"); } L::UnpackVariant(e, v, unpack_type, _rhs_loc, tys, fields) => { - w.write(&format!("{}::{}", e, v)); + w.write(format!("{}::{}", e, v)); match unpack_type { UnpackType::ByMutRef => w.write(" &mut "), UnpackType::ByImmRef => w.write(" &"), @@ -1659,7 +1719,7 @@ impl AstDebug for LValue_ { w.write(">"); w.write("{"); w.comma(fields, |w, (f, l)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); l.ast_debug(w) }); w.write("}"); diff --git a/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs b/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs index 330be03837d..f0e323d4da9 100644 --- a/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs +++ b/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::{collections::VecDeque, iter::Peekable}; +use std::collections::{BTreeSet, VecDeque}; use move_ir_types::location::*; use move_proc_macros::growing_stack; @@ -10,6 +10,7 @@ use move_symbol_pool::Symbol; use crate::{ diag, + diagnostics::{Diagnostic, DiagnosticReporter, Diagnostics, warning_filters::WarningFilters}, expansion::ast::ModuleIdent, ice, naming::ast::{self as N, BlockLabel}, @@ -58,97 +59,243 @@ use crate::{ // Context //************************************************************************************************** -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -enum ControlFlow_ { - AlreadyReported, +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +enum ControlFlowEntry { AbortCalled, - Divergent, InfiniteLoop, - NamedBlockControlCalled(BlockLabel), // tracks the name + GiveCalled(BlockLabel), // tracks the name + ContinueCalled(BlockLabel), // tracks the name ReturnCalled, - UnreachableCode, } -type ControlFlow = Spanned; +type ControlFlowSet = BTreeSet; + +#[derive(Debug)] +enum ControlFlow { + None, + Possible, + Divergent { + loc: Loc, + set: ControlFlowSet, + reported: bool, + }, +} + +impl ControlFlow { + fn is_none(&self) -> bool { + match self { + ControlFlow::None => true, + ControlFlow::Divergent { .. } | ControlFlow::Possible => false, + } + } + + fn is_some(&self) -> bool { + match self { + ControlFlow::None => false, + ControlFlow::Divergent { .. } | ControlFlow::Possible => true, + } + } + + // Combinse control flows around branch arms: + // - If both are None, None + // - If both are Divergent, Divergent + // - If either is Possible, divergence is Possible + fn combine_arms(self, loc: Loc, other: Self) -> Self { + use ControlFlow as CF; + match self { + CF::None => match other { + CF::None => CF::None, + CF::Possible => CF::Possible, + CF::Divergent { .. } => CF::Possible, + }, + CF::Possible => CF::Possible, + CF::Divergent { + loc: _, + set: mut left, + reported: reported_left, + } => match other { + CF::None => CF::Possible, + CF::Possible => CF::Possible, + CF::Divergent { + loc: _, + set: mut right, + reported: reported_right, + } => { + left.append(&mut right); + CF::Divergent { + loc, + set: left, + reported: reported_left || reported_right, + } + } + }, + } + } + + // Combinse control flows around sequence entries (assuming `self` comes before + // `next`): + // - If `self` diverges, divergent. + // - If `self` is None, whatever `next` does. + // - If `self` is Possible, consider `next`: + // - `None` means divergence is Possible + // - `Divergent` means divergence is Divergence, combining sets. This code: + // ... if (cond) break 'a; break 'b; ... Produces Divergent({a, b}) + // divergence, + // - `Possible` means divergence is Possible, combining + fn combine_seq(self, next: Self) -> Self { + use ControlFlow as CF; + match self { + CF::Divergent { loc, set, reported } => CF::Divergent { loc, set, reported }, + CF::None => next, + CF::Possible => match next { + CF::None => CF::Possible, + CF::Divergent { .. } => CF::Possible, + CF::Possible => CF::Possible, + }, + } + } + + fn remove_label(mut self, label: &BlockLabel) -> Self { + use ControlFlow as CF; + match &mut self { + CF::None | CF::Possible => (), + CF::Divergent { + set, + reported: _, + loc: _, + } => { + set.remove(&ControlFlowEntry::GiveCalled(*label)); + set.remove(&ControlFlowEntry::ContinueCalled(*label)); + if set.is_empty() { + return CF::None; + } + } + }; + self + } + + fn is_divergent(&self) -> bool { + match self { + ControlFlow::Divergent { .. } => true, + ControlFlow::None | ControlFlow::Possible => false, + } + } +} struct Context<'env> { - env: &'env mut CompilationEnv, + #[allow(unused)] + env: &'env CompilationEnv, + reporter: DiagnosticReporter<'env>, + // loops: Vec, } impl<'env> Context<'env> { - pub fn new(env: &'env mut CompilationEnv) -> Self { - Context { env } + pub fn new(env: &'env CompilationEnv) -> Self { + // let loops = vec![]; + // Context { env , loops } + let reporter = env.diagnostic_reporter_at_top_level(); + Context { env, reporter } + } + + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); } - fn report_value_error(&mut self, sp!(site, error): ControlFlow) { - use ControlFlow_::*; + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + + fn maybe_report_value_error(&mut self, error: &mut ControlFlow) -> bool { + use ControlFlow as CF; match error { - AbortCalled | Divergent | InfiniteLoop | NamedBlockControlCalled(_) | ReturnCalled => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, VALUE_UNREACHABLE_MSG))); - } - UnreachableCode => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, NOT_EXECUTED_MSG))); + CF::Divergent { + loc, + set: _, + reported, + } if !*reported => { + *reported = true; + self.add_diag(diag!(UnusedItem::DeadCode, (*loc, VALUE_UNREACHABLE_MSG))); + true } - _ => (), + CF::Divergent { .. } | CF::None | CF::Possible => false, } } - fn report_tail_error(&mut self, sp!(site, error): ControlFlow) { - use ControlFlow_::*; + fn maybe_report_tail_error(&mut self, error: &mut ControlFlow) -> bool { + use ControlFlow as CF; match error { - AbortCalled | InfiniteLoop => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, NOT_EXECUTED_MSG))); + CF::Divergent { + loc, + set: _, + reported, + } if !*reported => { + *reported = true; + self.add_diag(diag!(UnusedItem::DeadCode, (*loc, DIVERGENT_MSG))); + true } - UnreachableCode => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, NOT_EXECUTED_MSG))); - } - _ => (), + CF::Divergent { .. } | CF::None | CF::Possible => false, } } - fn report_statement_error(&mut self, sp!(site, error): ControlFlow) { - use ControlFlow_::*; + fn maybe_report_statement_error( + &mut self, + error: &mut ControlFlow, + next_stmt: Option<&Loc>, + ) -> bool { + use ControlFlow as CF; match error { - AbortCalled | Divergent | InfiniteLoop | ReturnCalled => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, UNREACHABLE_MSG))); - } - UnreachableCode => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, NOT_EXECUTED_MSG))); + CF::Divergent { + loc, + set: _, + reported, + } if !*reported => { + *reported = true; + let mut diag = diag!(UnusedItem::DeadCode, (*loc, DIVERGENT_MSG)); + if let Some(next_loc) = next_stmt { + diag.add_secondary_label((*next_loc, UNREACHABLE_MSG)); + } + self.add_diag(diag); + true } - _ => (), + CF::Divergent { .. } | CF::None | CF::Possible => false, } } - fn report_statement_tail_error(&mut self, sp!(site, error): ControlFlow, tail_exp: &T::Exp) { - use ControlFlow_::*; - match error { - AbortCalled | Divergent | InfiniteLoop | ReturnCalled | NamedBlockControlCalled(_) - if matches!(tail_exp.exp.value, T::UnannotatedExp_::Unit { .. }) => - { - self.env.add_diag(diag!( - UnusedItem::TrailingSemi, - (tail_exp.exp.loc, SEMI_MSG), - (site, UNREACHABLE_MSG), - (tail_exp.exp.loc, INFO_MSG), - )); - } - AbortCalled | Divergent | InfiniteLoop | ReturnCalled | NamedBlockControlCalled(_) => { - self.env.add_diag(diag!( - UnusedItem::DeadCode, - (tail_exp.exp.loc, NOT_EXECUTED_MSG) - )); - } - UnreachableCode => { - self.env - .add_diag(diag!(UnusedItem::DeadCode, (site, NOT_EXECUTED_MSG))); + fn maybe_report_statement_tail_error( + &mut self, + error: &mut ControlFlow, + tail_exp: &T::Exp, + ) -> bool { + use ControlFlow as CF; + if matches!(tail_exp.exp.value, T::UnannotatedExp_::Unit { .. }) { + match error { + CF::Divergent { + loc, + set: _, + reported, + } if !*reported => { + *reported = true; + self.add_diag(diag!( + UnusedItem::TrailingSemi, + (tail_exp.exp.loc, SEMI_MSG), + (*loc, DIVERGENT_MSG), + (tail_exp.exp.loc, INFO_MSG), + )); + true + } + CF::Divergent { .. } | CF::None | CF::Possible => false, } - _ => (), + } else { + self.maybe_report_statement_error(error, Some(&tail_exp.exp.loc)) } } } @@ -156,56 +303,60 @@ impl<'env> Context<'env> { const VALUE_UNREACHABLE_MSG: &str = "Expected a value. Any code surrounding or after this expression will not be reached"; -const UNREACHABLE_MSG: &str = "Any code after this expression will not be reached"; +const DIVERGENT_MSG: &str = "Any code after this expression will not be reached"; -const NOT_EXECUTED_MSG: &str = +const UNREACHABLE_MSG: &str = "Unreachable code. This statement (and any following statements) will not be executed."; const SEMI_MSG: &str = "Invalid trailing ';'"; const INFO_MSG: &str = "A trailing ';' in an expression block implicitly adds a '()' value after the semicolon. \ That '()' value will not be reachable"; -fn exits_named_block(name: BlockLabel, cf: Option) -> bool { - match cf { - Some(sp!(_, ControlFlow_::NamedBlockControlCalled(break_name))) => name == break_name, - _ => false, +fn return_called(loc: Loc) -> ControlFlow { + ControlFlow::Divergent { + loc, + set: BTreeSet::from([ControlFlowEntry::ReturnCalled]), + reported: false, } } -fn already_reported(loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::AlreadyReported)) -} - -fn abort_called(loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::AbortCalled)) -} - -// catch all for when we have to combine failures -fn divergent(loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::Divergent)) -} - -fn infinite_loop(loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::InfiniteLoop)) +fn abort_called(loc: Loc) -> ControlFlow { + ControlFlow::Divergent { + loc, + set: BTreeSet::from([ControlFlowEntry::AbortCalled]), + reported: false, + } } -fn named_control_called(loop_name: BlockLabel, loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::NamedBlockControlCalled(loop_name))) +fn give_called(loc: Loc, label: BlockLabel) -> ControlFlow { + ControlFlow::Divergent { + loc, + set: BTreeSet::from([ControlFlowEntry::GiveCalled(label)]), + reported: false, + } } -fn return_called(loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::ReturnCalled)) +fn continue_called(loc: Loc, label: BlockLabel) -> ControlFlow { + ControlFlow::Divergent { + loc, + set: BTreeSet::from([ControlFlowEntry::ContinueCalled(label)]), + reported: false, + } } -fn unreachable_code(loc: Loc) -> Option { - Some(sp(loc, ControlFlow_::UnreachableCode)) +fn infinite_loop(loc: Loc) -> ControlFlow { + ControlFlow::Divergent { + loc, + set: BTreeSet::from([ControlFlowEntry::InfiniteLoop]), + reported: false, + } } //************************************************************************************************** // Entry //************************************************************************************************** -pub fn program(compilation_env: &mut CompilationEnv, prog: &T::Program) { +pub fn program(compilation_env: &CompilationEnv, prog: &T::Program) { let mut context = Context::new(compilation_env); modules(&mut context, &prog.modules); } @@ -217,16 +368,14 @@ fn modules(context: &mut Context, modules: &UniqueMap) { } #[growing_stack] -fn tail(context: &mut Context, e: &T::Exp) -> Option { +fn tail(context: &mut Context, e: &T::Exp) -> ControlFlow { + use ControlFlow as CF; use T::UnannotatedExp_ as E; let T::Exp { - ty, - exp: sp!(eloc, e_), + exp: sp!(eloc, e_), .. } = e; match e_ { // ----------------------------------------------------------------------------------------- // control flow statements // ----------------------------------------------------------------------------------------- - E::IfElse(test, conseq, alt) => { - if let Some(test_control_flow) = value(context, test) { - context.report_value_error(test_control_flow); - return None; - }; - let conseq_flow = tail(context, conseq); - let alt_flow = tail(context, alt); - match (conseq_flow, alt_flow) { - _ if matches!(ty, sp!(_, N::Type_::Unit)) => None, - (Some(cflow), Some(aflow)) => { - if cflow.value == aflow.value { - context.report_tail_error(sp(*eloc, cflow.value)); - } else { - context.report_tail_error(cflow); - context.report_tail_error(aflow); - } - None - } - _ => None, - } - } - E::Match(subject, arms) => { - if let Some(test_control_flow) = value(context, subject) { - context.report_value_error(test_control_flow); - return None; - }; - let arm_somes = arms - .value - .iter() - .map(|sp!(_, arm)| { - arm.guard - .as_ref() - .and_then(|guard| value(context, guard)) - .iter() - .for_each(|flow| context.report_value_error(*flow)); - tail(context, &arm.rhs) - }) - .collect::>(); - if arm_somes.iter().all(|arm_opt| arm_opt.is_some()) { - for arm_opt in arm_somes { - let sp!(aloc, arm_error) = arm_opt.unwrap(); - context.report_tail_error(sp(aloc, arm_error)) - } - } - None - } + E::IfElse(test, conseq, alt_opt) => do_if( + context, + (eloc, test, conseq, alt_opt.as_deref()), + // tail_pos + true, + tail, + |context, flow| context.maybe_report_tail_error(flow), + ), + E::Match(subject, arms) => do_match( + context, + (subject, arms), + // tail_pos + true, + tail, + |context, flow| context.maybe_report_tail_error(flow), + ), E::VariantMatch(..) => { - context - .env - .add_diag(ice!((*eloc, "Found variant match in detect_dead_code"))); - None + context.add_diag(ice!((*eloc, "Found variant match in detect_dead_code"))); + CF::None } - // Whiles and loops Loops are currently moved to statement position - E::While(_, _, _) | E::Loop { .. } => statement(context, e), + // Whiles Loops are treated as statements because they cannot produce values. + E::While(_, _, _) => statement(context, e), + + // Normal loops are treated as statements. This allows people to write infinite loops in + // tail positions without error. This is because if it occurs in tail position, we assume + // it is intentionally infinite. It is, after all not causing any dead code. + E::Loop { .. } => statement(context, e), + E::NamedBlock(name, (_, seq)) => { // a named block in tail position checks for bad semicolons plus if the body // exits that block; if so, at least some of that code is live. - let body_result = tail_block(context, seq); - if exits_named_block(*name, body_result) { - None - } else { - body_result - } + let body_flow = tail_block(context, seq); + body_flow.remove_label(name) } E::Block((_, seq)) => tail_block(context, seq), @@ -369,7 +486,7 @@ fn tail(context: &mut Context, e: &T::Exp) -> Option { // statements // ----------------------------------------------------------------------------------------- E::Return(_) | E::Abort(_) | E::Give(_, _) | E::Continue(_) => value(context, e), - E::Assign(_, _, _) | E::Mutate(_, _) => None, + E::Assign(_, _, _) | E::Mutate(_, _) => CF::None, // ----------------------------------------------------------------------------------------- // value-like expression @@ -378,30 +495,35 @@ fn tail(context: &mut Context, e: &T::Exp) -> Option { } } -fn tail_block(context: &mut Context, seq: &VecDeque) -> Option { +fn tail_block(context: &mut Context, seq: &VecDeque) -> ControlFlow { use T::SequenceItem_ as S; let last_exp = seq.iter().last(); - let stmt_flow = statement_block( + let mut stmt_flow = statement_block( context, seq, // stmt_pos false, // skip_last true, ); - if let (Some(control_flow), Some(sp!(_, S::Seq(last)))) = (stmt_flow, last_exp) { - context.report_statement_tail_error(control_flow, last); - None - } else if let Some(control_flow) = stmt_flow { - context.report_tail_error(control_flow); - None + if stmt_flow.is_some() { + // If we have statement flow and a final expression, we might have an + // unnecessary semicolon if `last` is just a unit value. Let's check for + // that. + if let Some(sp!(_, S::Seq(last))) = last_exp { + context.maybe_report_statement_tail_error(&mut stmt_flow, last); + stmt_flow + } else { + context.maybe_report_tail_error(&mut stmt_flow); + stmt_flow + } } else { match last_exp { - None => None, + None => ControlFlow::None, Some(sp!(_, S::Seq(last))) => tail(context, last), Some(sp!(loc, _)) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( *loc, "ICE last sequence item should have been an exp in dead code analysis" ))); - None + ControlFlow::None } } } @@ -412,7 +534,8 @@ fn tail_block(context: &mut Context, seq: &VecDeque) -> Option< // ------------------------------------------------------------------------------------------------- #[growing_stack] -fn value(context: &mut Context, e: &T::Exp) -> Option { +fn value(context: &mut Context, e: &T::Exp) -> ControlFlow { + use ControlFlow as CF; use T::UnannotatedExp_ as E; let T::Exp { @@ -421,12 +544,11 @@ fn value(context: &mut Context, e: &T::Exp) -> Option { macro_rules! value_report { ($nested_value:expr) => {{ - if let Some(control_flow) = value(context, $nested_value) { - context.report_value_error(control_flow); - already_reported(*eloc) - } else { - None + let mut value_flow = value(context, $nested_value); + if context.maybe_report_value_error(&mut value_flow) { + return value_flow; } + value_flow }}; } @@ -434,63 +556,50 @@ fn value(context: &mut Context, e: &T::Exp) -> Option { // ----------------------------------------------------------------------------------------- // control flow statements // ----------------------------------------------------------------------------------------- - E::IfElse(test, conseq, alt) => { - if let Some(test_control_flow) = value(context, test) { - context.report_value_error(test_control_flow); - return already_reported(*eloc); - }; - if let (Some(cflow), Some(aflow)) = (value(context, conseq), value(context, alt)) { - if cflow.value == aflow.value { - context.report_value_error(sp(*eloc, cflow.value)); - } else { - context.report_value_error(cflow); - context.report_value_error(aflow); - } - return already_reported(*eloc); - } - None + E::IfElse(test, conseq, alt) => do_if( + context, + (eloc, test, conseq, alt.as_deref()), + // tail_pos + false, + value, + |context, flow| context.maybe_report_value_error(flow), + ), + E::Match(subject, arms) => do_match( + context, + (subject, arms), + // tail_pos + false, + value, + |context, flow| context.maybe_report_value_error(flow), + ), + E::VariantMatch(_subject, _, _arms) => { + context.add_diag(ice!((*eloc, "Found variant match in detect_dead_code"))); + CF::None } - E::Match(subject, arms) => { - if let Some(test_control_flow) = value(context, subject) { - context.report_value_error(test_control_flow); - return None; + E::While(..) => statement(context, e), + E::Loop { + name, + body, + has_break: _, + } => { + // A loop can yield values, but only through `break`. We treat the body as a + // statement, but then consider if it ever breaks out. If it does + // not, this is an infinite loop. + let body_flow = statement(context, body); + let loop_flow = if body_flow.is_none() { + let mut new_flow = infinite_loop(*eloc); + context.maybe_report_value_error(&mut new_flow); + new_flow + } else { + body_flow }; - let arm_somes = arms - .value - .iter() - .map(|sp!(_, arm)| { - arm.guard - .as_ref() - .and_then(|guard| value(context, guard)) - .iter() - .for_each(|flow| context.report_value_error(*flow)); - value(context, &arm.rhs) - }) - .collect::>(); - if arm_somes.iter().all(|arm_opt| arm_opt.is_some()) { - for arm_opt in arm_somes { - let sp!(aloc, arm_error) = arm_opt.unwrap(); - context.report_value_error(sp(aloc, arm_error)) - } - } - None - } - E::VariantMatch(_subject, _, _arms) => { - context - .env - .add_diag(ice!((*eloc, "Found variant match in detect_dead_code"))); - None + loop_flow.remove_label(name) } - E::While(..) | E::Loop { .. } => statement(context, e), E::NamedBlock(name, (_, seq)) => { - // a named block in value position checks if the body exits that block; if so, - // at least some of that code is live. - let body_result = value_block(context, seq); - if exits_named_block(*name, body_result) { - None - } else { - body_result - } + // a named block checks for bad semicolons plus if the body exits that + // block; if so, at least some of that code is live. + let body_flow = value_block(context, seq); + body_flow.remove_label(name) } E::Block((_, seq)) => value_block(context, seq), @@ -501,48 +610,44 @@ fn value(context: &mut Context, e: &T::Exp) -> Option { E::Builtin(_, args) | E::Vector(_, _, _, args) => value_report!(args), - E::Pack(_, _, _, fields) => fields - .iter() - .find_map(|(_, _, (_, (_, field_exp)))| value_report!(field_exp)), - - E::PackVariant(_, _, _, _, fields) => fields - .iter() - .find_map(|(_, _, (_, (_, field_exp)))| value_report!(field_exp)), - - E::ExpList(_) => { - use T::UnannotatedExp_ as TE; - if let TE::ExpList(items) = &e.exp.value { - for item in items { - match item { - T::ExpListItem::Single(exp, _) => { - let next = value_report!(exp); - if next.is_some() { - return next; - } - } - T::ExpListItem::Splat(_, _, _) => { - context.env.add_diag(ice!(( - *eloc, - "ICE splat exp unsupported by dead code analysis" - ))); - return None; - } + E::Pack(_, _, _, fields) | E::PackVariant(_, _, _, _, fields) => { + let mut flow = CF::None; + for (_, _, (_, (_, field_exp))) in fields { + let field_flow = value(context, field_exp); + flow = flow.combine_seq(field_flow); + context.maybe_report_value_error(&mut flow); + } + flow + } + + E::ExpList(items) => { + let mut flow = CF::None; + for item in items { + match item { + T::ExpListItem::Single(exp, _) => { + let item_flow = value(context, exp); + flow = flow.combine_seq(item_flow); + context.maybe_report_value_error(&mut flow); + } + T::ExpListItem::Splat(_, _, _) => { + context.add_diag(ice!(( + *eloc, + "ICE splat exp unsupported by dead code analysis" + ))); } } - None - } else { - value_report!(e) } + flow } - E::Annotate(base_exp, _) - | E::Dereference(base_exp) + E::Annotate(base_exp, _) | E::Cast(base_exp, _) => value(context, base_exp), + + E::Dereference(base_exp) | E::UnaryExp(_, base_exp) | E::Borrow(_, base_exp, _) - | E::Cast(base_exp, _) | E::TempBorrow(_, base_exp) => value_report!(base_exp), - E::BorrowLocal(_, _) => None, + E::BorrowLocal(_, _) => CF::None, // ----------------------------------------------------------------------------------------- // value-based expressions without subexpressions -- no control flow @@ -552,50 +657,55 @@ fn value(context: &mut Context, e: &T::Exp) -> Option { | E::Constant(_, _) | E::Move { .. } | E::Copy { .. } - | E::ErrorConstant { .. } => None, + | E::ErrorConstant { .. } => CF::None, // ----------------------------------------------------------------------------------------- // statements // ----------------------------------------------------------------------------------------- - E::Return(rhs) => value_report!(rhs).or_else(|| return_called(*eloc)), - E::Abort(rhs) => value_report!(rhs).or_else(|| abort_called(*eloc)), - E::Give(name, rhs) => value_report!(rhs).or_else(|| named_control_called(*name, *eloc)), - E::Continue(name) => named_control_called(*name, *eloc), - E::Assign(_, _, _) | E::Mutate(_, _) => None, // These are unit-valued + E::Return(rhs) => value_report!(rhs).combine_seq(return_called(*eloc)), + E::Abort(rhs) => value_report!(rhs).combine_seq(abort_called(*eloc)), + E::Give(name, rhs) => value_report!(rhs).combine_seq(give_called(*eloc, *name)), + E::Continue(name) => continue_called(*eloc, *name), + E::Assign(_, _, _) | E::Mutate(_, _) => CF::None, // These are unit-valued E::BinopExp(_, _, _, _) => process_binops(context, e), // ----------------------------------------------------------------------------------------- // odds and ends // ----------------------------------------------------------------------------------------- - E::Use(_) | E::UnresolvedError => None, + E::Use(_) | E::UnresolvedError => CF::None, } } -fn value_block(context: &mut Context, seq: &VecDeque) -> Option { +fn value_block(context: &mut Context, seq: &VecDeque) -> ControlFlow { use T::SequenceItem_ as S; let last_exp = seq.iter().last(); - let stmt_flow = statement_block( + let mut stmt_flow = statement_block( context, seq, // stmt_pos false, // skip_last true, ); - if let (Some(control_flow), Some(sp!(_, S::Seq(last)))) = (stmt_flow, last_exp) { - context.report_statement_tail_error(control_flow, last); - already_reported(control_flow.loc) - } else if let Some(control_flow) = stmt_flow { - context.report_value_error(control_flow); - already_reported(control_flow.loc) + if stmt_flow.is_some() { + // If we have statement flow and a final expression, we might have an + // unnecessary semicolon if `last` is just a unit value. Let's check for + // that. + if let Some(sp!(_, S::Seq(last))) = last_exp { + context.maybe_report_statement_tail_error(&mut stmt_flow, last); + stmt_flow + } else { + context.maybe_report_value_error(&mut stmt_flow); + stmt_flow + } } else { match last_exp { - None => None, + None => ControlFlow::None, Some(sp!(_, S::Seq(last))) => value(context, last), Some(sp!(loc, _)) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( *loc, "ICE last sequence item should have been an exp in dead code analysis" ))); - None + ControlFlow::None } } } @@ -606,139 +716,105 @@ fn value_block(context: &mut Context, seq: &VecDeque) -> Option // ------------------------------------------------------------------------------------------------- #[growing_stack] -fn statement(context: &mut Context, e: &T::Exp) -> Option { +fn statement(context: &mut Context, e: &T::Exp) -> ControlFlow { + use ControlFlow as CF; use T::UnannotatedExp_ as E; let T::Exp { exp: sp!(eloc, e_), .. } = e; + + macro_rules! value_report { + ($nested_value:expr) => {{ + let mut value_flow = value(context, $nested_value); + if context.maybe_report_value_error(&mut value_flow) { + return value_flow; + } + value_flow + }}; + } + match e_ { // ----------------------------------------------------------------------------------------- // control flow statements // ----------------------------------------------------------------------------------------- - E::IfElse(test, conseq, alt) => { - if let Some(test_control_flow) = value(context, test) { - context.report_value_error(test_control_flow); - statement(context, conseq); - statement(context, alt); - already_reported(*eloc) - } else { - // if the test was okay but the arms both diverged, we need to report that for - // the purpose of trailing semicolons. - match (statement(context, conseq), statement(context, alt)) { - (Some(_), Some(_)) => divergent(*eloc), - _ => None, - } - } - } - E::Match(subject, arms) => { - if let Some(test_control_flow) = value(context, subject) { - context.report_value_error(test_control_flow); - for sp!(_, arm) in arms.value.iter() { - arm.guard - .as_ref() - .and_then(|guard| value(context, guard)) - .iter() - .for_each(|flow| context.report_value_error(*flow)); - statement(context, &arm.rhs); - } - already_reported(*eloc) - } else { - // if the test was okay but all arms both diverged, we need to report that for the - // purpose of trailing semicolons. - let arm_somes = arms - .value - .iter() - .map(|sp!(_, arm)| statement(context, &arm.rhs)) - .collect::>(); - if arm_somes.iter().all(|arm_opt| arm_opt.is_some()) { - divergent(*eloc) - } else { - None - } - } - } + // For `if` and `match`, we don't care if the arms individually diverge since we only care + // about the final, total view of them. + E::IfElse(test, conseq, alt) => do_if( + context, + (eloc, test, conseq, alt.as_deref()), + // tail_pos + false, + statement, + |_, _| false, + ), + E::Match(subject, arms) => do_match( + context, + (subject, arms), + // tail_pos + false, + statement, + |_, _| false, + ), E::VariantMatch(_subject, _, _arms) => { - context - .env - .add_diag(ice!((*eloc, "Found variant match in detect_dead_code"))); - None + context.add_diag(ice!((*eloc, "Found variant match in detect_dead_code"))); + CF::None } - E::While(_, test, body) => { - if let Some(test_control_flow) = value(context, test) { - context.report_value_error(test_control_flow); - already_reported(*eloc) + E::While(name, test, body) => { + let mut test_flow = value(context, test); + if context.maybe_report_value_error(&mut test_flow) { + test_flow } else { - statement(context, body); - // we don't know if a while loop will ever run so we drop errors for the bodies. - None + // Since a body for a While loop is only Possible, not certain, we always force + // it into Possible. + let body_flow = statement(context, body).combine_arms(*eloc, CF::None); + let body_flow = body_flow.remove_label(name); + test_flow.combine_seq(body_flow) } } E::Loop { name, body, - has_break, + has_break: _, } => { - let body_result = statement(context, body); - if !has_break { + // A loop can yield values, but only through `break`. We treat the body as a + // statement, but then consider if it ever breaks out. If it does + // not, this is an infinite loop. + let body_flow = statement(context, body); + let loop_flow = if body_flow.is_none() { infinite_loop(*eloc) - } else if exits_named_block(*name, body_result) || *has_break { - // if the loop has a break, only Godel knows if it'll call it - None } else { - body_result - } + // Unlike values, for a loop in statement position we want to preserve if it + // diverges or not. + body_flow + }; + loop_flow.remove_label(name) } E::NamedBlock(name, (_, seq)) => { - // a named block in statement position checks if the body exits that block; if - // so, at least some of that code is live. - let body_result = value_block(context, seq); - if exits_named_block(*name, body_result) { - None - } else { - body_result - } + // a named block checks for bad semicolons plus if the body exits that + // block; if so, at least some of that code is live. + let body_flow = statement_block( + context, seq, // stmt_pos + true, // skip_last + false, + ); + body_flow.remove_label(name) } E::Block((_, seq)) => statement_block( context, seq, // stmt_pos true, // skip_last false, ), - E::Return(rhs) => { - if let Some(rhs_control_flow) = value(context, rhs) { - context.report_value_error(rhs_control_flow); - already_reported(*eloc) - } else { - return_called(*eloc) - } - } - E::Abort(rhs) => { - if let Some(rhs_control_flow) = value(context, rhs) { - context.report_value_error(rhs_control_flow); - already_reported(*eloc) - } else { - abort_called(*eloc) - } - } - E::Give(name, _) | E::Continue(name) => named_control_called(*name, *eloc), + E::Return(rhs) => value_report!(rhs).combine_seq(return_called(*eloc)), + E::Abort(rhs) => value_report!(rhs).combine_seq(abort_called(*eloc)), + E::Give(name, rhs) => value_report!(rhs).combine_seq(give_called(*eloc, *name)), + E::Continue(name) => continue_called(*eloc, *name), // ----------------------------------------------------------------------------------------- // statements with effects // ----------------------------------------------------------------------------------------- - E::Assign(_, _, rhs) => { - if let Some(rhs_control_flow) = value(context, rhs) { - context.report_value_error(rhs_control_flow); - } - None - } - E::Mutate(lhs, rhs) => { - if let Some(rhs_control_flow) = value(context, rhs) { - context.report_value_error(rhs_control_flow); - } else if let Some(lhs_control_flow) = value(context, lhs) { - context.report_value_error(lhs_control_flow); - } - None - } + E::Assign(_, _, rhs) => value_report!(rhs), + E::Mutate(lhs, rhs) => value_report!(rhs).combine_seq(value_report!(lhs)), // ----------------------------------------------------------------------------------------- // valued expressions -- when these occur in statement position need their children @@ -764,16 +840,14 @@ fn statement(context: &mut Context, e: &T::Exp) -> Option { | E::Copy { .. } | E::UnresolvedError => value(context, e), - E::Value(_) | E::Unit { .. } => None, + E::Value(_) | E::Unit { .. } => CF::None, // ----------------------------------------------------------------------------------------- // odds and ends -- things we need to deal with but that don't do much // ----------------------------------------------------------------------------------------- E::Use(_) => { - context - .env - .add_diag(ice!((*eloc, "ICE found unexpanded use"))); - None + context.add_diag(ice!((*eloc, "ICE found unexpanded use"))); + CF::None } } } @@ -783,81 +857,68 @@ fn statement_block( seq: &VecDeque, stmt_pos: bool, skip_last: bool, -) -> Option { +) -> ControlFlow { + use ControlFlow as CF; use T::SequenceItem_ as S; + let seq_has_trailing_unit = has_trailing_unit(seq); // if we're in statement position, we need to check for a trailing semicolon // error this code does that by noting a trialing unit and then proceeding // as if we are not in statement position. - if stmt_pos && has_trailing_unit(seq) { + if stmt_pos && seq_has_trailing_unit { let last = seq.iter().last(); - let result = statement_block( + let mut control_flow = statement_block( context, seq, // stmt_pos false, // skip_last true, ); - return if let (Some(control_flow), Some(sp!(_, S::Seq(entry)))) = (result, last) { - context.report_statement_tail_error(control_flow, entry); - None - } else { - None - }; + if let Some(sp!(_, S::Seq(entry))) = last { + context.maybe_report_statement_tail_error(&mut control_flow, entry); + } + return control_flow; } - let iterator = if skip_last { - seq.iter().skip_last().enumerate().collect::>() - } else { - seq.iter().enumerate().collect::>() - }; - let last_ndx = usize::saturating_sub(iterator.len(), 1); - let locs: Vec<_> = iterator.iter().map(|(_, s)| s.loc).collect(); - - for (ndx, sp!(_, seq_item)) in iterator { - match seq_item { - S::Seq(entry) if ndx == last_ndx => { - // If this is the last statement, the error may indicate a trailing semicolon - // error. Return it to whoever is expecting it so they can report it - // appropriately. - return statement(context, entry); - } - S::Seq(entry) => { - let entry_result = statement(context, entry); - if entry_result.is_some() { - context.report_statement_error(unreachable_code(locs[ndx + 1]).unwrap()); - return None; + // let iterator = if skip_last { + // seq.iter().skip_last().enumerate().collect::>() + // } else { + // seq.iter().enumerate().collect::>() + // }; + let last_ndx = usize::saturating_sub(seq.len(), 1); + let locs: Vec<_> = seq.iter().map(|s| s.loc).collect(); + + let mut cur_flow = CF::None; + for (ndx, sp!(_, seq_item)) in seq.iter().enumerate() { + if cur_flow.is_divergent() { + break; + } else if ndx == last_ndx && skip_last { + } else { + match seq_item { + S::Seq(entry) => { + let entry_flow = statement(context, entry); + cur_flow = cur_flow.combine_seq(entry_flow); + if cur_flow.is_divergent() + && ndx != last_ndx + && !(ndx + 1 == last_ndx && seq_has_trailing_unit) + { + context.maybe_report_statement_error(&mut cur_flow, Some(&locs[ndx + 1])); + } } - } - S::Declare(_) => (), - S::Bind(_, _, expr) => { - if let Some(control_flow) = value(context, expr) { - context.report_value_error(control_flow); - return None; + S::Declare(_) => (), + S::Bind(_, _, rhs) => { + let entry_flow = value(context, rhs); + cur_flow = cur_flow.combine_seq(entry_flow); + context.maybe_report_value_error(&mut cur_flow); } } } } - None + cur_flow } // ------------------------------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------------------------------- -struct SkipLastIterator(Peekable); -impl Iterator for SkipLastIterator { - type Item = I::Item; - fn next(&mut self) -> Option { - let item = self.0.next(); - self.0.peek().map(|_| item.unwrap()) - } -} -trait SkipLast: Iterator + Sized { - fn skip_last(self) -> SkipLastIterator { - SkipLastIterator(self.peekable()) - } -} -impl SkipLast for I {} - fn has_trailing_unit(seq: &VecDeque) -> bool { use T::SequenceItem_ as S; if let Some(sp!(_, S::Seq(exp))) = &seq.back() { @@ -867,68 +928,140 @@ fn has_trailing_unit(seq: &VecDeque) -> bool { } } +fn do_if( + context: &mut Context, + (loc, test, conseq, alt_opt): (&Loc, &T::Exp, &T::Exp, Option<&T::Exp>), + tail_pos: bool, + arm_recur: F1, + arm_error: F2, +) -> ControlFlow +where + F1: Fn(&mut Context, &T::Exp) -> ControlFlow, + F2: Fn(&mut Context, &mut ControlFlow) -> bool, +{ + use ControlFlow as CF; + let mut value_flow = value(context, test); + if context.maybe_report_value_error(&mut value_flow) { + return value_flow; + }; + + let conseq_flow = arm_recur(context, conseq); + let alt_flow = alt_opt + .map(|alt| arm_recur(context, alt)) + .unwrap_or(CF::None); + if tail_pos + && matches!(conseq.ty, sp!(_, N::Type_::Unit | N::Type_::Anything)) + && matches!( + alt_opt.map(|alt| &alt.ty), + None | Some(sp!(_, N::Type_::Unit | N::Type_::Anything)) + ) + { + return CF::None; + }; + let mut arms_flow = conseq_flow.combine_arms(*loc, alt_flow); + if arm_error(context, &mut arms_flow) { + arms_flow + } else { + value_flow.combine_seq(arms_flow) + } +} + +fn do_match( + context: &mut Context, + (subject, arms): (&T::Exp, &Spanned>), + tail_pos: bool, + arm_recur: F1, + arm_error: F2, +) -> ControlFlow +where + F1: Fn(&mut Context, &T::Exp) -> ControlFlow, + F2: Fn(&mut Context, &mut ControlFlow) -> bool, +{ + use ControlFlow as CF; + let mut subject_flow = value(context, subject); + if context.maybe_report_value_error(&mut subject_flow) { + return subject_flow; + }; + + let mut arm_flows = arms + .value + .iter() + .map(|sp!(_, arm)| { + if let Some(guard) = &arm.guard { + let mut guard_flow = value(context, guard); + context.maybe_report_value_error(&mut guard_flow); + }; + arm_recur(context, &arm.rhs) + }) + .collect::>(); + if tail_pos + && arms.value.iter().all(|arm| { + matches!( + arm.value.rhs.ty, + sp!(_, N::Type_::Unit | N::Type_::Anything) + ) + }) + { + return CF::None; + }; + // We _must_ have at least one arm, but we already produced errors about it. + let arms_first = if let Some(arm) = arm_flows.pop() { + arm + } else { + CF::None + }; + let mut arms_flow = arm_flows + .into_iter() + .fold(arms_first, |base, arm| base.combine_arms(arms.loc, arm)); + if arm_error(context, &mut arms_flow) { + arms_flow + } else { + subject_flow.combine_seq(arms_flow) + } +} + //************************************************************************************************** // Binops //************************************************************************************************** -fn process_binops(context: &mut Context, e: &T::Exp) -> Option { +fn process_binops(context: &mut Context, e: &T::Exp) -> ControlFlow { use T::UnannotatedExp_ as E; - enum Pn { - Op(BinOp_, Loc), - Val(Option), - } - // ---------------------------------------- // Convert nested binops into a PN list - let mut pn_stack = vec![]; - let mut work_queue = vec![e]; + let mut value_stack: Vec = vec![]; while let Some(exp) = work_queue.pop() { if let T::Exp { - exp: sp!(eloc, E::BinopExp(lhs, sp!(_, op), _, rhs)), + exp: sp!(_eloc, E::BinopExp(lhs, sp!(_, op), _, rhs)), .. } = exp { - pn_stack.push(Pn::Op(*op, *eloc)); - // push on backwards so when we reverse the stack, we are in RPN order - work_queue.push(rhs); - work_queue.push(lhs); + match op { + BinOp_::Or | BinOp_::And => { + // We only care about errors in the left-hand side due to laziness + work_queue.push(lhs); + } + _ => { + work_queue.push(rhs); + work_queue.push(lhs); + } + } } else { - pn_stack.push(Pn::Val(value(context, exp))); + value_stack.push(value(context, exp)); } } // ---------------------------------------- // Now process as an RPN stack - let mut value_stack: Vec> = vec![]; - - for entry in pn_stack.into_iter().rev() { - match entry { - Pn::Op(BinOp_::And, _) | Pn::Op(BinOp_::Or, _) => { - let test = value_stack.pop().expect("ICE binop hlir issue"); - let _rhs = value_stack.pop().expect("ICE binop hlir issue"); - // we only care about errors in the test, as the rhs is lazy - value_stack.push(test); - } - Pn::Op(_, eloc) => { - let lhs = value_stack.pop().expect("ICE binop hlir issue"); - let rhs = value_stack.pop().expect("ICE binop hlir issue"); - if let Some(control_flow) = lhs { - context.report_value_error(control_flow); - value_stack.push(already_reported(eloc)); - } else if let Some(control_flow) = rhs { - context.report_value_error(control_flow); - value_stack.push(already_reported(eloc)); - } else { - value_stack.push(lhs); - } - } - Pn::Val(maybe_control_flow) => value_stack.push(maybe_control_flow), + while let Some(mut flow) = value_stack.pop() { + if flow.is_divergent() { + context.maybe_report_value_error(&mut flow); + return flow; } } - value_stack.pop().unwrap() + ControlFlow::None } diff --git a/external-crates/move/crates/move-compiler/src/hlir/match_compilation.rs b/external-crates/move/crates/move-compiler/src/hlir/match_compilation.rs index 786b8716559..c318a2b6a08 100644 --- a/external-crates/move/crates/move-compiler/src/hlir/match_compilation.rs +++ b/external-crates/move/crates/move-compiler/src/hlir/match_compilation.rs @@ -2,6 +2,11 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use std::collections::{BTreeMap, BTreeSet, VecDeque}; + +use move_ir_types::location::*; +use move_proc_macros::growing_stack; + use crate::{ expansion::ast::{Fields, ModuleIdent, Mutability, Value, Value_}, hlir::translate::Context, @@ -16,70 +21,41 @@ use crate::{ }, typing::ast::{self as T, MatchPattern, UnannotatedPat_ as TP}, }; -use move_ir_types::location::*; -use move_proc_macros::growing_stack; -use std::collections::{BTreeMap, BTreeSet, VecDeque}; //************************************************************************************************** // Match Compilation //************************************************************************************************** -// This mostly follows the classical Maranget (2008) implementation toward optimal decision trees. - -type Fringe = VecDeque; +// This mostly follows the classical Maranget (2008) implementation toward +// optimal decision trees. -#[derive(Clone)] +#[derive(Debug, Clone)] enum StructUnpack { Default(T), Unpack(Vec<(Field, Var, Type)>, T), } -enum MatchStep { +#[derive(Debug, Clone)] +enum MatchTree { Leaf(Vec), Failure, LiteralSwitch { subject: FringeEntry, subject_binders: Vec<(Mutability, Var)>, - fringe: Fringe, - arms: BTreeMap, - default: PatternMatrix, + arms: BTreeMap>, + default: Box, // default }, StructUnpack { subject: FringeEntry, subject_binders: Vec<(Mutability, Var)>, tyargs: Vec, - unpack: StructUnpack<(Fringe, PatternMatrix)>, + unpack: StructUnpack>, }, VariantSwitch { subject: FringeEntry, subject_binders: Vec<(Mutability, Var)>, tyargs: Vec, - arms: BTreeMap, Fringe, PatternMatrix)>, - default: (Fringe, PatternMatrix), - }, -} - -#[derive(Clone)] -enum WorkResult { - Leaf(Vec), - Failure, - LiteralSwitch { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - arms: BTreeMap, - default: usize, // default - }, - StructUnpack { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - tyargs: Vec, - unpack: StructUnpack, - }, - VariantSwitch { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - tyargs: Vec, - arms: BTreeMap, usize)>, - default: usize, + arms: BTreeMap, Box)>, + default: Box, }, } @@ -93,169 +69,21 @@ pub(super) fn compile_match( // NB: `from` also flattens `or` and converts constants into guards. let (pattern_matrix, arms) = PatternMatrix::from(context, loc, subject.ty.clone(), arms.value); - let mut compilation_results: BTreeMap = BTreeMap::new(); - - let (mut initial_binders, init_subject, match_subject) = { - let subject_var = context.new_match_var("unpack_subject".to_string(), loc); - let subject_loc = subject.exp.loc; - let match_var = context.new_match_var("match_subject".to_string(), loc); - - let subject_entry = FringeEntry { - var: subject_var, - ty: subject.ty.clone(), - }; - let subject_borrow_rhs = make_var_ref(subject_entry.clone()); - - let match_entry = FringeEntry { - var: match_var, - ty: subject_borrow_rhs.ty.clone(), - }; - - let subject_binder = { - let lhs_loc = subject_loc; - let lhs_lvalue = make_lvalue(subject_var, Mutability::Imm, subject.ty.clone()); - let binder = T::SequenceItem_::Bind( - sp(lhs_loc, vec![lhs_lvalue]), - vec![Some(subject.ty.clone())], - Box::new(subject), - ); - sp(lhs_loc, binder) - }; - - let subject_borrow = { - let lhs_loc = loc; - let lhs_lvalue = make_lvalue(match_var, Mutability::Imm, subject_borrow_rhs.ty.clone()); - let binder = T::SequenceItem_::Bind( - sp(lhs_loc, vec![lhs_lvalue]), - vec![Some(subject_borrow_rhs.ty.clone())], - subject_borrow_rhs, - ); - sp(lhs_loc, binder) - }; - - ( - VecDeque::from([subject_binder, subject_borrow]), - subject_entry, - match_entry, - ) - }; - - let mut work_queue: Vec<(usize, Fringe, PatternMatrix)> = - vec![(0, VecDeque::from([match_subject]), pattern_matrix)]; - - let mut work_id = 0; + let (mut initial_binders, init_subject, match_subject) = + make_initial_fringe(context, subject, loc); - let mut next_id = || { - work_id += 1; - work_id - }; - - while let Some((cur_id, init_fringe, matrix)) = work_queue.pop() { - debug_print!( - context.debug.match_work_queue, - ("work queue entry" => cur_id; fmt), - (lines "fringe" => &init_fringe; sdbg), - ("matrix" => matrix; verbose) - ); - let redefined: Option = - match compile_match_head(context, init_fringe.clone(), matrix) { - MatchStep::Leaf(leaf) => compilation_results.insert(cur_id, WorkResult::Leaf(leaf)), - MatchStep::Failure => compilation_results.insert(cur_id, WorkResult::Failure), - MatchStep::LiteralSwitch { - subject, - subject_binders, - fringe, - arms, - default, - } => { - let mut answer_map = BTreeMap::new(); - for (value, matrix) in arms { - let work_id = next_id(); - answer_map.insert(value, work_id); - work_queue.push((work_id, fringe.clone(), matrix)); - } - let default_work_id = next_id(); - work_queue.push((default_work_id, fringe, default)); - let result = WorkResult::LiteralSwitch { - subject, - subject_binders, - arms: answer_map, - default: default_work_id, - }; - compilation_results.insert(cur_id, result) - } - MatchStep::StructUnpack { - subject, - subject_binders, - tyargs, - unpack, - } => { - let unpack_work_id = next_id(); - let unpack = match unpack { - StructUnpack::Default((fringe, matrix)) => { - work_queue.push((unpack_work_id, fringe, matrix)); - StructUnpack::Default(unpack_work_id) - } - StructUnpack::Unpack(dtor_fields, (fringe, matrix)) => { - work_queue.push((unpack_work_id, fringe, matrix)); - StructUnpack::Unpack(dtor_fields, unpack_work_id) - } - }; - compilation_results.insert( - cur_id, - WorkResult::StructUnpack { - subject, - subject_binders, - tyargs, - unpack, - }, - ) - } - - MatchStep::VariantSwitch { - subject, - subject_binders, - tyargs, - arms, - default: (dfringe, dmatrix), - } => { - let mut answer_map = BTreeMap::new(); - for (name, (dtor_fields, fringe, matrix)) in arms { - let work_id = next_id(); - answer_map.insert(name, (dtor_fields, work_id)); - work_queue.push((work_id, fringe, matrix)); - } - let default_work_id = next_id(); - work_queue.push((default_work_id, dfringe, dmatrix)); - compilation_results.insert( - cur_id, - WorkResult::VariantSwitch { - subject, - subject_binders, - tyargs, - arms: answer_map, - default: default_work_id, - }, - ) - } - }; - ice_assert!( - context.env, - redefined.is_none(), - loc, - "Match work queue went awry" - ); - } - - let match_start = compilation_results.remove(&0).unwrap(); + let match_tree = build_match_tree(context, VecDeque::from([match_subject]), pattern_matrix); + debug_print!( + context.debug.match_translation, + ("match tree" => match_tree; sdbg) + ); let mut resolution_context = ResolutionContext { hlir_context: context, output_type: result_type, arms: &arms, arms_loc: loc, - results: &mut compilation_results, }; - let match_exp = resolve_result(&mut resolution_context, &init_subject, match_start); + let match_exp = match_tree_to_exp(&mut resolution_context, &init_subject, match_tree); let eloc = match_exp.exp.loc; let mut seq = VecDeque::new(); @@ -265,64 +93,88 @@ pub(super) fn compile_match( T::exp(result_type.clone(), exp_value) } -fn compile_match_head( +/// Makes the initial fringe, including the bindings, subject, and imm-ref +/// version of the subject for use in the actual decision tree. +fn make_initial_fringe( + context: &mut Context, + subject: T::Exp, + loc: Loc, +) -> (VecDeque, FringeEntry, FringeEntry) { + let subject_var = context.new_match_var("unpack_subject".to_string(), loc); + let subject_loc = subject.exp.loc; + let match_var = context.new_match_var("match_subject".to_string(), loc); + + let subject_entry = FringeEntry { + var: subject_var, + ty: subject.ty.clone(), + }; + let subject_borrow_rhs = make_var_ref(subject_entry.clone()); + + let match_entry = FringeEntry { + var: match_var, + ty: subject_borrow_rhs.ty.clone(), + }; + + let subject_binder = { + let lhs_loc = subject_loc; + let lhs_lvalue = make_lvalue(subject_var, Mutability::Imm, subject.ty.clone()); + let binder = T::SequenceItem_::Bind( + sp(lhs_loc, vec![lhs_lvalue]), + vec![Some(subject.ty.clone())], + Box::new(subject), + ); + sp(lhs_loc, binder) + }; + + let subject_borrow = { + let lhs_loc = loc; + let lhs_lvalue = make_lvalue(match_var, Mutability::Imm, subject_borrow_rhs.ty.clone()); + let binder = T::SequenceItem_::Bind( + sp(lhs_loc, vec![lhs_lvalue]), + vec![Some(subject_borrow_rhs.ty.clone())], + subject_borrow_rhs, + ); + sp(lhs_loc, binder) + }; + + ( + VecDeque::from([subject_binder, subject_borrow]), + subject_entry, + match_entry, + ) +} + +#[growing_stack] +fn build_match_tree( context: &mut Context, mut fringe: VecDeque, mut matrix: PatternMatrix, -) -> MatchStep { +) -> MatchTree { debug_print!( context.debug.match_specialization, ("-----\ncompiling with fringe queue entry" => fringe; sdbg) ); + if matrix.is_empty() { - MatchStep::Failure - } else if let Some(leaf) = matrix.wild_arm_opt(&fringe) { - MatchStep::Leaf(leaf) - } else if fringe[0].ty.value.unfold_to_builtin_type_name().is_some() { - let subject = fringe - .pop_front() - .expect("ICE empty fringe in match compilation"); - let mut subject_binders = vec![]; - // treat column as a literal - let list = matrix.first_list(); - let mut arms = BTreeMap::new(); - for lit in list { - let lit_loc = lit.loc; - debug_print!(context.debug.match_specialization, ("lit specializing" => lit ; fmt)); - let (mut new_binders, inner_matrix) = matrix.specialize_literal(&lit); - debug_print!( - context.debug.match_specialization, - ("binders" => &new_binders; dbg), ("specialized" => inner_matrix) - ); - subject_binders.append(&mut new_binders); - ice_assert!( - context.env, - arms.insert(lit, inner_matrix).is_none(), - lit_loc, - "Specialization failed" - ); - } - let (mut new_binders, default) = matrix.specialize_default(); - debug_print!(context.debug.match_specialization, ("default binders" => &new_binders; dbg)); - subject_binders.append(&mut new_binders); - MatchStep::LiteralSwitch { - subject, - subject_binders, - fringe, - arms, - default, - } + debug_print!(context.debug.match_specialization, (msg "empty matrix")); + return MatchTree::Failure; + } + + if let Some(leaf) = matrix.wild_tree_opt(&fringe) { + debug_print!(context.debug.match_specialization, (msg "wild leaf"), ("matrix" => matrix)); + return MatchTree::Leaf(leaf); + } + + let Some(subject) = fringe.pop_front() else { + debug_print!(context.debug.match_specialization, (msg "empty fringe")); + return MatchTree::Failure; + }; + + if subject.ty.value.unfold_to_builtin_type_name().is_some() { + compile_match_literal(context, subject, fringe, matrix) } else { - let subject = fringe - .pop_front() - .expect("ICE empty fringe in match compilation"); let tyargs = subject.ty.value.type_arguments().unwrap().clone(); - let mut subject_binders = vec![]; - debug_print!( - context.debug.match_specialization, - ("subject" => subject), - ("matrix" => matrix) - ); + let (mident, datatype_name) = subject .ty .value @@ -331,101 +183,171 @@ fn compile_match_head( .expect("ICE non-datatype type in head constructor fringe position"); if context.info.is_struct(&mident, &datatype_name) { - // If we have an actual destructuring anywhere, we do that and take the specialized - // matrix (which holds the default matrix and bindings, for our purpose). If we don't, - // we just take the default matrix. - let decl_fields = context.info.struct_fields(&mident, &datatype_name).unwrap(); - let unpack = if let Some((ploc, arg_types)) = matrix.first_struct_ctors() { - let fringe_binders = - context.make_imm_ref_match_binders(decl_fields, ploc, arg_types); - let fringe_exps = make_fringe_entries(&fringe_binders); - let mut inner_fringe = fringe.clone(); - for fringe_exp in fringe_exps.into_iter().rev() { - inner_fringe.push_front(fringe_exp); - } - let bind_tys = fringe_binders - .iter() - .map(|(_, _, ty)| ty) - .collect::>(); - debug_print!( - context.debug.match_specialization, ("struct specialized" => datatype_name; dbg) - ); - let (mut new_binders, inner_matrix) = matrix.specialize_struct(context, bind_tys); - debug_print!(context.debug.match_specialization, - ("binders" => new_binders; dbg), - ("specialized" => inner_matrix)); - subject_binders.append(&mut new_binders); - StructUnpack::Unpack(fringe_binders, (inner_fringe, inner_matrix)) - } else { - let (mut new_binders, default_matrix) = matrix.specialize_default(); - subject_binders.append(&mut new_binders); - StructUnpack::Default((fringe, default_matrix)) - }; - MatchStep::StructUnpack { + compile_match_struct( + context, subject, - subject_binders, tyargs, - unpack, - } + fringe, + matrix, + mident, + datatype_name, + ) } else { - let mut unmatched_variants = context - .info - .enum_variants(&mident, &datatype_name) - .into_iter() - .collect::>(); - - let ctors = matrix.first_variant_ctors(); - - let mut arms = BTreeMap::new(); - for (ctor, (ploc, arg_types)) in ctors { - unmatched_variants.remove(&ctor); - let decl_fields = context - .info - .enum_variant_fields(&mident, &datatype_name, &ctor) - .unwrap(); - let fringe_binders = - context.make_imm_ref_match_binders(decl_fields, ploc, arg_types); - let fringe_exps = make_fringe_entries(&fringe_binders); - let mut inner_fringe = fringe.clone(); - for fringe_exp in fringe_exps.into_iter().rev() { - inner_fringe.push_front(fringe_exp); - } - let bind_tys = fringe_binders - .iter() - .map(|(_, _, ty)| ty) - .collect::>(); - debug_print!( - context.debug.match_specialization, ("enum specialized" => datatype_name; dbg) - ); - let (mut new_binders, inner_matrix) = - matrix.specialize_variant(context, &ctor, bind_tys); - debug_print!(context.debug.match_specialization, - ("binders" => new_binders; dbg), - ("specialized" => inner_matrix)); - subject_binders.append(&mut new_binders); - ice_assert!( - context.env, - arms.insert(ctor, (fringe_binders, inner_fringe, inner_matrix)) - .is_none(), - ploc, - "Inserted duplicate ctor" - ); - } - - let (mut new_binders, default_matrix) = matrix.specialize_default(); - subject_binders.append(&mut new_binders); - - MatchStep::VariantSwitch { + compile_variant_switch( + context, subject, - subject_binders, tyargs, - arms, - default: (fringe, default_matrix), - } + fringe, + matrix, + mident, + datatype_name, + ) } } } +#[growing_stack] +fn compile_match_literal( + context: &mut Context, + subject: FringeEntry, + fringe: VecDeque, + matrix: PatternMatrix, +) -> MatchTree { + let mut subject_binders = vec![]; + let lits = matrix.first_list(); + let mut arms = BTreeMap::new(); + + for lit in lits { + debug_print!(context.debug.match_specialization, ("lit specializing" => lit ; fmt)); + let (mut new_binders, inner_matrix) = matrix.specialize_literal(&lit); + subject_binders.append(&mut new_binders); + arms.insert( + lit, + Box::new(build_match_tree(context, fringe.clone(), inner_matrix)), + ); + } + + let (mut new_binders, default) = matrix.specialize_default(); + subject_binders.append(&mut new_binders); + let default_result = Box::new(build_match_tree(context, fringe, default)); + + MatchTree::LiteralSwitch { + subject, + subject_binders, + arms, + default: default_result, + } +} + +#[growing_stack] +fn compile_match_struct( + context: &mut Context, + subject: FringeEntry, + tyargs: Vec, + fringe: VecDeque, + matrix: PatternMatrix, + mident: ModuleIdent, + datatype_name: DatatypeName, +) -> MatchTree { + let decl_fields = context.info.struct_fields(&mident, &datatype_name).unwrap(); + let (subject_binders, unpack) = if let Some((ploc, arg_types)) = matrix.first_struct_ctors() { + let fringe_binders = context.make_imm_ref_match_binders(decl_fields, ploc, arg_types); + let fringe_exps = make_fringe_entries(&fringe_binders); + let inner_fringe = fringe_exps.into_iter().chain(fringe.clone()).collect(); + + let bind_tys = fringe_binders + .iter() + .map(|(_, _, ty)| ty) + .collect::>(); + let (subject_binders, inner_matrix) = matrix.specialize_struct(context, bind_tys); + + let unpack = StructUnpack::Unpack( + fringe_binders, + Box::new(build_match_tree(context, inner_fringe, inner_matrix)), + ); + (subject_binders, unpack) + } else { + let (subject_binders, default_matrix) = matrix.specialize_default(); + let unpack = + StructUnpack::Default(Box::new(build_match_tree(context, fringe, default_matrix))); + (subject_binders, unpack) + }; + + MatchTree::StructUnpack { + subject, + subject_binders, + tyargs, + unpack, + } +} + +#[growing_stack] +fn compile_variant_switch( + context: &mut Context, + subject: FringeEntry, + tyargs: Vec, + fringe: VecDeque, + matrix: PatternMatrix, + mident: ModuleIdent, + datatype_name: DatatypeName, +) -> MatchTree { + let mut subject_binders = vec![]; + let mut unmatched_variants = context + .info + .enum_variants(&mident, &datatype_name) + .into_iter() + .collect::>(); + + let ctors = matrix.first_variant_ctors(); + let mut arms = BTreeMap::new(); + + for (ctor, (ploc, arg_types)) in ctors { + unmatched_variants.remove(&ctor); + let decl_fields = context + .info + .enum_variant_fields(&mident, &datatype_name, &ctor) + .unwrap(); + let fringe_binders = context.make_imm_ref_match_binders(decl_fields, ploc, arg_types); + let fringe_exps = make_fringe_entries(&fringe_binders); + let inner_fringe = fringe_exps.into_iter().chain(fringe.clone()).collect(); + + let bind_tys = fringe_binders + .iter() + .map(|(_, _, ty)| ty) + .collect::>(); + let (mut new_binders, inner_matrix) = matrix.specialize_variant(context, &ctor, bind_tys); + subject_binders.append(&mut new_binders); + + arms.insert( + ctor, + ( + fringe_binders, + Box::new(build_match_tree(context, inner_fringe, inner_matrix)), + ), + ); + } + + let (mut new_binders, default_matrix) = if unmatched_variants.is_empty() { + let empty_pattern = PatternMatrix { + tys: vec![], + loc: matrix.loc, + patterns: vec![], + }; + (vec![], empty_pattern) + } else { + matrix.specialize_default() + }; + subject_binders.append(&mut new_binders); + + MatchTree::VariantSwitch { + subject, + subject_binders, + tyargs, + arms, + default: Box::new(build_match_tree(context, fringe, default_matrix)), + } +} + fn make_fringe_entries(binders: &[(Field, Var, Type)]) -> VecDeque { binders .iter() @@ -445,7 +367,6 @@ struct ResolutionContext<'ctxt, 'call> { output_type: &'call Type, arms: &'call Vec, arms_loc: Loc, - results: &'call mut BTreeMap, } impl<'ctxt, 'call> ResolutionContext<'ctxt, 'call> { @@ -457,37 +378,32 @@ impl<'ctxt, 'call> ResolutionContext<'ctxt, 'call> { self.arms_loc } - fn work_result(&mut self, work_id: usize) -> WorkResult { - self.results.remove(&work_id).unwrap() - } - - fn copy_work_result(&mut self, work_id: usize) -> WorkResult { - self.results.get(&work_id).unwrap().clone() - } - fn output_type(&self) -> Type { self.output_type.clone() } } #[growing_stack] -fn resolve_result( +fn match_tree_to_exp( context: &mut ResolutionContext, init_subject: &FringeEntry, - result: WorkResult, + result: MatchTree, ) -> T::Exp { match result { - WorkResult::Leaf(leaf) => make_leaf(context, init_subject, leaf), - WorkResult::Failure => T::exp( - context.output_type(), - sp(context.arms_loc, T::UnannotatedExp_::UnresolvedError), - ), - WorkResult::VariantSwitch { + MatchTree::Leaf(leaf) => make_leaf(context, init_subject, leaf), + MatchTree::Failure => { + context.hlir_context.add_diag(ice!((context.arms_loc, "Generated a failure expression, which should not be allowed under match exhaustion."))); + T::exp( + context.output_type(), + sp(context.arms_loc, T::UnannotatedExp_::UnresolvedError), + ) + } + MatchTree::VariantSwitch { subject, subject_binders, tyargs, mut arms, - default: default_ndx, + default, } => { let (m, e) = subject .ty @@ -504,9 +420,8 @@ fn resolve_result( let sorted_variants: Vec = context.hlir_context.info.enum_variants(&m, &e); let mut blocks = vec![]; for v in sorted_variants { - if let Some((unpack_fields, result_ndx)) = arms.remove(&v) { - let work_result = context.work_result(result_ndx); - let rest_result = resolve_result(context, init_subject, work_result); + if let Some((unpack_fields, next)) = arms.remove(&v) { + let rest_result = match_tree_to_exp(context, init_subject, *next); let unpack_block = make_match_variant_unpack( m, e, @@ -518,8 +433,8 @@ fn resolve_result( ); blocks.push((v, unpack_block)); } else { - let work_result = context.copy_work_result(default_ndx); - let rest_result = resolve_result(context, init_subject, work_result); + let default_tree = (*default).clone(); + let rest_result = match_tree_to_exp(context, init_subject, default_tree); blocks.push((v, rest_result)); } } @@ -527,7 +442,7 @@ fn resolve_result( let body_exp = T::exp(context.output_type(), sp(context.arms_loc(), out_exp)); make_copy_bindings(bindings, body_exp) } - WorkResult::StructUnpack { + MatchTree::StructUnpack { subject, subject_binders, tyargs, @@ -545,13 +460,9 @@ fn resolve_result( .map(|(_mut, binder)| (binder, (Mutability::Imm, subject.clone()))) .collect(); let unpack_exp = match unpack { - StructUnpack::Default(result_ndx) => { - let work_result = context.work_result(result_ndx); - resolve_result(context, init_subject, work_result) - } - StructUnpack::Unpack(unpack_fields, result_ndx) => { - let work_result = context.work_result(result_ndx); - let rest_result = resolve_result(context, init_subject, work_result); + StructUnpack::Default(next) => match_tree_to_exp(context, init_subject, *next), + StructUnpack::Unpack(unpack_fields, next) => { + let rest_result = match_tree_to_exp(context, init_subject, *next); make_match_struct_unpack( m, s, @@ -564,7 +475,7 @@ fn resolve_result( }; make_copy_bindings(bindings, unpack_exp) } - WorkResult::LiteralSwitch { + MatchTree::LiteralSwitch { subject, subject_binders, mut arms, @@ -581,26 +492,23 @@ fn resolve_result( .collect(); // If the literal switch for a boolean is saturated, no default case. let lit_subject = make_match_lit(subject.clone()); - let true_arm_ndx = arms + let true_arm = arms .remove(&sp(Loc::invalid(), Value_::Bool(true))) .unwrap(); - let false_arm_ndx = arms + let false_arm = arms .remove(&sp(Loc::invalid(), Value_::Bool(false))) .unwrap(); - let true_arm_result = context.work_result(true_arm_ndx); - let false_arm_result = context.work_result(false_arm_ndx); - - let true_arm = resolve_result(context, init_subject, true_arm_result); - let false_arm = resolve_result(context, init_subject, false_arm_result); - let result_type = true_arm.ty.clone(); + let true_arm = match_tree_to_exp(context, init_subject, *true_arm); + let false_arm = match_tree_to_exp(context, init_subject, *false_arm); + let result_ty = context.output_type().clone(); make_copy_bindings( bindings, - make_if_else(lit_subject, true_arm, false_arm, result_type), + make_if_else(lit_subject, true_arm, false_arm, result_ty), ) } - WorkResult::LiteralSwitch { + MatchTree::LiteralSwitch { subject, subject_binders, arms: map, @@ -616,14 +524,13 @@ fn resolve_result( let mut entries = map.into_iter().collect::>(); entries.sort_by(|(key1, _), (key2, _)| key1.cmp(key2)); - let else_work_result = context.work_result(default); - let mut out_exp = resolve_result(context, init_subject, else_work_result); + let else_work_result = (*default).clone(); + let mut out_exp = match_tree_to_exp(context, init_subject, else_work_result); - for (key, result_ndx) in entries.into_iter().rev() { - let work_result = context.work_result(result_ndx); - let match_arm = resolve_result(context, init_subject, work_result); + for (key, next_tree) in entries.into_iter().rev() { + let match_arm = match_tree_to_exp(context, init_subject, *next_tree); let test_exp = make_lit_test(lit_subject.clone(), key); - let result_ty = out_exp.ty.clone(); + let result_ty = context.output_type().clone(); out_exp = make_if_else(test_exp, match_arm, out_exp, result_ty); } make_copy_bindings(bindings, out_exp) @@ -641,7 +548,7 @@ fn make_leaf( if leaf.len() == 1 { let last = leaf.pop().unwrap(); ice_assert!( - context.hlir_context.env, + context.hlir_context.reporter, last.guard.is_none(), last.guard.unwrap().exp.loc, "Must have a non-guarded leaf" @@ -651,7 +558,7 @@ fn make_leaf( let last = leaf.pop().unwrap(); ice_assert!( - context.hlir_context.env, + context.hlir_context.reporter, last.guard.is_none(), last.guard.unwrap().exp.loc, "Must have a non-guarded leaf" @@ -661,7 +568,7 @@ fn make_leaf( let out_ty = out_exp.ty.clone(); while let Some(arm) = leaf.pop() { ice_assert!( - context.hlir_context.env, + context.hlir_context.reporter, arm.guard.is_some(), arm.loc, "Expected a guard" @@ -725,7 +632,7 @@ fn make_arm_unpack( let Some((queue_entries, unpack)) = arm_variant_unpack(context, None, ploc, m, e, tys, v, fs, entry) else { - context.hlir_context.env.add_diag(ice!(( + context.hlir_context.add_diag(ice!(( ploc, "Did not build an arm unpack for a value variant" ))); @@ -751,7 +658,7 @@ fn make_arm_unpack( let Some((queue_entries, unpack)) = arm_struct_unpack(context, None, ploc, m, s, tys, fs, entry) else { - context.hlir_context.env.add_diag(ice!(( + context.hlir_context.add_diag(ice!(( ploc, "Did not build an arm unpack for a value struct" ))); @@ -853,8 +760,8 @@ fn arm_variant_unpack( .iter() .all(|(_, _, (_, (_, pat)))| matches!(pat.pat.value, TP::Wildcard)) || fields.is_empty(); - // If we are matching a ref with no fields under it, we aren't going to drop so - // we just continue on. + // If we are matching a ref with no fields under it, we aren't going to drop + // so we just continue on. if all_wild && mut_ref.is_some() { return None; } @@ -879,8 +786,8 @@ fn arm_struct_unpack( .iter() .all(|(_, _, (_, (_, pat)))| matches!(pat.pat.value, TP::Wildcard)) || fields.is_empty(); - // If we are matching a ref with no fields under it, we aren't going to drop so - // we just continue on. + // If we are matching a ref with no fields under it, we aren't going to drop + // so we just continue on. if all_wild && mut_ref.is_some() { return None; } @@ -1032,7 +939,8 @@ fn make_var_ref(subject: FringeEntry) -> Box { } } -// Performs an unpack for the purpose of matching, where we are matching against an imm. ref. +// Performs an unpack for the purpose of matching, where we are matching against +// an imm. ref. fn make_match_variant_unpack( mident: ModuleIdent, enum_: DatatypeName, @@ -1075,7 +983,8 @@ fn make_match_variant_unpack( T::exp(result_type, exp_value) } -// Performs a struct unpack for the purpose of matching, where we are matching against an imm. ref. +// Performs a struct unpack for the purpose of matching, where we are matching +// against an imm. ref. fn make_match_struct_unpack( mident: ModuleIdent, struct_: DatatypeName, @@ -1278,7 +1187,7 @@ fn make_if_else(test: T::Exp, conseq: T::Exp, alt: T::Exp, result_ty: Type) -> T result_ty, sp( loc, - T::UnannotatedExp_::IfElse(Box::new(test), Box::new(conseq), Box::new(alt)), + T::UnannotatedExp_::IfElse(Box::new(test), Box::new(conseq), Some(Box::new(alt))), ), ) } diff --git a/external-crates/move/crates/move-compiler/src/hlir/translate.rs b/external-crates/move/crates/move-compiler/src/hlir/translate.rs index 46fce24ed4f..10e83782c55 100644 --- a/external-crates/move/crates/move-compiler/src/hlir/translate.rs +++ b/external-crates/move/crates/move-compiler/src/hlir/translate.rs @@ -15,7 +15,8 @@ use move_symbol_pool::Symbol; use once_cell::sync::Lazy; use crate::{ - debug_display, debug_display_verbose, diag, + FullyCompiledProgram, debug_display, debug_display_verbose, diag, + diagnostics::{Diagnostic, DiagnosticReporter, Diagnostics, warning_filters::WarningFilters}, editions::{FeatureGate, Flavor}, expansion::ast::{self as E, Fields, ModuleIdent, Mutability, TargetKind}, hlir::{ @@ -30,15 +31,13 @@ use crate::{ Ability_, BinOp, BinOp_, ConstantName, DatatypeName, Field, FunctionName, VariantName, }, shared::{ - matching::{new_match_var_name, MatchContext, MATCH_TEMP_PREFIX}, - process_binops, + matching::{MATCH_TEMP_PREFIX, MatchContext, new_match_var_name}, program_info::TypingProgramInfo, string_utils::debug_print, unique_map::UniqueMap, *, }, typing::ast as T, - FullyCompiledProgram, }; //************************************************************************************************** @@ -121,18 +120,26 @@ pub fn display_var(s: Symbol) -> DisplayVar { //************************************************************************************************** pub(super) struct HLIRDebugFlags { + #[allow(dead_code)] pub(super) match_variant_translation: bool, + #[allow(dead_code)] pub(super) match_translation: bool, + #[allow(dead_code)] pub(super) match_specialization: bool, + #[allow(dead_code)] pub(super) match_work_queue: bool, + #[allow(dead_code)] pub(super) function_translation: bool, + #[allow(dead_code)] pub(super) eval_order: bool, } pub(super) struct Context<'env> { - pub env: &'env mut CompilationEnv, + pub env: &'env CompilationEnv, pub info: Arc, + #[allow(dead_code)] pub debug: HLIRDebugFlags, + pub reporter: DiagnosticReporter<'env>, current_package: Option, function_locals: UniqueMap, signature: Option, @@ -145,7 +152,7 @@ pub(super) struct Context<'env> { impl<'env> Context<'env> { pub fn new( - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, _pre_compiled_lib_opt: Option>, prog: &T::Program, ) -> Self { @@ -157,8 +164,10 @@ impl<'env> Context<'env> { match_specialization: false, match_work_queue: false, }; + let reporter = env.diagnostic_reporter_at_top_level(); Context { env, + reporter, info: prog.info.clone(), debug, current_package: None, @@ -171,6 +180,22 @@ impl<'env> Context<'env> { } } + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } pub fn has_empty_locals(&self) -> bool { self.function_locals.is_empty() } @@ -206,17 +231,15 @@ impl<'env> Context<'env> { } } - pub fn record_named_block_binders( + pub fn enter_named_block( &mut self, block_name: H::BlockLabel, binders: Vec, + ty: H::Type, ) { self.named_block_binders .add(block_name, binders) .expect("ICE reused block name"); - } - - pub fn record_named_block_type(&mut self, block_name: H::BlockLabel, ty: H::Type) { self.named_block_types .add(block_name, ty) .expect("ICE reused named block name"); @@ -229,6 +252,15 @@ impl<'env> Context<'env> { .clone() } + pub fn exit_named_block(&mut self, block_name: H::BlockLabel) { + self.named_block_binders + .remove(&block_name) + .expect("Tried to leave an unnkown block"); + self.named_block_types + .remove(&block_name) + .expect("Tried to leave an unnkown block"); + } + pub fn lookup_named_block_type(&mut self, block_name: &H::BlockLabel) -> Option { self.named_block_types.get(block_name).cloned() } @@ -246,12 +278,12 @@ impl<'env> Context<'env> { } impl MatchContext for Context<'_> { - fn env(&mut self) -> &mut CompilationEnv { + fn env(&self) -> &CompilationEnv { self.env } - fn env_ref(&self) -> &CompilationEnv { - self.env + fn reporter(&self) -> &DiagnosticReporter { + &self.reporter } /// Makes a new `naming/ast.rs` variable. Does _not_ record it as a function @@ -264,14 +296,11 @@ impl MatchContext for Context<'_> { // current color scope is. Since these are only used as match // temporaries, however, and they have names that may not be written as // input, it's impossible for these to shadow macro argument names. - sp( - loc, - N::Var_ { - name, - id: id as u16, - color: 0, - }, - ) + sp(loc, N::Var_ { + name, + id: id as u16, + color: 0, + }) } fn program_info(&self) -> &program_info::ProgramInfo { @@ -284,7 +313,7 @@ impl MatchContext for Context<'_> { //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: T::Program, ) -> H::Program { @@ -293,11 +322,16 @@ pub fn program( let mut context = Context::new(compilation_env, pre_compiled_lib, &prog); let T::Program { modules: tmodules, + warning_filters_table, info, } = prog; let modules = modules(&mut context, tmodules); - H::Program { modules, info } + H::Program { + modules, + warning_filters_table, + info, + } } fn modules( @@ -333,7 +367,7 @@ fn module( constants: tconstants, } = mdef; context.current_package = package_name; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let structs = tstructs.map(|name, s| struct_def(context, name, s)); let enums = tenums.map(|name, s| enum_def(context, name, s)); @@ -349,22 +383,19 @@ fn module( gen_unused_warnings(context, target_kind, &structs); context.current_package = None; - context.env.pop_warning_filter_scope(); - ( - module_ident, - H::ModuleDefinition { - warning_filter, - package_name, - attributes, - target_kind, - dependency_order, - friends, - structs, - enums, - constants, - functions, - }, - ) + context.pop_warning_filter_scope(); + (module_ident, H::ModuleDefinition { + warning_filter, + package_name, + attributes, + target_kind, + dependency_order, + friends, + structs, + enums, + constants, + functions, + }) } //************************************************************************************************** @@ -378,6 +409,7 @@ fn function(context: &mut Context, _name: FunctionName, f: T::Function) -> H::Fu warning_filter, index, attributes, + loc, compiled_visibility: tcompiled_visibility, visibility: tvisibility, entry, @@ -386,14 +418,15 @@ fn function(context: &mut Context, _name: FunctionName, f: T::Function) -> H::Fu body, } = f; assert!(macro_.is_none(), "ICE macros filtered above"); - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let signature = function_signature(context, signature); let body = function_body(context, &signature, _name, body); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); H::Function { warning_filter, index, attributes, + loc, compiled_visibility: visibility(tcompiled_visibility), visibility: visibility(tvisibility), entry, @@ -437,7 +470,7 @@ fn function_body( TB::Defined((_, seq)) => { debug_print!(context.debug.function_translation, (msg format!("-- {} ----------------", _name)), - (lines "body" => &seq)); + (lines "body" => &seq; verbose)); let (locals, body) = function_body_defined(context, sig, loc, seq); debug_print!(context.debug.function_translation, (msg "--------"), @@ -494,7 +527,7 @@ fn constant(context: &mut Context, _name: ConstantName, cdef: T::Constant) -> H: signature: tsignature, value: tvalue, } = cdef; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let signature = base_type(context, tsignature); let eloc = tvalue.exp.loc; let tseq = { @@ -508,7 +541,7 @@ fn constant(context: &mut Context, _name: ConstantName, cdef: T::Constant) -> H: return_type: H::Type_::base(signature.clone()), }; let (locals, body) = function_body_defined(context, &function_signature, loc, tseq); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); H::Constant { warning_filter, index, @@ -537,9 +570,9 @@ fn struct_def( type_parameters, fields, } = sdef; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let fields = struct_fields(context, fields); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); H::StructDefinition { warning_filter, index, @@ -581,13 +614,13 @@ fn enum_def( type_parameters, variants, } = edef; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let variants = variants.map(|_, defn| H::VariantDefinition { index: defn.index, loc: defn.loc, fields: variant_fields(context, defn.fields), }); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); H::EnumDefinition { warning_filter, index, @@ -643,7 +676,7 @@ fn base_type(context: &mut Context, sp!(loc, nb_): N::Type) -> H::BaseType { use N::Type_ as NT; let b_ = match nb_ { NT::Var(_) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, format!( "ICE type inf. var not expanded: {}", @@ -653,7 +686,7 @@ fn base_type(context: &mut Context, sp!(loc, nb_): N::Type) -> H::BaseType { return error_base_type(loc); } NT::Apply(None, _, _) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, format!("ICE kind not expanded: {}", debug_display_verbose!(nb_)) ))); @@ -664,7 +697,7 @@ fn base_type(context: &mut Context, sp!(loc, nb_): N::Type) -> H::BaseType { NT::UnresolvedError => HB::UnresolvedError, NT::Anything => HB::Unreachable, NT::Ref(_, _) | NT::Unit | NT::Fun(_, _) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, format!( "ICE base type constraint failed: {}", @@ -707,11 +740,11 @@ fn single_type(context: &mut Context, sp!(loc, ty_): N::Type) -> H::SingleType { fn type_(context: &mut Context, sp!(loc, ty_): N::Type) -> H::Type { use H::Type_ as HT; - use N::{TypeName_ as TN, Type_ as NT}; + use N::{Type_ as NT, TypeName_ as TN}; let t_ = match ty_ { NT::Unit => HT::Unit, NT::Apply(None, _, _) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, format!("ICE kind not expanded: {}", debug_display_verbose!(ty_)) ))); @@ -788,11 +821,12 @@ fn tail( // ----------------------------------------------------------------------------------------- // control flow statements // ----------------------------------------------------------------------------------------- - E::IfElse(test, conseq, alt) => { + E::IfElse(test, conseq, alt_opt) => { let cond = value(context, block, Some(&tbool(eloc)), *test); let mut if_block = make_block!(); let conseq_exp = tail(context, &mut if_block, Some(&out_type), *conseq); let mut else_block = make_block!(); + let alt = alt_opt.unwrap_or_else(|| Box::new(typing_unit_exp(eloc))); let alt_exp = tail(context, &mut else_block, Some(&out_type), *alt); let (binders, bound_exp) = make_binders(context, eloc, out_type.clone()); @@ -907,17 +941,14 @@ fn tail( } else { maybe_freeze(context, block, expected_type.cloned(), bound_exp) }; - context.record_named_block_binders(name, binders); - context.record_named_block_type(name, out_type.clone()); + context.enter_named_block(name, binders, out_type.clone()); let (loop_body, has_break) = process_loop_body(context, &name, *body); - block.push_back(sp( - eloc, - S::Loop { - name, - has_break, - block: loop_body, - }, - )); + block.push_back(sp(eloc, S::Loop { + name, + has_break, + block: loop_body, + })); + context.exit_named_block(name); if has_break { Some(result) } else { None } } e_ @ E::Loop { .. } => { @@ -936,21 +967,18 @@ fn tail( } else { maybe_freeze(context, block, expected_type.cloned(), bound_exp) }; - context.record_named_block_binders(name, binders.clone()); - context.record_named_block_type(name, out_type.clone()); + context.enter_named_block(name, binders.clone(), out_type.clone()); let mut body_block = make_block!(); let final_exp = tail_block(context, &mut body_block, Some(&out_type), seq); - final_exp.map(|exp| { + if let Some(exp) = final_exp { bind_value_in_block(context, binders, Some(out_type), &mut body_block, exp); - block.push_back(sp( - eloc, - S::NamedBlock { - name, - block: body_block, - }, - )); - result - }) + } + block.push_back(sp(eloc, S::NamedBlock { + name, + block: body_block, + })); + context.exit_named_block(name); + Some(result) } E::Block((_, seq)) => tail_block(context, block, expected_type, seq), @@ -963,9 +991,7 @@ fn tail( | E::Continue(_) | E::Assign(_, _, _) | E::Mutate(_, _) => { - context - .env - .add_diag(ice!((eloc, "ICE statement mishandled in HLIR lowering"))); + context.add_diag(ice!((eloc, "ICE statement mishandled in HLIR lowering"))); None } @@ -995,9 +1021,7 @@ fn tail_block( None => None, Some(sp!(_, S::Seq(last))) => tail(context, block, expected_type, *last), Some(sp!(loc, _)) => { - context - .env - .add_diag(ice!((loc, "ICE statement mishandled in HLIR lowering"))); + context.add_diag(ice!((loc, "ICE statement mishandled in HLIR lowering"))); None } } @@ -1059,18 +1083,14 @@ fn value( let [cond_item, code_item]: [TI; 2] = match arguments.exp.value { E::ExpList(arg_list) => arg_list.try_into().unwrap(), _ => { - context - .env - .add_diag(ice!((eloc, "ICE type checking assert failed"))); + context.add_diag(ice!((eloc, "ICE type checking assert failed"))); return error_exp(eloc); } }; let (econd, ecode) = match (cond_item, code_item) { (TI::Single(econd, _), TI::Single(ecode, _)) => (econd, ecode), _ => { - context - .env - .add_diag(ice!((eloc, "ICE type checking assert failed"))); + context.add_diag(ice!((eloc, "ICE type checking assert failed"))); return error_exp(eloc); } }; @@ -1079,15 +1099,12 @@ fn value( let cond = bind_exp(context, block, cond_value); let code = bind_exp(context, block, code_value); let if_block = make_block!(); - let else_block = make_block!(make_command(eloc, C::Abort(code))); - block.push_back(sp( - eloc, - S::IfElse { - cond: Box::new(cond), - if_block, - else_block, - }, - )); + let else_block = make_block!(make_command(eloc, C::Abort(code.exp.loc, code))); + block.push_back(sp(eloc, S::IfElse { + cond: Box::new(cond), + if_block, + else_block, + })); unit_exp(eloc) } E::Builtin(bt, arguments) @@ -1097,18 +1114,14 @@ fn value( let [cond_item, code_item]: [TI; 2] = match arguments.exp.value { E::ExpList(arg_list) => arg_list.try_into().unwrap(), _ => { - context - .env - .add_diag(ice!((eloc, "ICE type checking assert failed"))); + context.add_diag(ice!((eloc, "ICE type checking assert failed"))); return error_exp(eloc); } }; let (econd, ecode) = match (cond_item, code_item) { (TI::Single(econd, _), TI::Single(ecode, _)) => (econd, ecode), _ => { - context - .env - .add_diag(ice!((eloc, "ICE type checking assert failed"))); + context.add_diag(ice!((eloc, "ICE type checking assert failed"))); return error_exp(eloc); } }; @@ -1116,28 +1129,25 @@ fn value( let mut else_block = make_block!(); let code = value(context, &mut else_block, None, ecode); let if_block = make_block!(); - else_block.push_back(make_command(eloc, C::Abort(code))); - block.push_back(sp( - eloc, - S::IfElse { - cond: Box::new(cond), - if_block, - else_block, - }, - )); + else_block.push_back(make_command(eloc, C::Abort(code.exp.loc, code))); + block.push_back(sp(eloc, S::IfElse { + cond: Box::new(cond), + if_block, + else_block, + })); unit_exp(eloc) } // ----------------------------------------------------------------------------------------- // control flow statements // ----------------------------------------------------------------------------------------- - E::IfElse(test, conseq, alt) => { + E::IfElse(test, conseq, alt_opt) => { let cond = value(context, block, Some(&tbool(eloc)), *test); let mut if_block = make_block!(); let conseq_exp = value(context, &mut if_block, Some(&out_type), *conseq); let mut else_block = make_block!(); + let alt = alt_opt.unwrap_or_else(|| Box::new(typing_unit_exp(eloc))); let alt_exp = value(context, &mut else_block, Some(&out_type), *alt); - let (binders, bound_exp) = make_binders(context, eloc, out_type.clone()); let arms_unreachable = conseq_exp.is_unreachable() && alt_exp.is_unreachable(); @@ -1234,22 +1244,20 @@ fn value( } => { let name = translate_block_label(name); let (binders, bound_exp) = make_binders(context, eloc, out_type.clone()); - context.record_named_block_binders(name, binders); - context.record_named_block_type(name, out_type.clone()); + context.enter_named_block(name, binders, out_type.clone()); let (loop_body, has_break) = process_loop_body(context, &name, *body); - block.push_back(sp( - eloc, - S::Loop { - name, - has_break, - block: loop_body, - }, - )); - if has_break { + block.push_back(sp(eloc, S::Loop { + name, + has_break, + block: loop_body, + })); + let result = if has_break { bound_exp } else { make_exp(HE::Unreachable) - } + }; + context.exit_named_block(name); + result } e_ @ E::Loop { .. } => { statement(context, block, T::exp(in_type.clone(), sp(eloc, e_))); @@ -1258,18 +1266,15 @@ fn value( E::NamedBlock(name, (_, seq)) => { let name = translate_block_label(name); let (binders, bound_exp) = make_binders(context, eloc, out_type.clone()); - context.record_named_block_binders(name, binders.clone()); - context.record_named_block_type(name, out_type.clone()); + context.enter_named_block(name, binders.clone(), out_type.clone()); let mut body_block = make_block!(); let final_exp = value_block(context, &mut body_block, Some(&out_type), eloc, seq); bind_value_in_block(context, binders, Some(out_type), &mut body_block, final_exp); - block.push_back(sp( - eloc, - S::NamedBlock { - name, - block: body_block, - }, - )); + block.push_back(sp(eloc, S::NamedBlock { + name, + block: body_block, + })); + context.exit_named_block(name); bound_exp } E::Block((_, seq)) => value_block(context, block, Some(&out_type), eloc, seq), @@ -1504,7 +1509,7 @@ fn value( var, } => var, _ => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( eloc, format!( "ICE invalid bind_exp for single value: {}", @@ -1528,7 +1533,7 @@ fn value( | Some(bt @ sp!(_, BT::U128)) | Some(bt @ sp!(_, BT::U256)) => *bt, _ => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( eloc, format!( "ICE typing failed for cast: {} : {}", @@ -1593,9 +1598,7 @@ fn value( | E::Continue(_) | E::Assign(_, _, _) | E::Mutate(_, _) => { - context - .env - .add_diag(ice!((eloc, "ICE statement mishandled in HLIR lowering"))); + context.add_diag(ice!((eloc, "ICE statement mishandled in HLIR lowering"))); error_exp(eloc) } @@ -1603,7 +1606,7 @@ fn value( // odds and ends -- things we need to deal with but that don't do much // ----------------------------------------------------------------------------------------- E::Use(_) => { - context.env.add_diag(ice!((eloc, "ICE unexpanded use"))); + context.add_diag(ice!((eloc, "ICE unexpanded use"))); error_exp(eloc) } E::UnresolvedError => { @@ -1627,15 +1630,11 @@ fn value_block( match last_exp { Some(sp!(_, S::Seq(last))) => value(context, block, expected_type, *last), Some(sp!(loc, _)) => { - context - .env - .add_diag(ice!((loc, "ICE last sequence item should be an exp"))); + context.add_diag(ice!((loc, "ICE last sequence item should be an exp"))); error_exp(loc) } None => { - context - .env - .add_diag(ice!((seq_loc, "ICE empty sequence in value position"))); + context.add_diag(ice!((seq_loc, "ICE empty sequence in value position"))); error_exp(seq_loc) } } @@ -1802,20 +1801,18 @@ fn statement(context: &mut Context, block: &mut Block, e: T::Exp) { // ----------------------------------------------------------------------------------------- // control flow statements // ----------------------------------------------------------------------------------------- - E::IfElse(test, conseq, alt) => { + E::IfElse(test, conseq, alt_opt) => { let cond = value(context, block, Some(&tbool(eloc)), *test); let mut if_block = make_block!(); statement(context, &mut if_block, *conseq); let mut else_block = make_block!(); + let alt = alt_opt.unwrap_or_else(|| Box::new(typing_unit_exp(eloc))); statement(context, &mut else_block, *alt); - block.push_back(sp( - eloc, - S::IfElse { - cond: Box::new(cond), - if_block, - else_block, - }, - )); + block.push_back(sp(eloc, S::IfElse { + cond: Box::new(cond), + if_block, + else_block, + })); } E::Match(subject, arms) => { debug_print!(context.debug.match_translation, @@ -1853,37 +1850,31 @@ fn statement(context: &mut Context, block: &mut Block, e: T::Exp) { let cond = (cond_block, Box::new(cond_exp)); let name = translate_block_label(name); // While loops can still use break and continue so we build them dummy binders. - context.record_named_block_binders(name, vec![]); - context.record_named_block_type(name, tunit(eloc)); + context.enter_named_block(name, vec![], tunit(eloc)); let mut body_block = make_block!(); statement(context, &mut body_block, *body); - block.push_back(sp( - eloc, - S::While { - cond, - name, - block: body_block, - }, - )); + block.push_back(sp(eloc, S::While { + cond, + name, + block: body_block, + })); + context.exit_named_block(name); } E::Loop { name, body, .. } => { let name = translate_block_label(name); let out_type = type_(context, ty.clone()); let (binders, bound_exp) = make_binders(context, eloc, out_type.clone()); - context.record_named_block_binders(name, binders); - context.record_named_block_type(name, out_type); + context.enter_named_block(name, binders, out_type); let (loop_body, has_break) = process_loop_body(context, &name, *body); - block.push_back(sp( - eloc, - S::Loop { - name, - has_break, - block: loop_body, - }, - )); + block.push_back(sp(eloc, S::Loop { + name, + has_break, + block: loop_body, + })); if has_break { make_ignore_and_pop(block, bound_exp); } + context.exit_named_block(name); } E::Block((_, seq)) => statement_block(context, block, seq), E::Return(rhs) => { @@ -1897,7 +1888,7 @@ fn statement(context: &mut Context, block: &mut Block, e: T::Exp) { } E::Abort(rhs) => { let exp = value(context, block, None, *rhs); - block.push_back(make_command(eloc, C::Abort(exp))); + block.push_back(make_command(eloc, C::Abort(exp.exp.loc, exp))); } E::Give(name, rhs) => { let out_name = translate_block_label(name); @@ -1971,7 +1962,7 @@ fn statement(context: &mut Context, block: &mut Block, e: T::Exp) { // odds and ends -- things we need to deal with but that don't do much // ----------------------------------------------------------------------------------------- E::Use(_) => { - context.env.add_diag(ice!((eloc, "ICE unexpanded use"))); + context.add_diag(ice!((eloc, "ICE unexpanded use"))); } } } @@ -2037,27 +2028,28 @@ fn tunit(loc: Loc) -> H::Type { sp(loc, H::Type_::Unit) } +fn typing_unit_exp(loc: Loc) -> T::Exp { + T::exp( + sp(loc, N::Type_::Unit), + sp(loc, T::UnannotatedExp_::Unit { trailing: false }), + ) +} + fn unit_exp(loc: Loc) -> H::Exp { H::exp( tunit(loc), - sp( - loc, - H::UnannotatedExp_::Unit { - case: H::UnitCase::Implicit, - }, - ), + sp(loc, H::UnannotatedExp_::Unit { + case: H::UnitCase::Implicit, + }), ) } fn trailing_unit_exp(loc: Loc) -> H::Exp { H::exp( tunit(loc), - sp( - loc, - H::UnannotatedExp_::Unit { - case: H::UnitCase::Trailing, - }, - ), + sp(loc, H::UnannotatedExp_::Unit { + case: H::UnitCase::Trailing, + }), ) } @@ -2403,13 +2395,10 @@ fn make_ignore_and_pop(block: &mut Block, exp: H::Exp) { block.push_back(sp(loc, H::Statement_::Command(c))); } H::Type_::Multiple(tys) => { - let c = sp( - loc, - H::Command_::IgnoreAndPop { - pop_num: tys.len(), - exp, - }, - ); + let c = sp(loc, H::Command_::IgnoreAndPop { + pop_num: tys.len(), + exp, + }); block.push_back(sp(loc, H::Statement_::Command(c))); } }; @@ -2488,7 +2477,7 @@ fn bind_value_in_block( match lvalue { H::LValue_::Var { .. } => (), lv => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( *loc, format!( "ICE tried bind_value for non-var lvalue {}", @@ -2517,12 +2506,9 @@ fn make_binders(context: &mut Context, loc: Loc, ty: H::Type) -> (Vec vec![], H::exp( tunit(loc), - sp( - loc, - E::Unit { - case: H::UnitCase::Implicit, - }, - ), + sp(loc, E::Unit { + case: H::UnitCase::Implicit, + }), ), ), T::Single(single_type) => { @@ -2553,13 +2539,10 @@ fn make_temp(context: &mut Context, loc: Loc, sp!(_, ty): H::SingleType) -> (H:: unused_assignment: false, }; let lvalue = sp(loc, lvalue_); - let uexp = sp( - loc, - H::UnannotatedExp_::Move { - annotation: MoveOpAnnotation::InferredLastUsage, - var: binder, - }, - ); + let uexp = sp(loc, H::UnannotatedExp_::Move { + annotation: MoveOpAnnotation::InferredLastUsage, + var: binder, + }); (lvalue, H::exp(H::Type_::single(sp(loc, ty)), uexp)) } @@ -2587,9 +2570,7 @@ fn process_value(context: &mut Context, sp!(loc, ev_): E::Value) -> H::Value { use H::Value_ as HV; let v_ = match ev_ { EV::InferredNum(_) => { - context - .env - .add_diag(ice!((loc, "ICE not expanded to value"))); + context.add_diag(ice!((loc, "ICE not expanded to value"))); HV::U64(0) } EV::Address(a) => HV::Address(a.into_addr_bytes()), @@ -2608,152 +2589,265 @@ fn process_value(context: &mut Context, sp!(loc, ev_): E::Value) -> H::Value { sp(loc, v_) } +#[derive(Debug)] +enum BinopEntry { + Op { + exp_loc: Loc, + lhs: Box, + op: BinOp, + op_type: Box, + rhs: Box, + }, + ShortCircuitAnd { + loc: Loc, + tests: Vec, + last: Box, + }, + ShortCircuitOr { + loc: Loc, + tests: Vec, + last: Box, + }, + Exp { + exp: T::Exp, + }, +} + +#[allow(dead_code)] +fn print_entry(entry: &BinopEntry, indent: usize) { + match entry { + BinopEntry::Op { lhs, op, rhs, .. } => { + println!("{:indent$} op {op}", " "); + print_entry(lhs, indent + 2); + print_entry(rhs, indent + 2); + } + BinopEntry::ShortCircuitAnd { tests, last, .. } => { + println!("{:indent$} '&&' op group", " "); + for entry in tests { + print_entry(entry, indent + 2); + } + print_entry(last, indent + 2); + } + BinopEntry::ShortCircuitOr { tests, last, .. } => { + println!("{:indent$} '||' op group", " "); + for entry in tests { + print_entry(entry, indent + 2); + } + print_entry(last, indent + 2); + } + BinopEntry::Exp { .. } => { + println!("{:indent$} value", " "); + } + } +} + +#[growing_stack] +fn group_boolean_binops(e: T::Exp) -> BinopEntry { + use BinopEntry as BE; + use T::UnannotatedExp_ as TE; + let exp_loc = e.exp.loc; + let _exp_type = e.ty.clone(); + match e.exp.value { + TE::BinopExp(lhs, op, op_type, rhs) => { + let lhs = group_boolean_binops(*lhs); + let rhs = group_boolean_binops(*rhs); + match &op.value { + BinOp_::And => { + let mut new_tests = match lhs { + BE::ShortCircuitAnd { + loc: _, + mut tests, + last, + } => { + tests.push(*last); + tests + } + other => vec![other], + }; + let last = match rhs { + BE::ShortCircuitAnd { + loc: _, + tests, + last, + } => { + new_tests.extend(tests); + last + } + other => Box::new(other), + }; + BE::ShortCircuitAnd { + loc: exp_loc, + tests: new_tests, + last, + } + } + BinOp_::Or => { + let mut new_tests = match lhs { + BE::ShortCircuitOr { + loc: _, + mut tests, + last, + } => { + tests.push(*last); + tests + } + other => vec![other], + }; + let last = match rhs { + BE::ShortCircuitOr { + loc: _, + tests, + last, + } => { + new_tests.extend(tests); + last + } + other => Box::new(other), + }; + BE::ShortCircuitOr { + loc: exp_loc, + tests: new_tests, + last, + } + } + _ => { + let lhs = Box::new(lhs); + let rhs = Box::new(rhs); + BE::Op { + exp_loc, + lhs, + op, + op_type, + rhs, + } + } + } + } + _ => BE::Exp { exp: e }, + } +} + fn process_binops( context: &mut Context, input_block: &mut Block, result_type: H::Type, e: T::Exp, ) -> H::Exp { - use T::UnannotatedExp_ as E; - let (mut block, exp) = process_binops!( - (BinOp, H::Type, Loc), - (Block, H::Exp), - (e, result_type), - (exp, ty), - exp, - T::Exp { - exp: sp!(eloc, E::BinopExp(lhs, op, op_type, rhs)), - .. - } => - { - let op = (op, ty, eloc); - let op_type = freeze_ty(type_(context, *op_type)); - let rhs = (*rhs, op_type.clone()); - let lhs = (*lhs, op_type); - (lhs, op, rhs) - }, - { - let mut exp_block = make_block!(); - let exp = value(context, &mut exp_block, Some(ty).as_ref(), exp); - (exp_block, exp) - }, - value_stack, - (op, ty, eloc) => - { - match op { - sp!(loc, op @ BinOp_::And) => { - let test = value_stack.pop().expect("ICE binop hlir issue"); - let if_ = value_stack.pop().expect("ICE binop hlir issue"); - if simple_bool_binop_arg(&if_) { - let (mut test_block, test_exp) = test; - let (mut if_block, if_exp) = if_; - test_block.append(&mut if_block); - let exp = H::exp(ty, sp(eloc, make_binop(test_exp, sp(loc, op), if_exp))); - (test_block, exp) - } else { - let else_ = (make_block!(), bool_exp(loc, false)); - make_boolean_binop( - context, - sp(loc, op), - test, - if_, - else_, - ) - } + let entry = group_boolean_binops(e.clone()); + // print_entry(&entry, 0); + + #[growing_stack] + fn build_binop( + context: &mut Context, + input_block: &mut Block, + result_type: H::Type, + e: BinopEntry, + ) -> H::Exp { + match e { + BinopEntry::Op { + exp_loc, + lhs, + op, + op_type, + rhs, + } => { + let op_type = freeze_ty(type_(context, *op_type)); + let mut lhs_block = make_block!(); + let mut lhs_exp = build_binop(context, &mut lhs_block, op_type.clone(), *lhs); + let mut rhs_block = make_block!(); + let rhs_exp = build_binop(context, &mut rhs_block, op_type, *rhs); + if !rhs_block.is_empty() { + lhs_exp = bind_exp(context, &mut lhs_block, lhs_exp); } - sp!(loc, op @ BinOp_::Or) => { - let test = value_stack.pop().expect("ICE binop hlir issue"); - let else_ = value_stack.pop().expect("ICE binop hlir issue"); - if simple_bool_binop_arg(&else_) { - let (mut test_block, test_exp) = test; - let (mut else_block, else_exp) = else_; - test_block.append(&mut else_block); - let exp = H::exp(ty, sp(eloc, make_binop(test_exp, sp(loc, op), else_exp))); - (test_block, exp) - } else { - let if_ = (make_block!(), bool_exp(loc, true)); - make_boolean_binop( - context, - sp(loc, op), - test, - if_, - else_, - ) - } + input_block.extend(lhs_block); + input_block.extend(rhs_block); + H::exp(result_type, sp(exp_loc, make_binop(lhs_exp, op, rhs_exp))) + } + BinopEntry::ShortCircuitAnd { loc, tests, last } => { + let bool_ty = tbool(loc); + let (binders, bound_exp) = make_binders(context, loc, bool_ty.clone()); + + let mut cur_block = make_block!(); + let out_exp = build_binop(context, &mut cur_block, bool_ty.clone(), *last); + bind_value_in_block( + context, + binders.clone(), + Some(bool_ty.clone()), + &mut cur_block, + out_exp, + ); + + for entry in tests.into_iter().rev() { + let if_block = std::mem::take(&mut cur_block); + let cond = + Box::new(build_binop(context, &mut cur_block, bool_ty.clone(), entry)); + let mut else_block = make_block!(); + bind_value_in_block( + context, + binders.clone(), + Some(bool_ty.clone()), + &mut else_block, + bool_exp(loc, false), + ); + let if_stmt_ = H::Statement_::IfElse { + cond, + if_block, + else_block, + }; + let if_stmt = sp(loc, if_stmt_); + cur_block.push_back(if_stmt); } - op => { - let (mut lhs_block, mut lhs_exp) = value_stack.pop().expect("ICE binop hlir issue"); - let (mut rhs_block, rhs_exp) = value_stack.pop().expect("ICE binop hlir issue"); - if !rhs_block.is_empty() { - lhs_exp = bind_exp(context, &mut lhs_block, lhs_exp); - } - lhs_block.append(&mut rhs_block); - // NB: here we could check if the LHS and RHS are "large" terms and let-bind - // them if they are getting too big. - let exp = H::exp(ty, sp(eloc, make_binop(lhs_exp, op, rhs_exp))); - (lhs_block, exp) + input_block.extend(cur_block); + bound_exp + } + BinopEntry::ShortCircuitOr { loc, tests, last } => { + let bool_ty = tbool(loc); + let (binders, bound_exp) = make_binders(context, loc, bool_ty.clone()); + + let mut cur_block = make_block!(); + let out_exp = build_binop(context, &mut cur_block, bool_ty.clone(), *last); + bind_value_in_block( + context, + binders.clone(), + Some(bool_ty.clone()), + &mut cur_block, + out_exp, + ); + + for entry in tests.into_iter().rev() { + let else_block = std::mem::take(&mut cur_block); + let cond = + Box::new(build_binop(context, &mut cur_block, bool_ty.clone(), entry)); + let mut if_block = make_block!(); + bind_value_in_block( + context, + binders.clone(), + Some(bool_ty.clone()), + &mut if_block, + bool_exp(loc, true), + ); + let if_stmt_ = H::Statement_::IfElse { + cond, + if_block, + else_block, + }; + let if_stmt = sp(loc, if_stmt_); + cur_block.push_back(if_stmt); } + input_block.extend(cur_block); + bound_exp } + BinopEntry::Exp { exp } => value(context, input_block, Some(&result_type), exp), } - ); - input_block.append(&mut block); - exp + } + + build_binop(context, input_block, result_type, entry) } fn make_binop(lhs: H::Exp, op: BinOp, rhs: H::Exp) -> H::UnannotatedExp_ { H::UnannotatedExp_::BinopExp(Box::new(lhs), op, Box::new(rhs)) } -fn make_boolean_binop( - context: &mut Context, - op: BinOp, - (mut test_block, test_exp): (Block, H::Exp), - (mut if_block, if_exp): (Block, H::Exp), - (mut else_block, else_exp): (Block, H::Exp), -) -> (Block, H::Exp) { - let loc = op.loc; - - let bool_ty = tbool(loc); - let (binders, bound_exp) = make_binders(context, loc, bool_ty.clone()); - let opty = Some(bool_ty); - - let arms_unreachable = if_exp.is_unreachable() && else_exp.is_unreachable(); - // one of these _must_ always bind by construction. - bind_value_in_block( - context, - binders.clone(), - opty.clone(), - &mut if_block, - if_exp, - ); - bind_value_in_block(context, binders, opty, &mut else_block, else_exp); - assert!(!arms_unreachable, "ICE boolean binop processing failure"); - - let if_else = H::Statement_::IfElse { - cond: Box::new(test_exp), - if_block, - else_block, - }; - test_block.push_back(sp(loc, if_else)); - (test_block, bound_exp) -} - -fn simple_bool_binop_arg((block, exp): &(Block, H::Exp)) -> bool { - use H::UnannotatedExp_ as HE; - if !block.is_empty() { - false - } else { - matches!( - exp.exp.value, - HE::Value(_) - | HE::Constant(_) - | HE::Move { .. } - | HE::Copy { .. } - | HE::UnresolvedError - ) - } -} - //************************************************************************************************** // Freezing //************************************************************************************************** @@ -2810,7 +2904,7 @@ fn needs_freeze( format!("Expected type: {}", debug_display_verbose!(_expected)) ), ); - context.env.add_diag(diag); + context.add_diag(diag); } Freeze::NotNeeded } @@ -2851,7 +2945,7 @@ fn freeze(context: &mut Context, expected_type: &H::Type, e: H::Exp) -> (Block, "ICE list item has Multiple type: {}", debug_display_verbose!(e.ty) ); - context.env.add_diag(ice!((e.ty.loc, msg))); + context.add_diag(ice!((e.ty.loc, msg))); H::SingleType_::base(error_base_type(e.ty.loc)) } }) @@ -2899,12 +2993,9 @@ fn gen_unused_warnings( target_kind: TargetKind, structs: &UniqueMap, ) { - if !matches!( - target_kind, - TargetKind::Source { - is_root_package: true - } - ) { + if !matches!(target_kind, TargetKind::Source { + is_root_package: true + }) { // generate warnings only for modules compiled in this pass rather than for all // modules including pre-compiled libraries for which we do not have // source code available and cannot be analyzed in this pass @@ -2913,9 +3004,7 @@ fn gen_unused_warnings( let is_iota_mode = context.env.package_config(context.current_package).flavor == Flavor::Iota; for (_, sname, sdef) in structs { - context - .env - .add_warning_filter_scope(sdef.warning_filter.clone()); + context.push_warning_filter_scope(sdef.warning_filter); let has_key = sdef.abilities.has_ability_(Ability_::Key); @@ -2931,13 +3020,11 @@ fn gen_unused_warnings( .is_some_and(|names| names.contains(&f.value())) { let msg = format!("The '{}' field of the '{sname}' type is unused", f.value()); - context - .env - .add_diag(diag!(UnusedItem::StructField, (f.loc(), msg))); + context.add_diag(diag!(UnusedItem::StructField, (f.loc(), msg))); } } } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } } diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/id_leak.rs b/external-crates/move/crates/move-compiler/src/iota_mode/id_leak.rs index b48596c69e6..a21913ba749 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/id_leak.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/id_leak.rs @@ -2,60 +2,67 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use std::collections::BTreeMap; + +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; use move_symbol_pool::Symbol; use crate::{ cfgir::{ + CFGContext, MemberName, absint::JoinResult, + cfg::ImmForwardCFG, visitor::{ - LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, SimpleExecutionContext, + LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, + SimpleExecutionContext, cfg_satisfies, }, - CFGContext, MemberName, }, diag, diagnostics::{Diagnostic, Diagnostics}, editions::Flavor, expansion::ast::{ModuleIdent, TargetKind}, - hlir::ast::{Exp, Label, ModuleCall, SingleType, Type, Type_, Var}, + hlir::ast::{self as H, Exp, Label, ModuleCall, SingleType, Type, Type_, Var}, + iota_mode::{ + AUTHENTICATOR_STATE_CREATE, AUTHENTICATOR_STATE_MODULE_NAME, BRIDGE_ADDR_VALUE, + BRIDGE_CREATE, BRIDGE_MODULE_NAME, CLOCK_MODULE_NAME, DENY_LIST_CREATE, + DENY_LIST_MODULE_NAME, ID_LEAK_DIAG, IOTA_ADDR_NAME, IOTA_ADDR_VALUE, IOTA_CLOCK_CREATE, + IOTA_SYSTEM_ADDR_VALUE, IOTA_SYSTEM_CREATE, IOTA_SYSTEM_MODULE_NAME, OBJECT_MODULE_NAME, + OBJECT_NEW, OBJECT_NEW_UID_FROM_HASH, RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_CREATE, + TEST_SCENARIO_MODULE_NAME, TS_NEW_OBJECT, UID_TYPE_NAME, + }, parser::ast::Ability_, - shared::{program_info::TypingProgramInfo, CompilationEnv, Identifier}, - iota_mode::{OBJECT_NEW, TEST_SCENARIO_MODULE_NAME, TS_NEW_OBJECT}, -}; -use std::collections::BTreeMap; - -use super::{ - AUTHENTICATOR_STATE_CREATE, AUTHENTICATOR_STATE_MODULE_NAME, BRIDGE_ADDR_NAME, BRIDGE_CREATE, - BRIDGE_MODULE_NAME, CLOCK_MODULE_NAME, DENY_LIST_CREATE, DENY_LIST_MODULE_NAME, ID_LEAK_DIAG, - OBJECT_MODULE_NAME, OBJECT_NEW_UID_FROM_HASH, RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_CREATE, - IOTA_ADDR_NAME, IOTA_CLOCK_CREATE, IOTA_SYSTEM_ADDR_NAME, IOTA_SYSTEM_CREATE, - IOTA_SYSTEM_MODULE_NAME, UID_TYPE_NAME, + shared::{Identifier, program_info::TypingProgramInfo}, }; -pub const FRESH_ID_FUNCTIONS: &[(Symbol, Symbol, Symbol)] = &[ - (IOTA_ADDR_NAME, OBJECT_MODULE_NAME, OBJECT_NEW), - (IOTA_ADDR_NAME, OBJECT_MODULE_NAME, OBJECT_NEW_UID_FROM_HASH), - (IOTA_ADDR_NAME, TEST_SCENARIO_MODULE_NAME, TS_NEW_OBJECT), +pub const FRESH_ID_FUNCTIONS: &[(AccountAddress, Symbol, Symbol)] = &[ + (IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, OBJECT_NEW), + ( + IOTA_ADDR_VALUE, + OBJECT_MODULE_NAME, + OBJECT_NEW_UID_FROM_HASH, + ), + (IOTA_ADDR_VALUE, TEST_SCENARIO_MODULE_NAME, TS_NEW_OBJECT), ]; -pub const FUNCTIONS_TO_SKIP: &[(Symbol, Symbol, Symbol)] = &[ +pub const FUNCTIONS_TO_SKIP: &[(AccountAddress, Symbol, Symbol)] = &[ ( - IOTA_SYSTEM_ADDR_NAME, + IOTA_SYSTEM_ADDR_VALUE, IOTA_SYSTEM_MODULE_NAME, IOTA_SYSTEM_CREATE, ), - (IOTA_ADDR_NAME, CLOCK_MODULE_NAME, IOTA_CLOCK_CREATE), + (IOTA_ADDR_VALUE, CLOCK_MODULE_NAME, IOTA_CLOCK_CREATE), ( - IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, AUTHENTICATOR_STATE_MODULE_NAME, AUTHENTICATOR_STATE_CREATE, ), ( - IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_CREATE, ), - (IOTA_ADDR_NAME, DENY_LIST_MODULE_NAME, DENY_LIST_CREATE), - (BRIDGE_ADDR_NAME, BRIDGE_MODULE_NAME, BRIDGE_CREATE), + (IOTA_ADDR_VALUE, DENY_LIST_MODULE_NAME, DENY_LIST_CREATE), + (BRIDGE_ADDR_VALUE, BRIDGE_MODULE_NAME, BRIDGE_CREATE), ]; //************************************************************************************************** @@ -93,24 +100,21 @@ impl SimpleAbsIntConstructor for IDLeakVerifier { type AI<'a> = IDLeakVerifierAI<'a>; fn new<'a>( - env: &CompilationEnv, context: &'a CFGContext<'a>, + cfg: &ImmForwardCFG, _init_state: &mut as SimpleAbsInt>::State, ) -> Option> { let module = &context.module; let minfo = context.info.module(module); let package_name = minfo.package; - let config = env.package_config(package_name); + let config = context.env.package_config(package_name); if config.flavor != Flavor::Iota { // Skip if not iota return None; } - if !matches!( - minfo.target_kind, - TargetKind::Source { - is_root_package: true - } - ) { + if !matches!(minfo.target_kind, TargetKind::Source { + is_root_package: true + }) { // Skip non-source, dependency modules return None; } @@ -118,12 +122,25 @@ impl SimpleAbsIntConstructor for IDLeakVerifier { if let MemberName::Function(n) = &context.member { let should_skip = FUNCTIONS_TO_SKIP .iter() - .any(|to_skip| module.value.is(to_skip.0, to_skip.1) && n.value == to_skip.2); + .any(|to_skip| module.value.is(&to_skip.0, to_skip.1) && n.value == to_skip.2); if should_skip { return None; } } + // skip any function that doesn't create an object + cfg_satisfies( + cfg, + |_| true, + |e| { + use H::UnannotatedExp_ as E; + matches!( + &e.exp.value, + E::Pack(s, _, _) if minfo.structs.get(s).is_some_and(|s| s.abilities.has_ability_(Ability_::Key)), + ) + }, + ); + Some(IDLeakVerifierAI { module, info: context.info, @@ -156,7 +173,7 @@ impl<'a> SimpleAbsInt for IDLeakVerifierAI<'a> { state: &mut State, e: &Exp, ) -> Option> { - use crate::hlir::ast::UnannotatedExp_ as E; + use H::UnannotatedExp_ as E; let e__ = &e.exp.value; let E::Pack(s, _tys, fields) = e__ else { @@ -209,7 +226,7 @@ impl<'a> SimpleAbsInt for IDLeakVerifierAI<'a> { ) -> Option> { if FRESH_ID_FUNCTIONS .iter() - .any(|makes_fresh| f.is(makes_fresh.0, makes_fresh.1, makes_fresh.2)) + .any(|makes_fresh| f.is(&makes_fresh.0, makes_fresh.1, makes_fresh.2)) { return Some(vec![Value::FreshID(*loc)]); } @@ -222,7 +239,7 @@ impl<'a> SimpleAbsInt for IDLeakVerifierAI<'a> { } fn value_for_ty(loc: &Loc, sp!(_, t): &SingleType) -> Value { - if t.is_apply(IOTA_ADDR_NAME, OBJECT_MODULE_NAME, UID_TYPE_NAME) + if t.is_apply(&IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, UID_TYPE_NAME) .is_some() { Value::NotFresh(*loc) diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/info.rs b/external-crates/move/crates/move-compiler/src/iota_mode/info.rs new file mode 100644 index 00000000000..31b3f89bbba --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/iota_mode/info.rs @@ -0,0 +1,314 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! ProgramInfo extension for Iota Flavor +//! Contains information that may be expensive to compute and is needed only for Iota + +use std::{ + collections::{BTreeMap, BTreeSet}, + sync::Arc, +}; + +use crate::{ + diagnostics::warning_filters::WarningFilters, + expansion::ast::{Fields, ModuleIdent}, + naming::ast as N, + parser::ast::{Ability_, DatatypeName, Field}, + shared::{ + program_info::{DatatypeKind, TypingProgramInfo}, + unique_map::UniqueMap, + }, + iota_mode::{ + OBJECT_MODULE_NAME, IOTA_ADDR_VALUE, TRANSFER_FUNCTION_NAME, TRANSFER_MODULE_NAME, + UID_TYPE_NAME, + }, + typing::{ast as T, visitor::TypingVisitorContext}, + FullyCompiledProgram, +}; +use move_ir_types::location::Loc; +use move_proc_macros::growing_stack; + +#[derive(Debug, Clone, Copy)] +pub enum UIDHolder { + /// is `iota::object::UID`` + IsUID, + /// holds UID directly as one of the fields + Direct { field: Field, ty: Loc }, + /// holds a type which in turn `Direct`ly or `Indirect`ly holds UID + Indirect { field: Field, ty: Loc, uid: Loc }, +} + +#[derive(Debug, Clone, Copy)] +pub enum TransferKind { + /// The object has store + PublicTransfer(Loc), + /// transferred within the module to an address vis `iota::transfer::transfer` + PrivateTransfer(Loc), +} + +#[derive(Debug, Clone)] +pub struct IotaInfo { + /// All types that contain a UID, directly or indirectly + /// This requires a DFS traversal of type declarations + pub uid_holders: BTreeMap<(ModuleIdent, DatatypeName), UIDHolder>, + /// All types that either have store or are transferred privately + pub transferred: BTreeMap<(ModuleIdent, DatatypeName), TransferKind>, +} + +impl IotaInfo { + pub fn new( + pre_compiled_lib: Option>, + modules: &UniqueMap, + info: &TypingProgramInfo, + ) -> Self { + assert!(info.iota_flavor_info.is_none()); + let uid_holders = all_uid_holders(info); + let transferred = all_transferred(pre_compiled_lib, modules, info); + Self { + uid_holders, + transferred, + } + } +} + +/// DFS traversal to find all UID holders +fn all_uid_holders(info: &TypingProgramInfo) -> BTreeMap<(ModuleIdent, DatatypeName), UIDHolder> { + fn merge_uid_holder(u1: UIDHolder, u2: UIDHolder) -> UIDHolder { + match (u1, u2) { + (u @ UIDHolder::IsUID, _) | (_, u @ UIDHolder::IsUID) => u, + (d @ UIDHolder::Direct { .. }, _) | (_, d @ UIDHolder::Direct { .. }) => d, + (u1, _) => u1, + } + } + + fn merge_uid_holder_opt( + u1_opt: Option, + u2_opt: Option, + ) -> Option { + match (u1_opt, u2_opt) { + (Some(u1), Some(u2)) => Some(merge_uid_holder(u1, u2)), + (o1, o2) => o1.or(o2), + } + } + + // returns true if the type at the given position is a phantom type + fn phantom_positions( + info: &TypingProgramInfo, + sp!(_, tn_): &N::TypeName, + ) -> Vec { + match tn_ { + N::TypeName_::Multiple(n) => vec![false; *n], + N::TypeName_::Builtin(sp!(_, b_)) => b_ + .tparam_constraints(Loc::invalid()) + .into_iter() + .map(|_| false) + .collect(), + N::TypeName_::ModuleType(m, n) => { + let ty_params = match info.datatype_kind(m, n) { + DatatypeKind::Struct => &info.struct_definition(m, n).type_parameters, + DatatypeKind::Enum => &info.enum_definition(m, n).type_parameters, + }; + ty_params.iter().map(|tp| tp.is_phantom).collect() + } + } + } + + #[growing_stack] + fn visit_ty( + info: &TypingProgramInfo, + visited: &mut BTreeSet<(ModuleIdent, DatatypeName)>, + uid_holders: &mut BTreeMap<(ModuleIdent, DatatypeName), UIDHolder>, + sp!(_, ty_): &N::Type, + ) -> Option { + match ty_ { + N::Type_::Unit + | N::Type_::Param(_) + | N::Type_::Var(_) + | N::Type_::Fun(_, _) + | N::Type_::Anything + | N::Type_::UnresolvedError => None, + + N::Type_::Ref(_, inner) => visit_ty(info, visited, uid_holders, inner), + + N::Type_::Apply(_, sp!(_, tn_), _) + if tn_.is(&IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, UID_TYPE_NAME) => + { + Some(UIDHolder::IsUID) + } + + N::Type_::Apply(_, tn, tys) => { + let phantom_positions = phantom_positions(info, tn); + let ty_args_holder = tys + .iter() + .zip(phantom_positions) + .filter(|(_t, is_phantom)| *is_phantom) + .map(|(t, _is_phantom)| visit_ty(info, visited, uid_holders, t)) + .fold(None, merge_uid_holder_opt); + let tn_holder = if let N::TypeName_::ModuleType(m, n) = tn.value { + visit_decl(info, visited, uid_holders, m, n); + uid_holders.get(&(m, n)).copied() + } else { + None + }; + merge_uid_holder_opt(ty_args_holder, tn_holder) + } + } + } + + #[growing_stack] + fn visit_fields( + info: &TypingProgramInfo, + visited: &mut BTreeSet<(ModuleIdent, DatatypeName)>, + uid_holders: &mut BTreeMap<(ModuleIdent, DatatypeName), UIDHolder>, + fields: &Fields, + ) -> Option { + fields + .key_cloned_iter() + .map(|(field, (_, ty))| { + Some(match visit_ty(info, visited, uid_holders, ty)? { + UIDHolder::IsUID => UIDHolder::Direct { field, ty: ty.loc }, + UIDHolder::Direct { field, ty: uid } + | UIDHolder::Indirect { field, uid, ty: _ } => UIDHolder::Indirect { + field, + ty: ty.loc, + uid, + }, + }) + }) + .fold(None, merge_uid_holder_opt) + } + + #[growing_stack] + fn visit_decl( + info: &TypingProgramInfo, + visited: &mut BTreeSet<(ModuleIdent, DatatypeName)>, + uid_holders: &mut BTreeMap<(ModuleIdent, DatatypeName), UIDHolder>, + mident: ModuleIdent, + tn: DatatypeName, + ) { + if visited.contains(&(mident, tn)) { + return; + } + visited.insert((mident, tn)); + + let uid_holder_opt = match info.datatype_kind(&mident, &tn) { + DatatypeKind::Struct => match &info.struct_definition(&mident, &tn).fields { + N::StructFields::Defined(_, fields) => { + visit_fields(info, visited, uid_holders, fields) + } + N::StructFields::Native(_) => None, + }, + DatatypeKind::Enum => info + .enum_definition(&mident, &tn) + .variants + .iter() + .filter_map(|(_, _, v)| match &v.fields { + N::VariantFields::Defined(_, fields) => Some(fields), + N::VariantFields::Empty => None, + }) + .map(|fields| visit_fields(info, visited, uid_holders, fields)) + .fold(None, merge_uid_holder_opt), + }; + if let Some(uid_holder) = uid_holder_opt { + uid_holders.insert((mident, tn), uid_holder); + } + } + + // iterate over all struct/enum declarations + let visited = &mut BTreeSet::new(); + let mut uid_holders = BTreeMap::new(); + for (mident, mdef) in info.modules.key_cloned_iter() { + let datatypes = mdef + .structs + .key_cloned_iter() + .map(|(n, _)| n) + .chain(mdef.enums.key_cloned_iter().map(|(n, _)| n)); + for tn in datatypes { + visit_decl(info, visited, &mut uid_holders, mident, tn) + } + } + uid_holders +} + +fn all_transferred( + pre_compiled_lib: Option>, + modules: &UniqueMap, + info: &TypingProgramInfo, +) -> BTreeMap<(ModuleIdent, DatatypeName), TransferKind> { + let mut transferred = BTreeMap::new(); + for (mident, minfo) in info.modules.key_cloned_iter() { + for (s, sdef) in minfo.structs.key_cloned_iter() { + if !sdef.abilities.has_ability_(Ability_::Key) { + continue; + } + let Some(store_loc) = sdef.abilities.ability_loc_(Ability_::Store) else { + continue; + }; + transferred.insert((mident, s), TransferKind::PublicTransfer(store_loc)); + } + + let mdef = match modules.get(&mident) { + Some(mdef) => mdef, + None => pre_compiled_lib + .as_ref() + .unwrap() + .typing + .modules + .get(&mident) + .unwrap(), + }; + for (_, _, fdef) in &mdef.functions { + add_private_transfers(&mut transferred, fdef); + } + } + transferred +} + +fn add_private_transfers( + transferred: &mut BTreeMap<(ModuleIdent, DatatypeName), TransferKind>, + fdef: &T::Function, +) { + struct TransferVisitor<'a> { + transferred: &'a mut BTreeMap<(ModuleIdent, DatatypeName), TransferKind>, + } + impl<'a> TypingVisitorContext for TransferVisitor<'a> { + fn push_warning_filter_scope(&mut self, _: WarningFilters) { + unreachable!("no warning filters in function bodies") + } + + fn pop_warning_filter_scope(&mut self) { + unreachable!("no warning filters in function bodies") + } + + fn visit_exp_custom(&mut self, e: &T::Exp) -> bool { + use T::UnannotatedExp_ as E; + let E::ModuleCall(call) = &e.exp.value else { + return false; + }; + if !call.is( + &IOTA_ADDR_VALUE, + TRANSFER_MODULE_NAME, + TRANSFER_FUNCTION_NAME, + ) { + return false; + } + let [sp!(_, ty)] = call.type_arguments.as_slice() else { + return false; + }; + let Some(n) = ty.type_name().and_then(|t| t.value.datatype_name()) else { + return false; + }; + self.transferred + .entry(n) + .or_insert_with(|| TransferKind::PrivateTransfer(e.exp.loc)); + false + } + } + + let mut visitor = TransferVisitor { transferred }; + match &fdef.body.value { + T::FunctionBody_::Native | &T::FunctionBody_::Macro => (), + T::FunctionBody_::Defined(seq) => visitor.visit_seq(fdef.body.loc, seq), + } +} diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/coin_field.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/coin_field.rs index f958d2d47d1..b46f12bbf50 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/coin_field.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/coin_field.rs @@ -6,19 +6,18 @@ //! structs. In most cases it's preferable to use iota::balance::Balance instead //! to save space. -use move_ir_types::location::Loc; -use move_symbol_pool::Symbol; - use super::{ - LinterDiagnosticCategory, LinterDiagnosticCode, COIN_MOD_NAME, - COIN_STRUCT_NAME, IOTA_PKG_NAME, LINT_WARNING_PREFIX, + COIN_MOD_NAME, COIN_STRUCT_NAME, LINT_WARNING_PREFIX, LinterDiagnosticCategory, + LinterDiagnosticCode, }; use crate::{ diag, - diagnostics::codes::{custom, DiagnosticInfo, Severity}, + diagnostics::codes::{DiagnosticInfo, Severity, custom}, + expansion::ast::ModuleIdent, + iota_mode::IOTA_ADDR_VALUE, naming::ast as N, - shared::CompilationEnv, - typing::{ast as T, visitor::TypingVisitor}, + parser::ast::DatatypeName, + typing::{ast as T, visitor::simple_visitor}, }; const COIN_FIELD_DIAG: DiagnosticInfo = custom( @@ -29,40 +28,35 @@ const COIN_FIELD_DIAG: DiagnosticInfo = custom( "sub-optimal 'iota::coin::Coin' field type", ); -pub struct CoinFieldVisitor; - -impl TypingVisitor for CoinFieldVisitor { - fn visit(&mut self, env: &mut CompilationEnv, program: &mut T::Program) { - for (_, _, mdef) in program.modules.iter() { - if mdef.attributes.is_test_or_test_only() { - continue; - } - env.add_warning_filter_scope(mdef.warning_filter.clone()); - mdef.structs - .iter() - .filter(|(_, _, sdef)| !sdef.attributes.is_test_or_test_only()) - .for_each(|(sloc, sname, sdef)| struct_def(env, *sname, sdef, sloc)); - env.pop_warning_filter_scope(); +simple_visitor!( + CoinFieldVisitor, + fn visit_module_custom(&mut self, _ident: ModuleIdent, mdef: &T::ModuleDefinition) -> bool { + // skip if test only + mdef.attributes.is_test_or_test_only() + }, + // TODO enums + fn visit_struct_custom( + &mut self, + _module: ModuleIdent, + _sname: DatatypeName, + sdef: &N::StructDefinition, + ) -> bool { + if sdef.attributes.is_test_or_test_only() { + return false; } - } -} -fn struct_def(env: &mut CompilationEnv, sname: Symbol, sdef: &N::StructDefinition, sloc: Loc) { - env.add_warning_filter_scope(sdef.warning_filter.clone()); - - if let N::StructFields::Defined(_, sfields) = &sdef.fields { - for (floc, fname, (_, ftype)) in sfields.iter() { - if is_field_coin_type(ftype) { - let msg = format!("The field '{fname}' of '{sname}' has type 'iota::coin::Coin'"); - let uid_msg = "Storing 'iota::balance::Balance' in this field will typically be more space-efficient"; - let d = diag!(COIN_FIELD_DIAG, (sloc, msg), (floc, uid_msg)); - env.add_diag(d); + if let N::StructFields::Defined(_, sfields) = &sdef.fields { + for (_floc, _fname, (_, ftype)) in sfields { + if is_field_coin_type(ftype) { + let msg = "Sub-optimal 'iota::coin::Coin' field type. Using \ + 'iota::balance::Balance' instead will be more space efficient"; + self.add_diag(diag!(COIN_FIELD_DIAG, (ftype.loc, msg))); + } } } + false } - - env.pop_warning_filter_scope(); -} +); fn is_field_coin_type(sp!(_, t): &N::Type) -> bool { use N::Type_ as T; @@ -70,7 +64,7 @@ fn is_field_coin_type(sp!(_, t): &N::Type) -> bool { T::Ref(_, inner_t) => is_field_coin_type(inner_t), T::Apply(_, tname, _) => { let sp!(_, tname) = tname; - tname.is(IOTA_PKG_NAME, COIN_MOD_NAME, COIN_STRUCT_NAME) + tname.is(&IOTA_ADDR_VALUE, COIN_MOD_NAME, COIN_STRUCT_NAME) } T::Unit | T::Param(_) | T::Var(_) | T::Anything | T::UnresolvedError | T::Fun(_, _) => { false diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/collection_equality.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/collection_equality.rs index fe6c879c2ba..0f9ebdf7d7b 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/collection_equality.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/collection_equality.rs @@ -7,27 +7,22 @@ //! (in)equality at this type of comparison is not very useful and DOES NOT take //! into consideration structural (in)equality. +use move_core_types::account_address::AccountAddress; +use move_symbol_pool::Symbol; + use super::{ - base_type, LinterDiagnosticCategory, LinterDiagnosticCode, BAG_MOD_NAME, - BAG_STRUCT_NAME, IOTA_PKG_NAME, LINKED_TABLE_MOD_NAME, LINKED_TABLE_STRUCT_NAME, - LINT_WARNING_PREFIX, OBJECT_BAG_MOD_NAME, OBJECT_BAG_STRUCT_NAME, - OBJECT_TABLE_MOD_NAME, OBJECT_TABLE_STRUCT_NAME, TABLE_MOD_NAME, TABLE_STRUCT_NAME, - TABLE_VEC_MOD_NAME, TABLE_VEC_STRUCT_NAME, VEC_MAP_MOD_NAME, VEC_MAP_STRUCT_NAME, - VEC_SET_MOD_NAME, VEC_SET_STRUCT_NAME, + BAG_MOD_NAME, BAG_STRUCT_NAME, LINKED_TABLE_MOD_NAME, LINKED_TABLE_STRUCT_NAME, + LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode, OBJECT_BAG_MOD_NAME, + OBJECT_BAG_STRUCT_NAME, OBJECT_TABLE_MOD_NAME, OBJECT_TABLE_STRUCT_NAME, TABLE_MOD_NAME, + TABLE_STRUCT_NAME, TABLE_VEC_MOD_NAME, TABLE_VEC_STRUCT_NAME, VEC_MAP_MOD_NAME, + VEC_MAP_STRUCT_NAME, VEC_SET_MOD_NAME, VEC_SET_STRUCT_NAME, }; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, - naming::ast as N, + diagnostics::codes::{DiagnosticInfo, Severity, custom}, + iota_mode::{IOTA_ADDR_NAME, IOTA_ADDR_VALUE}, parser::ast as P, - shared::{CompilationEnv, Identifier}, - typing::{ - ast as T, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, - }, + typing::{ast as T, visitor::simple_visitor}, }; const COLLECTIONS_EQUALITY_DIAG: DiagnosticInfo = custom( @@ -38,81 +33,88 @@ const COLLECTIONS_EQUALITY_DIAG: DiagnosticInfo = custom( "possibly useless collections compare", ); -const COLLECTION_TYPES: &[(&str, &str, &str)] = &[ - (IOTA_PKG_NAME, BAG_MOD_NAME, BAG_STRUCT_NAME), - (IOTA_PKG_NAME, OBJECT_BAG_MOD_NAME, OBJECT_BAG_STRUCT_NAME), - (IOTA_PKG_NAME, TABLE_MOD_NAME, TABLE_STRUCT_NAME), +const COLLECTION_TYPES: &[(Symbol, AccountAddress, &str, &str)] = &[ + ( + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, + BAG_MOD_NAME, + BAG_STRUCT_NAME, + ), + ( + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, + OBJECT_BAG_MOD_NAME, + OBJECT_BAG_STRUCT_NAME, + ), + ( + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, + TABLE_MOD_NAME, + TABLE_STRUCT_NAME, + ), ( - IOTA_PKG_NAME, + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, OBJECT_TABLE_MOD_NAME, OBJECT_TABLE_STRUCT_NAME, ), ( - IOTA_PKG_NAME, + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, LINKED_TABLE_MOD_NAME, LINKED_TABLE_STRUCT_NAME, ), - (IOTA_PKG_NAME, TABLE_VEC_MOD_NAME, TABLE_VEC_STRUCT_NAME), - (IOTA_PKG_NAME, VEC_MAP_MOD_NAME, VEC_MAP_STRUCT_NAME), - (IOTA_PKG_NAME, VEC_SET_MOD_NAME, VEC_SET_STRUCT_NAME), + ( + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, + TABLE_VEC_MOD_NAME, + TABLE_VEC_STRUCT_NAME, + ), + ( + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, + VEC_MAP_MOD_NAME, + VEC_MAP_STRUCT_NAME, + ), + ( + IOTA_ADDR_NAME, + IOTA_ADDR_VALUE, + VEC_SET_MOD_NAME, + VEC_SET_STRUCT_NAME, + ), ]; -pub struct CollectionEqualityVisitor; -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} - -impl TypingVisitorConstructor for CollectionEqualityVisitor { - type Context<'a> = Context<'a>; - - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { - fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { +simple_visitor!( + CollectionEqualityVisitor, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { use T::UnannotatedExp_ as E; if let E::BinopExp(_, op, t, _) = &exp.exp.value { if op.value != P::BinOp_::Eq && op.value != P::BinOp_::Neq { // not a comparison return false; } - let Some(bt) = base_type(t) else { - return false; - }; - let N::Type_::Apply(_, tname, _) = &bt.value else { - return false; - }; - let N::TypeName_::ModuleType(mident, sname) = tname.value else { + let Some(sp!(_, tn_)) = t.value.unfold_to_type_name() else { + // no type name return false; }; - - if let Some((caddr, cmodule, cname)) = - COLLECTION_TYPES.iter().find(|(caddr, cmodule, cname)| { - mident.value.is(*caddr, *cmodule) && sname.value().as_str() == *cname - }) + if let Some((caddr_name, _, cmodule, cname)) = COLLECTION_TYPES + .iter() + .find(|(_, caddr_value, cmodule, cname)| tn_.is(caddr_value, *cmodule, *cname)) { let msg = format!( - "Comparing collections of type '{caddr}::{cmodule}::{cname}' may yield unexpected result." + "Comparing collections of type '{caddr_name}::{cmodule}::{cname}' \ + may yield unexpected result." ); let note_msg = format!( - "Equality for collections of type '{caddr}::{cmodule}::{cname}' IS NOT a structural check based on content" + "Equality for collections of type '{caddr_name}::{cmodule}::{cname}' \ + IS NOT a structural check based on content" ); let mut d = diag!(COLLECTIONS_EQUALITY_DIAG, (op.loc, msg),); d.add_note(note_msg); - self.env.add_diag(d); + self.add_diag(d); return true; } } false } - - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } -} +); diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/custom_state_change.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/custom_state_change.rs index 2ed20cda313..97663bd7c3c 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/custom_state_change.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/custom_state_change.rs @@ -11,39 +11,43 @@ //! with a store ability and passes it as an argument to a "private" //! transfer/share/freeze call. +use std::collections::BTreeMap; + +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; +use super::{ + FREEZE_FUN, INVALID_LOC, LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode, + RECEIVE_FUN, SHARE_FUN, TRANSFER_FUN, TRANSFER_MOD_NAME, +}; use crate::{ cfgir::{ + CFGContext, MemberName, absint::JoinResult, + cfg::ImmForwardCFG, visitor::{ - LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, SimpleExecutionContext, + LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, + SimpleExecutionContext, calls_special_function, }, - CFGContext, MemberName, }, diag, diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, Diagnostic, Diagnostics, + codes::{DiagnosticInfo, Severity, custom}, }, hlir::ast::{ - BaseType_, Label, ModuleCall, SingleType, SingleType_, Type, TypeName_, Type_, Var, + BaseType_, Label, ModuleCall, SingleType, SingleType_, Type, Type_, TypeName_, Var, }, + iota_mode::IOTA_ADDR_VALUE, parser::ast::Ability_, - shared::{CompilationEnv, Identifier}, -}; -use std::collections::BTreeMap; - -use super::{ - LinterDiagnosticCategory, LinterDiagnosticCode, FREEZE_FUN, INVALID_LOC, LINT_WARNING_PREFIX, - RECEIVE_FUN, SHARE_FUN, IOTA_PKG_NAME, TRANSFER_FUN, TRANSFER_MOD_NAME, + shared::Identifier, }; -const PRIVATE_OBJ_FUNCTIONS: &[(&str, &str, &str)] = &[ - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, TRANSFER_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, SHARE_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, FREEZE_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, RECEIVE_FUN), +const PRIVATE_OBJ_FUNCTIONS: &[(AccountAddress, &str, &str)] = &[ + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, TRANSFER_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, SHARE_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, FREEZE_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, RECEIVE_FUN), ]; const CUSTOM_STATE_CHANGE_DIAG: DiagnosticInfo = custom( @@ -89,14 +93,30 @@ impl SimpleAbsIntConstructor for CustomStateChangeVerifier { type AI<'a> = CustomStateChangeVerifierAI; fn new<'a>( - _env: &CompilationEnv, context: &'a CFGContext<'a>, - _init_state: &mut State, + cfg: &ImmForwardCFG, + init_state: &mut State, ) -> Option> { let MemberName::Function(fn_name) = context.member else { return None; }; + if !init_state + .locals + .values() + .any(|state| matches!(state, LocalState::Available(_, Value::LocalObjWithStore(_)))) + { + // if there is no object parameter with store, we can skip the function + // since this is the only case which will trigger the warning + return None; + } + + if !calls_special_function(PRIVATE_OBJ_FUNCTIONS, cfg) { + // if the function does not call any of the private transfer functions, we can + // skip it + return None; + } + Some(CustomStateChangeVerifierAI { fn_name_loc: fn_name.loc, }) @@ -136,27 +156,22 @@ impl SimpleAbsInt for CustomStateChangeVerifierAI { .find(|(addr, module, fun)| f.is(addr, module, fun)) { if let Value::LocalObjWithStore(obj_addr_loc) = args[0] { - let msg = format!( - "Potential unintended implementation of a custom {} function.", - fname - ); - let (op, action) = if *fname == TRANSFER_FUN { - ("transfer", "transferred") - } else if *fname == SHARE_FUN { - ("share", "shared") - } else if *fname == FREEZE_FUN { - ("freeze", "frozen") - } else { - ("receive", "received") + let (op, action) = match *fname { + TRANSFER_FUN => ("transfer", "transferred"), + SHARE_FUN => ("share", "shared"), + FREEZE_FUN => ("freeze", "frozen"), + RECEIVE_FUN => ("receive", "received"), + s => unimplemented!("Unexpected private obj function {s}"), }; + let msg = format!("Potential unintended implementation of a custom {op} function."); let uid_msg = format!( - "Instances of a type with a store ability can be {action} using \ - the public_{fname} function which often negates the intent \ - of enforcing a custom {op} policy" + "Instances of a type with a 'store' ability can be {action} using \ + the 'public_{fname}' function which often negates the intent \ + of enforcing a custom {op} policy" ); let note_msg = format!( - "A custom {op} policy for a given type is implemented through calling \ - the private {fname} function variant in the module defining this type" + "A custom {op} policy for a given type is implemented through \ + calling the private '{fname}' function variant in the module defining this type" ); let mut d = diag!( CUSTOM_STATE_CHANGE_DIAG, @@ -166,8 +181,8 @@ impl SimpleAbsInt for CustomStateChangeVerifierAI { d.add_note(note_msg); if obj_addr_loc != INVALID_LOC { let loc_msg = format!( - "An instance of a module-private type with a store ability to be {} coming from here", - action + "An instance of a module-private type with a \ + 'store' ability to be {action} coming from here" ); d.add_secondary_label((obj_addr_loc, loc_msg)); } @@ -210,6 +225,7 @@ impl SimpleDomain for State { for (_mut, v, st) in &context.signature.parameters { if is_local_obj_with_store(st, context) { let local_state = locals.get_mut(v).unwrap(); + debug_assert!(matches!(local_state, LocalState::Available(_, _))); if let LocalState::Available(loc, _) = local_state { *local_state = LocalState::Available(*loc, Value::LocalObjWithStore(*loc)); } diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/freeze_wrapped.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/freeze_wrapped.rs index 1caef52b254..6945bcb119f 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/freeze_wrapped.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/freeze_wrapped.rs @@ -8,24 +8,28 @@ use std::{collections::BTreeMap, sync::Arc}; +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; use move_symbol_pool::Symbol; -use super::{ - base_type, LinterDiagnosticCategory, LinterDiagnosticCode, FREEZE_FUN, - IOTA_PKG_NAME, LINT_WARNING_PREFIX, PUBLIC_FREEZE_FUN, - TRANSFER_MOD_NAME, -}; use crate::{ diag, diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, + Diagnostic, DiagnosticReporter, Diagnostics, + codes::{DiagnosticInfo, Severity, custom}, + warning_filters::WarningFilters, }, expansion::ast as E, + iota_mode::{ + IOTA_ADDR_VALUE, + linters::{ + FREEZE_FUN, LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode, + PUBLIC_FREEZE_FUN, TRANSFER_MOD_NAME, + }, + }, naming::ast as N, parser::ast::{self as P, Ability_}, - shared::{program_info::TypingProgramInfo, CompilationEnv, Identifier}, + shared::{CompilationEnv, Identifier, program_info::TypingProgramInfo}, typing::{ ast as T, visitor::{TypingVisitorConstructor, TypingVisitorContext}, @@ -40,9 +44,9 @@ const FREEZE_WRAPPING_DIAG: DiagnosticInfo = custom( "attempting to freeze wrapped objects", ); -const FREEZE_FUNCTIONS: &[(&str, &str, &str)] = &[ - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, PUBLIC_FREEZE_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, FREEZE_FUN), +const FREEZE_FUNCTIONS: &[(AccountAddress, &str, &str)] = &[ + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, PUBLIC_FREEZE_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, FREEZE_FUN), ]; /// Information about a field that wraps other objects. @@ -76,7 +80,9 @@ type WrappingFields = pub struct FreezeWrappedVisitor; pub struct Context<'a> { - env: &'a mut CompilationEnv, + #[allow(unused)] + env: &'a CompilationEnv, + reporter: DiagnosticReporter<'a>, program_info: Arc, /// Memoizes information about struct fields wrapping other objects as they /// are discovered @@ -86,21 +92,30 @@ pub struct Context<'a> { impl TypingVisitorConstructor for FreezeWrappedVisitor { type Context<'a> = Context<'a>; - fn context<'a>(env: &'a mut CompilationEnv, program: &T::Program) -> Self::Context<'a> { + fn context<'a>(env: &'a CompilationEnv, program: &T::Program) -> Self::Context<'a> { + let reporter = env.diagnostic_reporter_at_top_level(); Context { env, + reporter, program_info: program.info.clone(), wrapping_fields: WrappingFields::new(), } } } +impl Context<'_> { + fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } +} + impl<'a> TypingVisitorContext for Context<'a> { - fn visit_module_custom( - &mut self, - _ident: E::ModuleIdent, - mdef: &mut T::ModuleDefinition, - ) -> bool { + fn visit_module_custom(&mut self, _ident: E::ModuleIdent, mdef: &T::ModuleDefinition) -> bool { // skips if true mdef.attributes.is_test_or_test_only() } @@ -109,33 +124,27 @@ impl<'a> TypingVisitorContext for Context<'a> { &mut self, _module: E::ModuleIdent, _function_name: P::FunctionName, - fdef: &mut T::Function, + fdef: &T::Function, ) -> bool { // skips if true fdef.attributes.is_test_or_test_only() } - fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { use T::UnannotatedExp_ as E; if let E::ModuleCall(fun) = &exp.exp.value { if FREEZE_FUNCTIONS.iter().any(|(addr, module, fname)| { - fun.module.value.is(*addr, *module) && &fun.name.value().as_str() == fname + fun.module.value.is(addr, *module) && &fun.name.value().as_str() == fname }) { - let Some(bt) = base_type(&fun.type_arguments[0]) else { - // not an (potentially dereferenced) N::Type_::Apply nor N::Type_::Param - return false; - }; - let N::Type_::Apply(_, tname, _) = &bt.value else { - // not a struct type - return false; - }; - let N::TypeName_::ModuleType(mident, sname) = tname.value else { + let Some(sp!(_, N::TypeName_::ModuleType(mident, sname))) = + fun.type_arguments[0].value.type_name() + else { // struct with a given name not found return false; }; if let Some(wrapping_field_info) = self.find_wrapping_field_loc(mident, sname) { add_diag( - self.env, + self, fun.arguments.exp.loc, sname.value(), wrapping_field_info, @@ -147,12 +156,12 @@ impl<'a> TypingVisitorContext for Context<'a> { false } - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) + fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) } fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() + self.reporter.pop_warning_filter_scope() } } @@ -178,7 +187,7 @@ impl<'a> Context<'a> { let sloc = self.program_info.struct_declared_loc(mident, sname); Some((sloc, true)) } else { - self.find_wrapping_field_loc(*mident, *sname) + self.find_wrapping_field_loc(mident, sname) .as_ref() .map(|info| (info.wrapped_type_loc, false)) } @@ -201,34 +210,31 @@ impl<'a> Context<'a> { /// information is included as well. fn find_wrapping_field_loc( &mut self, - mident: E::ModuleIdent, - sname: P::DatatypeName, + mident: &E::ModuleIdent, + sname: &P::DatatypeName, ) -> Option { - let memoized_info = self - .wrapping_fields - .get(&mident) - .and_then(|m| m.get(&sname)); + let memoized_info = self.wrapping_fields.get(mident).and_then(|m| m.get(sname)); if memoized_info.is_none() { let info = self.find_wrapping_field_loc_impl(mident, sname); self.wrapping_fields - .entry(mident) + .entry(*mident) .or_default() - .insert(sname, info); + .insert(*sname, info); } *self .wrapping_fields - .get(&mident) - .and_then(|m| m.get(&sname)) + .get(mident) + .and_then(|m| m.get(sname)) .unwrap() } fn find_wrapping_field_loc_impl( &mut self, - mident: E::ModuleIdent, - sname: P::DatatypeName, + mident: &E::ModuleIdent, + sname: &P::DatatypeName, ) -> Option { let info = self.program_info.clone(); - let sdef = info.struct_definition(&mident, &sname); + let sdef = info.struct_definition(mident, sname); let N::StructFields::Defined(_, sfields) = &sdef.fields else { return None; }; @@ -242,7 +248,7 @@ impl<'a> Context<'a> { } fn add_diag( - env: &mut CompilationEnv, + context: &mut Context, freeze_arg_loc: Loc, frozen_struct_name: Symbol, info: WrappingFieldInfo, @@ -270,5 +276,5 @@ fn add_diag( if !direct { d.add_secondary_label((wrapped_tloc, "Indirectly wrapped object is of this type")); } - env.add_diag(d); + context.add_diag(d); } diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/freezing_capability.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/freezing_capability.rs index e55ff3b48d5..42676c0530b 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/freezing_capability.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/freezing_capability.rs @@ -2,27 +2,28 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Implements lint to warn against freezing capability-like types in Iota, identifying function calls that may incorrectly freeze such types. -//! The lint checks for specific freezing functions defined in constants and inspects their type arguments for capability-like type names. +//! Implements lint to warn against freezing capability-like types in Iota, +//! identifying function calls that may incorrectly freeze such types. +//! The lint checks for specific freezing functions defined in constants and +//! inspects their type arguments for capability-like type names. -use super::{LinterDiagnosticCategory, LinterDiagnosticCode, LINT_WARNING_PREFIX}; +use move_core_types::account_address::AccountAddress; +use move_ir_types::location::*; +use once_cell::sync::Lazy; +use regex::Regex; + +use super::{LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode}; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, + diagnostics::codes::{DiagnosticInfo, Severity, custom}, + iota_mode::{ + IOTA_ADDR_VALUE, + linters::{FREEZE_FUN, PUBLIC_FREEZE_FUN, TRANSFER_MOD_NAME}, }, naming::ast::TypeName_, - shared::{CompilationEnv, Identifier}, - iota_mode::linters::{FREEZE_FUN, PUBLIC_FREEZE_FUN, IOTA_PKG_NAME, TRANSFER_MOD_NAME}, - typing::{ - ast as T, core, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, - }, + shared::Identifier, + typing::{ast as T, core, visitor::simple_visitor}, }; -use move_ir_types::location::*; -use once_cell::sync::Lazy; -use regex::Regex; const FREEZE_CAPABILITY_DIAG: DiagnosticInfo = custom( LINT_WARNING_PREFIX, @@ -32,47 +33,33 @@ const FREEZE_CAPABILITY_DIAG: DiagnosticInfo = custom( "freezing potential capability", ); -const FREEZE_FUNCTIONS: &[(&str, &str, &str)] = &[ - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, PUBLIC_FREEZE_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, FREEZE_FUN), +const FREEZE_FUNCTIONS: &[(AccountAddress, &str, &str)] = &[ + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, PUBLIC_FREEZE_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, FREEZE_FUN), ]; -pub struct WarnFreezeCapability; - -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} - static REGEX: Lazy = Lazy::new(|| Regex::new(r".*Cap(?:[A-Z0-9_]+|ability|$).*").unwrap()); -impl TypingVisitorConstructor for WarnFreezeCapability { - type Context<'a> = Context<'a>; - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl<'a> TypingVisitorContext for Context<'a> { +simple_visitor!( + WarnFreezeCapability, fn visit_module_custom( &mut self, _ident: crate::expansion::ast::ModuleIdent, - mdef: &mut T::ModuleDefinition, + mdef: &T::ModuleDefinition, ) -> bool { // skips if true mdef.attributes.is_test_or_test_only() - } - + }, fn visit_function_custom( &mut self, _module: crate::expansion::ast::ModuleIdent, _function_name: crate::parser::ast::FunctionName, - fdef: &mut T::Function, + fdef: &T::Function, ) -> bool { // skips if true fdef.attributes.is_test_or_test_only() - } - - fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { + }, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { if let T::UnannotatedExp_::ModuleCall(fun) = &exp.exp.value { if is_freeze_function(fun) { check_type_arguments(self, fun, exp.exp.loc); @@ -80,19 +67,11 @@ impl<'a> TypingVisitorContext for Context<'a> { } false } - - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } -} +); fn is_freeze_function(fun: &T::ModuleCall) -> bool { FREEZE_FUNCTIONS.iter().any(|(addr, module, fname)| { - fun.module.value.is(*addr, *module) && &fun.name.value().as_str() == fname + fun.module.value.is(addr, *module) && &fun.name.value().as_str() == fname }) } @@ -111,7 +90,7 @@ fn check_type_arguments(context: &mut Context, fun: &T::ModuleCall, loc: Loc) { "Freezing a capability might lock out critical operations \ or otherwise open access to operations that otherwise should be restricted", ); - context.env.add_diag(diag); + context.add_diag(diag); }; } } diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/missing_key.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/missing_key.rs index 7e565ecb7e4..7058b4311fa 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/missing_key.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/missing_key.rs @@ -2,24 +2,18 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! This linter rule checks for structs with an `id` field of type `UID` without the `key` ability. +//! This linter rule checks for structs with an `id` field of type `UID` without +//! the `key` ability. -use super::{LinterDiagnosticCategory, LinterDiagnosticCode, LINT_WARNING_PREFIX}; -use crate::expansion::ast::ModuleIdent; -use crate::parser::ast::DatatypeName; +use super::{LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode}; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, + diagnostics::codes::{DiagnosticInfo, Severity, custom}, + expansion::ast::ModuleIdent, + iota_mode::{ID_FIELD_NAME, IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, UID_TYPE_NAME}, naming::ast::{StructDefinition, StructFields}, - parser::ast::Ability_, - shared::CompilationEnv, - typing::{ - ast as T, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, - }, + parser::ast::{Ability_, DatatypeName}, + typing::visitor::simple_visitor, }; const MISSING_KEY_ABILITY_DIAG: DiagnosticInfo = custom( @@ -30,48 +24,31 @@ const MISSING_KEY_ABILITY_DIAG: DiagnosticInfo = custom( "struct with id but missing key ability", ); -pub struct MissingKeyVisitor; - -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} -impl TypingVisitorConstructor for MissingKeyVisitor { - type Context<'a> = Context<'a>; - - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } - +simple_visitor!( + MissingKeyVisitor, fn visit_struct_custom( &mut self, _module: ModuleIdent, _struct_name: DatatypeName, - sdef: &mut StructDefinition, + sdef: &StructDefinition, ) -> bool { if first_field_has_id_field_of_type_uid(sdef) && lacks_key_ability(sdef) { - let uid_msg = - "Struct's first field has an 'id' field of type 'iota::object::UID' but is missing the 'key' ability."; + let uid_msg = "Struct's first field has an 'id' field of type 'iota::object::UID' but is missing the 'key' ability."; let diagnostic = diag!(MISSING_KEY_ABILITY_DIAG, (sdef.loc, uid_msg)); - self.env.add_diag(diagnostic); + self.add_diag(diagnostic); } false } -} +); fn first_field_has_id_field_of_type_uid(sdef: &StructDefinition) -> bool { match &sdef.fields { StructFields::Defined(_, fields) => fields.iter().any(|(_, symbol, (idx, ty))| { - *idx == 0 && symbol == &symbol!("id") && ty.value.is("iota", "object", "UID") + *idx == 0 + && symbol == &ID_FIELD_NAME + && ty + .value + .is(&IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, UID_TYPE_NAME) }), StructFields::Native(_) => false, } diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/mod.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/mod.rs index f99876be629..dfef04a22b5 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/mod.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/mod.rs @@ -8,11 +8,10 @@ use move_symbol_pool::Symbol; use crate::{ cfgir::visitor::AbstractInterpreterVisitor, command_line::compiler::Visitor, - diagnostics::codes::WarningFilter, + diagnostics::warning_filters::WarningFilter, expansion::ast as E, hlir::ast::{BaseType_, SingleType, SingleType_}, - linters::{LintLevel, LinterDiagnosticCategory, ALLOW_ATTR_CATEGORY, LINT_WARNING_PREFIX}, - naming::ast as N, + linters::{ALLOW_ATTR_CATEGORY, LINT_WARNING_PREFIX, LintLevel, LinterDiagnosticCategory}, typing::visitor::TypingVisitor, }; @@ -27,8 +26,6 @@ pub mod public_random; pub mod self_transfer; pub mod share_owned; -pub const IOTA_PKG_NAME: &str = "iota"; - pub const TRANSFER_MOD_NAME: &str = "transfer"; pub const TRANSFER_FUN: &str = "transfer"; pub const PUBLIC_TRANSFER_FUN: &str = "public_transfer"; @@ -189,15 +186,6 @@ pub fn linter_visitors(level: LintLevel) -> Vec { } } -pub fn base_type(t: &N::Type) -> Option<&N::Type> { - use N::Type_ as T; - match &t.value { - T::Ref(_, inner_t) => base_type(inner_t), - T::Apply(_, _, _) | T::Param(_) => Some(t), - T::Unit | T::Var(_) | T::Anything | T::UnresolvedError | T::Fun(_, _) => None, - } -} - /// Returns abilities of a given type, if any. pub fn type_abilities(sp!(_, st_): &SingleType) -> Option { let sp!(_, bt_) = match st_ { diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_mut_tx_context.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_mut_tx_context.rs index 169a3455f1c..b4b2f89b5be 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_mut_tx_context.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_mut_tx_context.rs @@ -2,28 +2,24 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Enforces that public functions use `&mut TxContext` instead of `&TxContext` to ensure upgradability. -//! Detects and reports instances where a non-mutable reference to `TxContext` is used in public function signatures. -//! Promotes best practices for future-proofing smart contract code by allowing mutation of the transaction context. -use super::{LinterDiagnosticCategory, LinterDiagnosticCode, LINT_WARNING_PREFIX}; +//! Enforces that public functions use `&mut TxContext` instead of `&TxContext` +//! to ensure upgradability. Detects and reports instances where a non-mutable +//! reference to `TxContext` is used in public function signatures. +//! Promotes best practices for future-proofing smart contract code by allowing +//! mutation of the transaction context. +use move_ir_types::location::Loc; + +use super::{LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode}; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, + diagnostics::codes::{DiagnosticInfo, Severity, custom}, expansion::ast::{ModuleIdent, Visibility}, + iota_mode::{IOTA_ADDR_VALUE, TX_CONTEXT_MODULE_NAME, TX_CONTEXT_TYPE_NAME}, naming::ast::Type_, parser::ast::FunctionName, - shared::CompilationEnv, - iota_mode::{IOTA_ADDR_NAME, TX_CONTEXT_MODULE_NAME, TX_CONTEXT_TYPE_NAME}, - typing::{ - ast as T, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, - }, + typing::{ast as T, visitor::simple_visitor}, }; -use move_ir_types::location::Loc; const REQUIRE_MUTABLE_TX_CONTEXT_DIAG: DiagnosticInfo = custom( LINT_WARNING_PREFIX, @@ -33,38 +29,17 @@ const REQUIRE_MUTABLE_TX_CONTEXT_DIAG: DiagnosticInfo = custom( "prefer '&mut TxContext' over '&TxContext'", ); -pub struct PreferMutableTxContext; - -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} - -impl TypingVisitorConstructor for PreferMutableTxContext { - type Context<'a> = Context<'a>; - - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } - - fn visit_module_custom(&mut self, ident: ModuleIdent, _mdef: &mut T::ModuleDefinition) -> bool { +simple_visitor!( + PreferMutableTxContext, + fn visit_module_custom(&mut self, ident: ModuleIdent, _mdef: &T::ModuleDefinition) -> bool { // skip if in 'iota::tx_context' - ident.value.is(IOTA_ADDR_NAME, TX_CONTEXT_MODULE_NAME) - } - + ident.value.is(&IOTA_ADDR_VALUE, TX_CONTEXT_MODULE_NAME) + }, fn visit_function_custom( &mut self, _module: ModuleIdent, _function_name: FunctionName, - fdef: &mut T::Function, + fdef: &T::Function, ) -> bool { if !matches!(&fdef.visibility, Visibility::Public(_)) { return false; @@ -73,17 +48,17 @@ impl TypingVisitorContext for Context<'_> { for (_, _, sp!(loc, param_ty_)) in &fdef.signature.parameters { if matches!( param_ty_, - Type_::Ref(false, t) if t.value.is(IOTA_ADDR_NAME, TX_CONTEXT_MODULE_NAME, TX_CONTEXT_TYPE_NAME), + Type_::Ref(false, t) if t.value.is(&IOTA_ADDR_VALUE, TX_CONTEXT_MODULE_NAME, TX_CONTEXT_TYPE_NAME), ) { - report_non_mutable_tx_context(self.env, *loc); + report_non_mutable_tx_context(self, *loc); } } false } -} +); -fn report_non_mutable_tx_context(env: &mut CompilationEnv, loc: Loc) { +fn report_non_mutable_tx_context(context: &mut Context, loc: Loc) { let msg = format!( "'public' functions should prefer '&mut {0}' over '&{0}' for better upgradability.", TX_CONTEXT_TYPE_NAME @@ -94,5 +69,5 @@ fn report_non_mutable_tx_context(env: &mut CompilationEnv, loc: Loc) { of '&TxContext'. As such, it is recommended to consider using '&mut TxContext' to \ future-proof the function.", ); - env.add_diag(diag); + context.add_diag(diag); } diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_random.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_random.rs index 0fb46825f87..762b4339d5a 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_random.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/public_random.rs @@ -6,24 +6,17 @@ //! public functions. use super::{ - LinterDiagnosticCategory, LinterDiagnosticCode, IOTA_PKG_NAME, LINT_WARNING_PREFIX, + LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode, RANDOM_GENERATOR_STRUCT_NAME, RANDOM_MOD_NAME, RANDOM_STRUCT_NAME, }; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, + diagnostics::codes::{DiagnosticInfo, Severity, custom}, expansion::ast::{ModuleIdent, Visibility}, - iota_mode::IOTA_ADDR_NAME, + iota_mode::{IOTA_ADDR_NAME, IOTA_ADDR_VALUE}, naming::ast as N, parser::ast::FunctionName, - shared::CompilationEnv, - typing::{ - ast as T, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, - }, + typing::{ast as T, visitor::simple_visitor}, }; const PUBLIC_RANDOM_DIAG: DiagnosticInfo = custom( @@ -34,38 +27,17 @@ const PUBLIC_RANDOM_DIAG: DiagnosticInfo = custom( "Risky use of 'iota::random'", ); -pub struct PublicRandomVisitor; -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} - -impl TypingVisitorConstructor for PublicRandomVisitor { - type Context<'a> = Context<'a>; - - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } - - fn visit_module_custom(&mut self, ident: ModuleIdent, mdef: &mut T::ModuleDefinition) -> bool { +simple_visitor!( + PublicRandomVisitor, + fn visit_module_custom(&mut self, ident: ModuleIdent, mdef: &T::ModuleDefinition) -> bool { // skips if true - mdef.attributes.is_test_or_test_only() || ident.value.address.is(IOTA_ADDR_NAME) - } - + mdef.attributes.is_test_or_test_only() || ident.value.address.is(&IOTA_ADDR_VALUE) + }, fn visit_function_custom( &mut self, _module: ModuleIdent, fname: FunctionName, - fdef: &mut T::Function, + fdef: &T::Function, ) -> bool { if fdef.attributes.is_test_or_test_only() || !matches!(fdef.visibility, Visibility::Public(_)) @@ -80,25 +52,29 @@ impl TypingVisitorContext for Context<'_> { let mut d = diag!(PUBLIC_RANDOM_DIAG, (tloc, msg)); let note = format!( "Functions that accept '{}::{}::{}' as a parameter might be abused by attackers by inspecting the results of randomness", - IOTA_PKG_NAME, RANDOM_MOD_NAME, struct_name + IOTA_ADDR_NAME, RANDOM_MOD_NAME, struct_name ); d.add_note(note); d.add_note("Non-public functions are preferred"); - self.env.add_diag(d); + self.add_diag(d); } } true } -} +); fn is_random_or_random_generator(sp!(_, t): &N::Type) -> Option<&str> { use N::Type_ as T; match t { T::Ref(_, inner_t) => is_random_or_random_generator(inner_t), T::Apply(_, sp!(_, tname), _) => { - if tname.is(IOTA_PKG_NAME, RANDOM_MOD_NAME, RANDOM_STRUCT_NAME) { + if tname.is(&IOTA_ADDR_VALUE, RANDOM_MOD_NAME, RANDOM_STRUCT_NAME) { Some(RANDOM_STRUCT_NAME) - } else if tname.is(IOTA_PKG_NAME, RANDOM_MOD_NAME, RANDOM_GENERATOR_STRUCT_NAME) { + } else if tname.is( + &IOTA_ADDR_VALUE, + RANDOM_MOD_NAME, + RANDOM_GENERATOR_STRUCT_NAME, + ) { Some(RANDOM_GENERATOR_STRUCT_NAME) } else { None diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/self_transfer.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/self_transfer.rs index 714575d6bd5..fc94103cdc9 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/self_transfer.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/self_transfer.rs @@ -7,34 +7,36 @@ use std::collections::BTreeMap; +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; use super::{ - type_abilities, LinterDiagnosticCategory, LinterDiagnosticCode, - INVALID_LOC, IOTA_PKG_NAME, LINT_WARNING_PREFIX, PUBLIC_TRANSFER_FUN, - TRANSFER_FUN, TRANSFER_MOD_NAME, + INVALID_LOC, LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode, + PUBLIC_TRANSFER_FUN, TRANSFER_FUN, TRANSFER_MOD_NAME, type_abilities, }; use crate::{ cfgir::{ + CFGContext, MemberName, absint::JoinResult, + cfg::ImmForwardCFG, visitor::{ - LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, SimpleExecutionContext, + LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, + SimpleExecutionContext, calls_special_function, }, - CFGContext, MemberName, }, diag, diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, Diagnostic, Diagnostics, + codes::{DiagnosticInfo, Severity, custom}, }, hlir::ast::{Label, ModuleCall, Type, Type_, Var}, + iota_mode::{IOTA_ADDR_VALUE, TX_CONTEXT_MODULE_NAME}, parser::ast::Ability_, - shared::CompilationEnv, }; -const TRANSFER_FUNCTIONS: &[(&str, &str, &str)] = &[ - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, PUBLIC_TRANSFER_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, TRANSFER_FUN), +const TRANSFER_FUNCTIONS: &[(AccountAddress, &str, &str)] = &[ + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, PUBLIC_TRANSFER_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, TRANSFER_FUN), ]; const SELF_TRANSFER_DIAG: DiagnosticInfo = custom( @@ -80,8 +82,8 @@ impl SimpleAbsIntConstructor for SelfTransferVerifier { type AI<'a> = SelfTransferVerifierAI; fn new<'a>( - _env: &CompilationEnv, context: &'a CFGContext<'a>, + cfg: &ImmForwardCFG, _init_state: &mut as SimpleAbsInt>::State, ) -> Option> { let MemberName::Function(name) = context.member else { @@ -107,6 +109,10 @@ impl SimpleAbsIntConstructor for SelfTransferVerifier { // encourage folks to return values instead of using transfer return None; } + if !calls_special_function(TRANSFER_FUNCTIONS, cfg) { + // skip if it does not use transfer functions + return None; + } Some(SelfTransferVerifierAI { fn_ret_loc: context.signature.return_type.loc, }) @@ -162,7 +168,7 @@ impl SimpleAbsInt for SelfTransferVerifierAI { } return Some(vec![]); } - if f.is("iota", "tx_context", "sender") { + if f.is(&IOTA_ADDR_VALUE, TX_CONTEXT_MODULE_NAME, "sender") { return Some(vec![Value::SenderAddress(*loc)]); } Some(match &return_ty.value { diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/linters/share_owned.rs b/external-crates/move/crates/move-compiler/src/iota_mode/linters/share_owned.rs index 89a30f21f15..3b98049617f 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/linters/share_owned.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/linters/share_owned.rs @@ -7,37 +7,51 @@ //! to an abort. A typical patterns is to create a fresh object and share it //! within the same function +use std::collections::BTreeMap; + +use move_core_types::account_address::AccountAddress; use move_ir_types::location::*; +use move_proc_macros::growing_stack; use crate::{ cfgir::{ + CFGContext, absint::JoinResult, + cfg::ImmForwardCFG, visitor::{ - LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, SimpleExecutionContext, + LocalState, SimpleAbsInt, SimpleAbsIntConstructor, SimpleDomain, + SimpleExecutionContext, calls_special_function, }, - CFGContext, }, diag, diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, Diagnostic, Diagnostics, + codes::{DiagnosticInfo, Severity, custom}, }, + expansion::ast::ModuleIdent, hlir::ast::{ - Exp, LValue, LValue_, Label, ModuleCall, SingleType, Type, Type_, UnannotatedExp_, Var, + BaseType, BaseType_, Exp, LValue, LValue_, Label, ModuleCall, SingleType, SingleType_, + Type, Type_, TypeName_, UnannotatedExp_, Var, + }, + iota_mode::{ + IOTA_ADDR_VALUE, TX_CONTEXT_MODULE_NAME, TX_CONTEXT_TYPE_NAME, + info::{IotaInfo, TransferKind}, + linters::{ + LINT_WARNING_PREFIX, LinterDiagnosticCategory, LinterDiagnosticCode, PUBLIC_SHARE_FUN, + SHARE_FUN, TRANSFER_MOD_NAME, type_abilities, + }, + }, + naming::ast::BuiltinTypeName_, + parser::ast::{Ability_, DatatypeName}, + shared::{ + Identifier, + program_info::{DatatypeKind, TypingProgramInfo}, }, - parser::ast::Ability_, - shared::{CompilationEnv, Identifier}, -}; -use std::collections::BTreeMap; - -use super::{ - type_abilities, LinterDiagnosticCategory, LinterDiagnosticCode, LINT_WARNING_PREFIX, - PUBLIC_SHARE_FUN, SHARE_FUN, IOTA_PKG_NAME, TRANSFER_MOD_NAME, }; -const SHARE_FUNCTIONS: &[(&str, &str, &str)] = &[ - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, PUBLIC_SHARE_FUN), - (IOTA_PKG_NAME, TRANSFER_MOD_NAME, SHARE_FUN), +const SHARE_FUNCTIONS: &[(AccountAddress, &str, &str)] = &[ + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, PUBLIC_SHARE_FUN), + (IOTA_ADDR_VALUE, TRANSFER_MOD_NAME, SHARE_FUN), ]; const SHARE_OWNED_DIAG: DiagnosticInfo = custom( @@ -53,7 +67,10 @@ const SHARE_OWNED_DIAG: DiagnosticInfo = custom( //************************************************************************************************** pub struct ShareOwnedVerifier; -pub struct ShareOwnedVerifierAI; + +pub struct ShareOwnedVerifierAI<'a> { + info: &'a TypingProgramInfo, +} #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)] pub enum Value { @@ -80,11 +97,11 @@ pub struct State { //************************************************************************************************** impl SimpleAbsIntConstructor for ShareOwnedVerifier { - type AI<'a> = ShareOwnedVerifierAI; + type AI<'a> = ShareOwnedVerifierAI<'a>; fn new<'a>( - _env: &CompilationEnv, context: &'a CFGContext<'a>, + cfg: &ImmForwardCFG, _init_state: &mut as SimpleAbsInt>::State, ) -> Option> { if context.attributes.is_test_or_test_only() @@ -96,11 +113,14 @@ impl SimpleAbsIntConstructor for ShareOwnedVerifier { { return None; } - Some(ShareOwnedVerifierAI) + if !calls_special_function(SHARE_FUNCTIONS, cfg) { + return None; + } + Some(ShareOwnedVerifierAI { info: context.info }) } } -impl SimpleAbsInt for ShareOwnedVerifierAI { +impl<'a> SimpleAbsInt for ShareOwnedVerifierAI<'a> { type State = State; type ExecutionContext = ExecutionContext; @@ -149,37 +169,28 @@ impl SimpleAbsInt for ShareOwnedVerifierAI { if SHARE_FUNCTIONS .iter() .any(|(addr, module, fun)| f.is(addr, module, fun)) - && args[0] != Value::FreshObj + && args.first().is_some_and(|v| v != &Value::FreshObj) { - let msg = "Potential abort from a (potentially) owned object created by a different transaction."; - let uid_msg = "Creating a fresh object and sharing it within the same function will ensure this does not abort."; - let mut d = diag!( - SHARE_OWNED_DIAG, - (*loc, msg), - (f.arguments[0].exp.loc, uid_msg) - ); - if let Value::NotFreshObj(l) = args[0] { - d.add_secondary_label((l, "A potentially owned object coming from here")) - } - context.add_diag(d) + self.maybe_warn_share_owned(context, loc, f, args) } + let all_args_pure = !f.arguments.iter().any(|a| self.can_hold_obj(&a.ty)); Some(match &return_ty.value { Type_::Unit => vec![], Type_::Single(t) => { - let v = if is_obj_type(t) { - Value::NotFreshObj(t.loc) - } else { + let v = if all_args_pure || !is_obj_type(t) { Value::Other + } else { + Value::NotFreshObj(t.loc) }; vec![v] } Type_::Multiple(types) => types .iter() .map(|t| { - if is_obj_type(t) { - Value::NotFreshObj(t.loc) - } else { + if all_args_pure || !is_obj_type(t) { Value::Other + } else { + Value::NotFreshObj(t.loc) } }) .collect(), @@ -211,6 +222,112 @@ impl SimpleAbsInt for ShareOwnedVerifierAI { } } +impl<'a> ShareOwnedVerifierAI<'a> { + fn can_hold_obj(&self, sp!(_, ty_): &Type) -> bool { + match ty_ { + Type_::Unit => false, + Type_::Single(st) => self.can_hold_obj_single(st), + Type_::Multiple(sts) => sts.iter().any(|st| self.can_hold_obj_single(st)), + } + } + + fn can_hold_obj_single(&self, sp!(_, st_): &SingleType) -> bool { + match st_ { + SingleType_::Base(bt) | SingleType_::Ref(_, bt) => self.can_hold_obj_base(bt), + } + } + + #[growing_stack] + fn can_hold_obj_base(&self, sp!(_, bt_): &BaseType) -> bool { + match bt_ { + // special case TxContext as not holding an object + BaseType_::Apply(_, sp!(_, tn), _) + if tn.is( + &IOTA_ADDR_VALUE, + TX_CONTEXT_MODULE_NAME, + TX_CONTEXT_TYPE_NAME, + ) => + { + false + } + // vector in value might have an object + BaseType_::Apply( + _, + sp!(_, TypeName_::Builtin(sp!(_, BuiltinTypeName_::Vector))), + bs, + ) => bs.iter().any(|b| self.can_hold_obj_base(b)), + // builtins cannot hold objects + BaseType_::Apply(_, sp!(_, TypeName_::Builtin(_)), _) => false, + + BaseType_::Apply(_, sp!(_, TypeName_::ModuleType(m, n)), targs) => { + let m = *m; + let n = *n; + if self.iota_info().uid_holders.contains_key(&(m, n)) { + return true; + } + let phantom_positions = phantom_positions(self.info, &m, &n); + phantom_positions + .into_iter() + .zip(targs) + .filter(|(is_phantom, _)| !*is_phantom) + .any(|(_, t)| self.can_hold_obj_base(t)) + } + // any user defined type or type parameter is pessimistically assumed to hold an object + BaseType_::Param(_) => true, + BaseType_::Unreachable | BaseType_::UnresolvedError => false, + } + } + + fn maybe_warn_share_owned( + &self, + context: &mut ExecutionContext, + loc: &Loc, + f: &ModuleCall, + args: Vec, + ) { + let Value::NotFreshObj(not_fresh_loc) = &args[0] else { + return; + }; + let Some(tn) = f + .type_arguments + .first() + .and_then(|t| t.value.type_name()) + .and_then(|n| n.value.datatype_name()) + else { + return; + }; + let Some(transferred_kind) = self.iota_info().transferred.get(&tn) else { + return; + }; + + let msg = + "Potential abort from a (potentially) owned object created by a different transaction."; + let uid_msg = "Creating a fresh object and sharing it within the same function will \ + ensure this does not abort."; + let not_fresh_msg = "A potentially owned object coming from here"; + let (tloc, tmsg) = match transferred_kind { + TransferKind::PublicTransfer(store_loc) => ( + store_loc, + "Potentially an owned object because 'store' grants access to public transfers", + ), + TransferKind::PrivateTransfer(loc) => (loc, "Transferred as an owned object here"), + }; + let d = diag!( + SHARE_OWNED_DIAG, + (*loc, msg), + (f.arguments[0].exp.loc, uid_msg), + (*not_fresh_loc, not_fresh_msg), + (*tloc, tmsg), + ); + + context.add_diag(d) + } + + fn iota_info(&self) -> &'a IotaInfo { + self.info.iota_flavor_info.as_ref().unwrap() + } +} + fn is_obj(sp!(_, l_): &LValue) -> bool { if let LValue_::Var { ty: st, .. } = l_ { return is_obj_type(st); @@ -225,6 +342,18 @@ fn is_obj_type(st_: &SingleType) -> bool { abilities.has_ability_(Ability_::Key) } +fn phantom_positions( + info: &TypingProgramInfo, + m: &ModuleIdent, + n: &DatatypeName, +) -> Vec { + let ty_params = match info.datatype_kind(m, n) { + DatatypeKind::Struct => &info.struct_definition(m, n).type_parameters, + DatatypeKind::Enum => &info.enum_definition(m, n).type_parameters, + }; + ty_params.iter().map(|tp| tp.is_phantom).collect() +} + impl SimpleDomain for State { type Value = Value; diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs b/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs index f053d5ea2ea..0183378cbbe 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs @@ -2,14 +2,23 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use move_core_types::account_address::AccountAddress; use move_symbol_pool::Symbol; use crate::diagnostics::codes::{custom, DiagnosticInfo, Severity}; pub mod id_leak; +pub mod info; pub mod linters; pub mod typing; +// DEEPBOOK_ADDRESS / DEEPBOOK_PACKAGE_ID = 0xdee9; + +pub const STD_ADDR_VALUE: AccountAddress = AccountAddress::from_suffix(0x1); +pub const IOTA_ADDR_VALUE: AccountAddress = AccountAddress::from_suffix(0x2); +pub const IOTA_SYSTEM_ADDR_VALUE: AccountAddress = AccountAddress::from_suffix(0x3); +pub const BRIDGE_ADDR_VALUE: AccountAddress = AccountAddress::from_suffix(0xb); + pub const INIT_FUNCTION_NAME: Symbol = symbol!("init"); pub const ID_FIELD_NAME: Symbol = symbol!("id"); diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs b/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs index 40485c1010e..fdc6902cbc1 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs @@ -9,18 +9,18 @@ use move_symbol_pool::Symbol; use crate::{ diag, - diagnostics::{Diagnostic, WarningFilters}, + diagnostics::{Diagnostic, DiagnosticReporter, Diagnostics, warning_filters::WarningFilters}, editions::Flavor, expansion::ast::{AbilitySet, Fields, ModuleIdent, Mutability, TargetKind, Visibility}, + iota_mode::*, naming::ast::{ - self as N, BuiltinTypeName_, FunctionSignature, StructFields, Type, TypeName_, Type_, Var, + self as N, BuiltinTypeName_, FunctionSignature, StructFields, Type, Type_, TypeName_, Var, }, parser::ast::{Ability_, DatatypeName, FunctionName}, - shared::{program_info::TypingProgramInfo, CompilationEnv, Identifier}, - iota_mode::*, + shared::{CompilationEnv, Identifier, program_info::TypingProgramInfo}, typing::{ ast::{self as T, ModuleCall}, - core::{ability_not_satisfied_tips, error_format, error_format_, Subst}, + core::{Subst, ability_not_satisfied_tips, error_format, error_format_}, visitor::{TypingVisitorConstructor, TypingVisitorContext}, }, }; @@ -33,7 +33,7 @@ pub struct IotaTypeChecks; impl TypingVisitorConstructor for IotaTypeChecks { type Context<'a> = Context<'a>; - fn context<'a>(env: &'a mut CompilationEnv, program: &T::Program) -> Self::Context<'a> { + fn context<'a>(env: &'a CompilationEnv, program: &T::Program) -> Self::Context<'a> { Context::new(env, program.info.clone()) } } @@ -44,7 +44,8 @@ impl TypingVisitorConstructor for IotaTypeChecks { #[allow(unused)] pub struct Context<'a> { - env: &'a mut CompilationEnv, + env: &'a CompilationEnv, + reporter: DiagnosticReporter<'a>, info: Arc, iota_transfer_ident: Option, current_module: Option, @@ -54,14 +55,16 @@ pub struct Context<'a> { } impl<'a> Context<'a> { - fn new(env: &'a mut CompilationEnv, info: Arc) -> Self { + fn new(env: &'a CompilationEnv, info: Arc) -> Self { let iota_module_ident = info .modules .key_cloned_iter() - .find(|(m, _)| m.value.is(IOTA_ADDR_NAME, TRANSFER_MODULE_NAME)) + .find(|(m, _)| m.value.is(&IOTA_ADDR_VALUE, TRANSFER_MODULE_NAME)) .map(|(m, _)| m); + let reporter = env.diagnostic_reporter_at_top_level(); Context { env, + reporter, info, iota_transfer_ident: iota_module_ident, current_module: None, @@ -71,6 +74,15 @@ impl<'a> Context<'a> { } } + fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + fn set_module(&mut self, current_module: ModuleIdent) { self.current_module = Some(current_module); self.otw_name = Some(Symbol::from( @@ -99,26 +111,23 @@ const OTW_NOTE: &str = "One-time witness types are structs with the following re //************************************************************************************************** impl<'a> TypingVisitorContext for Context<'a> { - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) + fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) } fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() + self.reporter.pop_warning_filter_scope() } - fn visit_module_custom(&mut self, ident: ModuleIdent, mdef: &mut T::ModuleDefinition) -> bool { + fn visit_module_custom(&mut self, ident: ModuleIdent, mdef: &T::ModuleDefinition) -> bool { let config = self.env.package_config(mdef.package_name); if config.flavor != Flavor::Iota { // Skip if not iota return true; } - if !matches!( - mdef.target_kind, - TargetKind::Source { - is_root_package: true - } - ) { + if !matches!(mdef.target_kind, TargetKind::Source { + is_root_package: true + }) { // Skip non-source, dependency modules return true; } @@ -158,7 +167,7 @@ impl<'a> TypingVisitorContext for Context<'a> { &mut self, module: ModuleIdent, name: FunctionName, - fdef: &mut T::Function, + fdef: &T::Function, ) -> bool { debug_assert!(self.current_module.as_ref() == Some(&module)); function(self, name, fdef); @@ -166,7 +175,7 @@ impl<'a> TypingVisitorContext for Context<'a> { true } - fn visit_exp_custom(&mut self, e: &mut T::Exp) -> bool { + fn visit_exp_custom(&mut self, e: &T::Exp) -> bool { exp(self, e); // do not skip recursion false @@ -206,9 +215,7 @@ fn struct_def(context: &mut Context, name: DatatypeName, sdef: &N::StructDefinit }; if let Some(loc) = invalid_first_field { // no fields or an invalid 'id' field - context - .env - .add_diag(invalid_object_id_field_diag(key_loc, loc, name)); + context.add_diag(invalid_object_id_field_diag(key_loc, loc, name)); return; }; @@ -216,7 +223,7 @@ fn struct_def(context: &mut Context, name: DatatypeName, sdef: &N::StructDefinit let id_field_loc = fields.get_loc_(&ID_FIELD_NAME).unwrap(); if !id_field_type .value - .is(IOTA_ADDR_NAME, OBJECT_MODULE_NAME, UID_TYPE_NAME) + .is(&IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, UID_TYPE_NAME) { let actual = format!( "But found type: {}", @@ -224,7 +231,7 @@ fn struct_def(context: &mut Context, name: DatatypeName, sdef: &N::StructDefinit ); let mut diag = invalid_object_id_field_diag(key_loc, *id_field_loc, name); diag.add_secondary_label((id_field_type.loc, actual)); - context.env.add_diag(diag); + context.add_diag(diag); } } @@ -262,7 +269,7 @@ fn enum_def(context: &mut Context, name: DatatypeName, edef: &N::EnumDefinition) let msg = format!("Invalid object '{name}'"); let key_msg = format!("Enums cannot have the '{}' ability.", Ability_::Key); let diag = diag!(OBJECT_DECL_DIAG, (name.loc(), msg), (key_loc, key_msg)); - context.env.add_diag(diag); + context.add_diag(diag); }; } @@ -270,7 +277,7 @@ fn enum_def(context: &mut Context, name: DatatypeName, edef: &N::EnumDefinition) // Functions //********************************************************************************************** -fn function(context: &mut Context, name: FunctionName, fdef: &mut T::Function) { +fn function(context: &mut Context, name: FunctionName, fdef: &T::Function) { let T::Function { compiled_visibility: _, visibility, @@ -280,6 +287,7 @@ fn function(context: &mut Context, name: FunctionName, fdef: &mut T::Function) { index: _, macro_: _, attributes, + loc: _, entry, } = fdef; let prev_in_test = context.in_test; @@ -293,7 +301,7 @@ fn function(context: &mut Context, name: FunctionName, fdef: &mut T::Function) { entry_signature(context, *entry_loc, name, signature); } if let sp!(_, T::FunctionBody_::Defined(seq)) = body { - context.visit_seq(seq) + context.visit_seq(body.loc, seq) } context.in_test = prev_in_test; } @@ -309,17 +317,16 @@ fn init_visibility( entry: Option, ) { match visibility { - Visibility::Public(loc) | Visibility::Friend(loc) | Visibility::Package(loc) => { - context.env.add_diag(diag!( + Visibility::Public(loc) | Visibility::Friend(loc) | Visibility::Package(loc) => context + .add_diag(diag!( INIT_FUN_DIAG, (name.loc(), "Invalid 'init' function declaration"), (loc, "'init' functions must be internal to their module"), - )) - } + )), Visibility::Internal => (), } if let Some(entry) = entry { - context.env.add_diag(diag!( + context.add_diag(diag!( INIT_FUN_DIAG, (name.loc(), "Invalid 'init' function declaration"), (entry, "'init' functions cannot be 'entry' functions"), @@ -335,7 +342,7 @@ fn init_signature(context: &mut Context, name: FunctionName, signature: &Functio } = signature; if !type_parameters.is_empty() { let tp_loc = type_parameters[0].user_specified_name.loc; - context.env.add_diag(diag!( + context.add_diag(diag!( INIT_FUN_DIAG, (name.loc(), "Invalid 'init' function declaration"), (tp_loc, "'init' functions cannot have type parameters"), @@ -346,7 +353,7 @@ fn init_signature(context: &mut Context, name: FunctionName, signature: &Functio "'init' functions must have a return type of {}", error_format_(&Type_::Unit, &Subst::empty()) ); - context.env.add_diag(diag!( + context.add_diag(diag!( INIT_FUN_DIAG, (name.loc(), "Invalid 'init' function declaration"), (return_type.loc, msg), @@ -368,7 +375,7 @@ fn init_signature(context: &mut Context, name: FunctionName, signature: &Functio m = TX_CONTEXT_MODULE_NAME, t = TX_CONTEXT_TYPE_NAME, ); - context.env.add_diag(diag!( + context.add_diag(diag!( INIT_FUN_DIAG, (name.loc(), "Invalid 'init' function declaration"), (last_loc, msg), @@ -398,7 +405,7 @@ fn init_signature(context: &mut Context, name: FunctionName, signature: &Functio (otw_loc, otw_msg), ); diag.add_note(OTW_NOTE); - context.env.add_diag(diag) + context.add_diag(diag) } else if parameters.len() > 1 { // if there is more than one parameter, the first must be the OTW let (_, first_var, first_ty) = parameters.first().unwrap(); @@ -422,7 +429,7 @@ fn init_signature(context: &mut Context, name: FunctionName, signature: &Functio (first_ty.loc, msg) ); diag.add_note(OTW_NOTE); - context.env.add_diag(diag) + context.add_diag(diag) } else if let Some(sdef) = info .module(context.current_module()) .structs @@ -440,7 +447,7 @@ fn init_signature(context: &mut Context, name: FunctionName, signature: &Functio if parameters.len() > 2 { // no init function can take more than 2 parameters (the OTW and the TxContext) let (_, third_var, _) = ¶meters[2]; - context.env.add_diag(diag!( + context.add_diag(diag!( INIT_FUN_DIAG, (name.loc(), "Invalid 'init' function declaration"), ( @@ -476,7 +483,7 @@ fn check_otw_type( let mut valid = true; if let Some(tp) = sdef.type_parameters.first() { let msg = "One-time witness types cannot have type parameters"; - context.env.add_diag(otw_diag(diag!( + context.add_diag(otw_diag(diag!( OTW_DECL_DIAG, (name.loc(), "Invalid one-time witness declaration"), (tp.param.user_specified_name.loc, msg), @@ -498,7 +505,7 @@ fn check_otw_type( (loc, format!("Found more than one field. {msg_base}")) } }; - context.env.add_diag(otw_diag(diag!( + context.add_diag(otw_diag(diag!( OTW_DECL_DIAG, (name.loc(), "Invalid one-time witness declaration"), (invalid_loc, invalid_msg), @@ -529,7 +536,7 @@ fn check_otw_type( "One-time witness types can only have the have the '{}' ability", Ability_::Drop ); - context.env.add_diag(otw_diag(diag!( + context.add_diag(otw_diag(diag!( OTW_DECL_DIAG, (name.loc(), "Invalid one-time witness declaration"), (loc, msg), @@ -612,7 +619,11 @@ fn tx_context_kind(sp!(_, last_param_ty_): &Type) -> TxContextKind { // not a user defined type return TxContextKind::None; }; - if inner_name.is(IOTA_ADDR_NAME, TX_CONTEXT_MODULE_NAME, TX_CONTEXT_TYPE_NAME) { + if inner_name.is( + &IOTA_ADDR_VALUE, + TX_CONTEXT_MODULE_NAME, + TX_CONTEXT_TYPE_NAME, + ) { if *is_mut { TxContextKind::Mutable } else { @@ -694,7 +705,7 @@ fn entry_param_ty( .to_owned() }; let emsg = format!("'{name}' was declared 'entry' here"); - context.env.add_diag(diag!( + context.add_diag(diag!( ENTRY_FUN_SIGNATURE_DIAG, (param.loc, pmsg), (param_ty.loc, tmsg), @@ -707,7 +718,9 @@ fn is_mut_clock(param_ty: &Type) -> bool { match ¶m_ty.value { Type_::Ref(/* mut */ false, _) => false, Type_::Ref(/* mut */ true, t) => is_mut_clock(t), - Type_::Apply(_, sp!(_, n_), _) => n_.is(IOTA_ADDR_NAME, CLOCK_MODULE_NAME, CLOCK_TYPE_NAME), + Type_::Apply(_, sp!(_, n_), _) => { + n_.is(&IOTA_ADDR_VALUE, CLOCK_MODULE_NAME, CLOCK_TYPE_NAME) + } Type_::Unit | Type_::Param(_) | Type_::Var(_) @@ -722,7 +735,7 @@ fn is_mut_random(param_ty: &Type) -> bool { Type_::Ref(/* mut */ false, _) => false, Type_::Ref(/* mut */ true, t) => is_mut_random(t), Type_::Apply(_, sp!(_, n_), _) => n_.is( - IOTA_ADDR_NAME, + &IOTA_ADDR_VALUE, RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_TYPE_NAME, ), @@ -739,7 +752,7 @@ fn is_entry_receiving_ty(param_ty: &Type) -> bool { match ¶m_ty.value { Type_::Ref(_, t) => is_entry_receiving_ty(t), Type_::Apply(_, sp!(_, n), targs) - if n.is(IOTA_ADDR_NAME, TRANSFER_MODULE_NAME, RECEIVING_TYPE_NAME) => + if n.is(&IOTA_ADDR_VALUE, TRANSFER_MODULE_NAME, RECEIVING_TYPE_NAME) => { debug_assert!(targs.len() == 1); // Don't care about the type parameter, just that it's a receiving type -- since @@ -769,15 +782,15 @@ fn is_entry_primitive_ty(param_ty: &Type) -> bool { // custom "primitives" Type_::Apply(_, sp!(_, n), targs) - if n.is(STD_ADDR_NAME, ASCII_MODULE_NAME, ASCII_TYPE_NAME) - || n.is(STD_ADDR_NAME, UTF_MODULE_NAME, UTF_TYPE_NAME) - || n.is(IOTA_ADDR_NAME, OBJECT_MODULE_NAME, ID_TYPE_NAME) => + if n.is(&STD_ADDR_VALUE, ASCII_MODULE_NAME, ASCII_TYPE_NAME) + || n.is(&STD_ADDR_VALUE, UTF_MODULE_NAME, UTF_TYPE_NAME) + || n.is(&IOTA_ADDR_VALUE, OBJECT_MODULE_NAME, ID_TYPE_NAME) => { debug_assert!(targs.is_empty()); true } Type_::Apply(_, sp!(_, n), targs) - if n.is(STD_ADDR_NAME, OPTION_MODULE_NAME, OPTION_TYPE_NAME) => + if n.is(&STD_ADDR_VALUE, OPTION_MODULE_NAME, OPTION_TYPE_NAME) => { debug_assert!(targs.len() == 1); is_entry_primitive_ty(&targs[0]) @@ -846,7 +859,7 @@ fn entry_return( Type_::Ref(_, _) => { let fmsg = format!("Invalid return type for entry function '{}'", name); let tmsg = "Expected a non-reference type"; - context.env.add_diag(diag!( + context.add_diag(diag!( ENTRY_FUN_SIGNATURE_DIAG, (entry_loc, fmsg), (*tloc, tmsg) @@ -920,7 +933,7 @@ fn invalid_entry_return_ty<'a>( declared_abilities, ty_args, ); - context.env.add_diag(diag) + context.add_diag(diag) } //************************************************************************************************** @@ -944,14 +957,14 @@ fn exp(context: &mut Context, e: &T::Exp) { consider extracting the logic into a new function and \ calling that instead.", ); - context.env.add_diag(diag) + context.add_diag(diag) } - if module.value.is(IOTA_ADDR_NAME, EVENT_MODULE_NAME) + if module.value.is(&IOTA_ADDR_VALUE, EVENT_MODULE_NAME) && name.value() == EVENT_FUNCTION_NAME { check_event_emit(context, e.exp.loc, mcall) } - let is_transfer_module = module.value.is(IOTA_ADDR_NAME, TRANSFER_MODULE_NAME); + let is_transfer_module = module.value.is(&IOTA_ADDR_VALUE, TRANSFER_MODULE_NAME); if is_transfer_module && PRIVATE_TRANSFER_FUNCTIONS.contains(&name.value()) { check_private_transfer(context, e.exp.loc, mcall) } @@ -968,7 +981,7 @@ fn exp(context: &mut Context, e: &T::Exp) { cannot be created manually, but are passed as an argument 'init'"; let mut diag = diag!(OTW_USAGE_DIAG, (e.exp.loc, msg)); diag.add_note(OTW_NOTE); - context.env.add_diag(diag) + context.add_diag(diag) } } _ => (), @@ -978,11 +991,11 @@ fn exp(context: &mut Context, e: &T::Exp) { fn otw_special_cases(context: &Context) -> bool { BRIDGE_SUPPORTED_ASSET .iter() - .any(|token| context.current_module().value.is(BRIDGE_ADDR_NAME, token)) + .any(|token| context.current_module().value.is(&BRIDGE_ADDR_VALUE, token)) || context .current_module() .value - .is(IOTA_ADDR_NAME, IOTA_MODULE_NAME) + .is(&IOTA_ADDR_VALUE, IOTA_MODULE_NAME) } fn check_event_emit(context: &mut Context, loc: Loc, mcall: &ModuleCall) { @@ -1008,7 +1021,7 @@ fn check_event_emit(context: &mut Context, loc: Loc, mcall: &ModuleCall) { "The type {} is not declared in the current module", error_format(first_ty, &Subst::empty()), ); - context.env.add_diag(diag!( + context.add_diag(diag!( EVENT_EMIT_CALL_DIAG, (loc, msg), (first_ty.loc, ty_msg) @@ -1026,7 +1039,7 @@ fn check_private_transfer(context: &mut Context, loc: Loc, mcall: &ModuleCall) { let current_module = context.current_module(); if current_module .value - .is(IOTA_ADDR_NAME, TRANSFER_FUNCTION_NAME) + .is(&IOTA_ADDR_VALUE, TRANSFER_FUNCTION_NAME) { // inside the transfer module, so no private transfer rules return; @@ -1086,6 +1099,6 @@ fn check_private_transfer(context: &mut Context, loc: Loc, mcall: &ModuleCall) { ); diag.add_secondary_label((store_loc, store_msg)) } - context.env.add_diag(diag) + context.add_diag(diag) } } diff --git a/external-crates/move/crates/move-compiler/src/linters/abort_constant.rs b/external-crates/move/crates/move-compiler/src/linters/abort_constant.rs new file mode 100644 index 00000000000..57e9a8b6389 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/abort_constant.rs @@ -0,0 +1,102 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Lint to encourage the use of named constants with 'abort' and 'assert' for enhanced code readability. +//! Detects cases where non-constants are used and issues a warning. + +use crate::diagnostics::warning_filters::WarningFilters; +use crate::diagnostics::DiagnosticReporter; +use crate::linters::StyleCodes; +use crate::{ + cfgir::{ + ast as G, + visitor::{CFGIRVisitorConstructor, CFGIRVisitorContext}, + }, + diag, + diagnostics::{Diagnostic, Diagnostics}, + editions::FeatureGate, + hlir::ast as H, + shared::CompilationEnv, +}; +use move_ir_types::location::Loc; +use move_symbol_pool::Symbol; + +pub struct AssertAbortNamedConstants; + +pub struct Context<'a> { + package_name: Option, + env: &'a CompilationEnv, + reporter: DiagnosticReporter<'a>, +} + +impl CFGIRVisitorConstructor for AssertAbortNamedConstants { + type Context<'a> = Context<'a>; + + fn context<'a>(env: &'a CompilationEnv, program: &G::Program) -> Self::Context<'a> { + let package_name = program + .modules + .iter() + .next() + .and_then(|(_, _, mdef)| mdef.package_name); + let reporter = env.diagnostic_reporter_at_top_level(); + Context { + env, + reporter, + package_name, + } + } +} + +impl Context<'_> { + fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } +} + +impl CFGIRVisitorContext for Context<'_> { + fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + + fn visit_command_custom(&mut self, cmd: &H::Command) -> bool { + if let H::Command_::Abort(loc, abort_exp) = &cmd.value { + self.check_named_constant(abort_exp, *loc); + } + false + } +} + +impl Context<'_> { + fn check_named_constant(&mut self, arg_exp: &H::Exp, loc: Loc) { + let is_constant = matches!( + &arg_exp.exp.value, + H::UnannotatedExp_::Constant(_) | H::UnannotatedExp_::ErrorConstant { .. }, + ); + + if !is_constant { + let mut diag = diag!( + StyleCodes::AbortWithoutConstant.diag_info(), + (loc, "Prefer using a named constant.") + ); + + if self + .env + .supports_feature(self.package_name, FeatureGate::CleverAssertions) + { + diag.add_note("Consider using an error constant with the '#[error]' to allow for a more descriptive error."); + } + + self.add_diag(diag); + } + } +} diff --git a/external-crates/move/crates/move-compiler/src/linters/combinable_comparisons.rs b/external-crates/move/crates/move-compiler/src/linters/combinable_comparisons.rs new file mode 100644 index 00000000000..dd2bf179c5c --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/combinable_comparisons.rs @@ -0,0 +1,238 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! The `CombinableBool` detects and warns about boolean conditions in Move code that can be simplified. +//! It identifies comparisons that are logically equivalent and suggests more concise alternatives. +//! This rule focuses on simplifying expressions involving `==`, `<`, `>`, and `!=` operators to improve code readability. + +use crate::{ + diag, + linters::StyleCodes, + parser::ast::{BinOp, BinOp_}, + typing::{ + ast::{self as T}, + visitor::{same_value_exp, simple_visitor}, + }, +}; + +#[derive(Debug, Clone, Copy)] +enum Simplification { + Reducible(CmpOp), + AlwaysTrue, + AlwaysFalse, +} + +#[derive(Debug, Clone, Copy)] +enum BoolOp { + And, + Or, +} + +/// See `simplify` for how these values are used. +#[repr(u8)] +#[derive(Debug, Clone, Copy)] +enum CmpOp { + Lt = LT, + Eq = EQ, + Le = LE, + Gt = GT, + Neq = NEQ, + Ge = GE, +} + +// See `simplify` for how these values are used. +const FALSE: u8 = 0b000; +const LT: u8 = 0b001; +const EQ: u8 = 0b010; +const LE: u8 = 0b011; +const GT: u8 = 0b100; +const NEQ: u8 = 0b101; +const GE: u8 = 0b110; +const TRUE: u8 = 0b111; + +simple_visitor!( + CombinableComparisons, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { + use T::UnannotatedExp_ as E; + let E::BinopExp(outer_l, outer_bop, _, outer_r) = &exp.exp.value else { + return false; + }; + // TODO handle negation + let E::BinopExp(l1, op_l, _, r1) = &outer_l.exp.value else { + return false; + }; + let E::BinopExp(l2, op_r, _, r2) = &outer_r.exp.value else { + return false; + }; + let Some((outer, inner_l, inner_r)) = binop_case(outer_bop, l1, op_l, r1, l2, op_r, r2) + else { + return false; + }; + let simplification = simplify(outer, inner_l, inner_r); + let msg = match simplification { + Simplification::Reducible(inner_op) => { + format!("simplifies to the operation '{}'", inner_op) + } + Simplification::AlwaysTrue => "is always 'true'".to_string(), + Simplification::AlwaysFalse => "is always 'false'".to_string(), + }; + self.reporter.add_diag(diag!( + StyleCodes::CombinableComparisons.diag_info(), + (exp.exp.loc, format!("This comparison {msg}")), + )); + + false + } +); + +/// Each binary operator is represented as a 3-bit number where each bit represents a range of +/// possible values. With three bits, 0bGEL we are "drawing" an interval of ranges. The comparison +/// `true` if the value is within the interval. so for `x cmp y`` +/// ```text +/// G E L +/// ^ this bit represents x < y (less than the equal bit) +/// ^ this bit represents x == y (the equal bit) +/// ^ this bit represents x > y (greater than the equal bit) +/// ``` +/// We then take the disjunction of intervals by the bits--creating a bitset. +/// So for example, `>=` is 0b110 since the interval is either greater OR equal. +/// And for `!=` is 0b101 since the interval is either not equal OR less than. We are only dealing +/// with primitives so we know the values are well ordered. +/// From there we can then bitwise-or the bits (set union) when the outer operation is `||` and +/// bitwise-and the bits (set intersection) when the outer operation is `&&` to get the final +/// "simplified" operation. If all bits are set, then the operation is always true. If no bits are +/// set, then the operation is always false. +fn simplify(outer: BoolOp, inner_l: CmpOp, inner_r: CmpOp) -> Simplification { + let lbits = inner_l as u8; + let rbits = inner_r as u8; + let simplification = match outer { + BoolOp::And => lbits & rbits, + BoolOp::Or => lbits | rbits, + }; + match simplification { + FALSE => Simplification::AlwaysFalse, + LT => Simplification::Reducible(CmpOp::Lt), + EQ => Simplification::Reducible(CmpOp::Eq), + LE => Simplification::Reducible(CmpOp::Le), + GT => Simplification::Reducible(CmpOp::Gt), + NEQ => Simplification::Reducible(CmpOp::Neq), + GE => Simplification::Reducible(CmpOp::Ge), + TRUE => Simplification::AlwaysTrue, + _ => unreachable!(), + } +} + +fn bool_op(sp!(_, bop_): &BinOp) -> Option { + Some(match bop_ { + BinOp_::And => BoolOp::And, + BinOp_::Or => BoolOp::Or, + BinOp_::Eq + | BinOp_::Lt + | BinOp_::Gt + | BinOp_::Le + | BinOp_::Ge + | BinOp_::Add + | BinOp_::Sub + | BinOp_::Mul + | BinOp_::Mod + | BinOp_::Div + | BinOp_::BitOr + | BinOp_::BitAnd + | BinOp_::Xor + | BinOp_::Shl + | BinOp_::Shr + | BinOp_::Range + | BinOp_::Implies + | BinOp_::Iff + | BinOp_::Neq => return None, + }) +} + +fn cmp_op(sp!(_, bop_): &BinOp) -> Option { + Some(match bop_ { + BinOp_::Eq => CmpOp::Eq, + BinOp_::Neq => CmpOp::Neq, + BinOp_::Lt => CmpOp::Lt, + BinOp_::Gt => CmpOp::Gt, + BinOp_::Le => CmpOp::Le, + BinOp_::Ge => CmpOp::Ge, + + BinOp_::Add + | BinOp_::Sub + | BinOp_::Mul + | BinOp_::Mod + | BinOp_::Div + | BinOp_::BitOr + | BinOp_::BitAnd + | BinOp_::Xor + | BinOp_::Shl + | BinOp_::Shr + | BinOp_::Range + | BinOp_::Implies + | BinOp_::Iff + | BinOp_::And + | BinOp_::Or => return None, + }) +} + +fn flip(op: CmpOp) -> CmpOp { + match op { + CmpOp::Eq => CmpOp::Eq, + CmpOp::Neq => CmpOp::Neq, + CmpOp::Lt => CmpOp::Gt, + CmpOp::Gt => CmpOp::Lt, + CmpOp::Le => CmpOp::Ge, + CmpOp::Ge => CmpOp::Le, + } +} + +fn binop_case( + outer_bop: &BinOp, + l1: &T::Exp, + op_l: &BinOp, + r1: &T::Exp, + l2: &T::Exp, + op_r: &BinOp, + r2: &T::Exp, +) -> Option<(BoolOp, CmpOp, CmpOp)> { + let outer = bool_op(outer_bop)?; + let inner_l = cmp_op(op_l)?; + let inner_r = cmp_op(op_r)?; + let (inner_l, inner_r) = operand_case(l1, inner_l, r1, l2, inner_r, r2)?; + Some((outer, inner_l, inner_r)) +} + +fn operand_case( + l1: &T::Exp, + op1: CmpOp, + r1: &T::Exp, + l2: &T::Exp, + op2: CmpOp, + r2: &T::Exp, +) -> Option<(CmpOp, CmpOp)> { + if same_value_exp(l1, l2) && same_value_exp(r1, r2) { + Some((op1, op2)) + } else if same_value_exp(l1, r2) && same_value_exp(r1, l2) { + Some((op1, flip(op2))) + } else { + None + } +} + +impl std::fmt::Display for CmpOp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + CmpOp::Eq => "==", + CmpOp::Neq => "!=", + CmpOp::Lt => "<", + CmpOp::Gt => ">", + CmpOp::Le => "<=", + CmpOp::Ge => ">=", + } + ) + } +} diff --git a/external-crates/move/crates/move-compiler/src/linters/constant_naming.rs b/external-crates/move/crates/move-compiler/src/linters/constant_naming.rs index 5ee30e7baf8..c5d74c9a8d2 100644 --- a/external-crates/move/crates/move-compiler/src/linters/constant_naming.rs +++ b/external-crates/move/crates/move-compiler/src/linters/constant_naming.rs @@ -7,67 +7,30 @@ //! within a module against this convention. use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, expansion::ast::ModuleIdent, + linters::StyleCodes, parser::ast::ConstantName, - shared::CompilationEnv, - typing::{ - ast as T, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, - }, + typing::{ast as T, visitor::simple_visitor}, }; -use super::{LinterDiagnosticCategory, CONSTANT_NAMING_DIAG_CODE, LINT_WARNING_PREFIX}; - -/// Diagnostic information for constant naming violations. -const CONSTANT_NAMING_DIAG: DiagnosticInfo = custom( - LINT_WARNING_PREFIX, - Severity::Warning, - LinterDiagnosticCategory::Style as u8, - CONSTANT_NAMING_DIAG_CODE, - "constant should follow naming convention", -); - -pub struct ConstantNamingVisitor; -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} -impl TypingVisitorConstructor for ConstantNamingVisitor { - type Context<'a> = Context<'a>; - - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { +simple_visitor!( + ConstantNaming, fn visit_constant_custom( &mut self, _module: ModuleIdent, constant_name: ConstantName, - cdef: &mut T::Constant, + cdef: &T::Constant, ) -> bool { let name = constant_name.0.value.as_str(); if !is_valid_name(name) { let uid_msg = format!("'{name}' should be ALL_CAPS. Or for error constants, use PascalCase",); - let diagnostic = diag!(CONSTANT_NAMING_DIAG, (cdef.loc, uid_msg)); - self.env.add_diag(diagnostic); + let diagnostic = diag!(StyleCodes::ConstantNaming.diag_info(), (cdef.loc, uid_msg)); + self.add_diag(diagnostic); } false } - - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } -} +); /// Returns `true` if the string is in all caps snake case, including numeric characters. fn is_valid_name(name: &str) -> bool { diff --git a/external-crates/move/crates/move-compiler/src/linters/equal_operands.rs b/external-crates/move/crates/move-compiler/src/linters/equal_operands.rs new file mode 100644 index 00000000000..870107a1f6f --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/equal_operands.rs @@ -0,0 +1,57 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Detects operands that are equal in a binary operation which results in a constant value. +//! Unlike the warning generated during constant folding, this works over non-constant expressions. + +use crate::{ + cfgir::visitor::{same_value_exp, simple_visitor}, + diag, + hlir::ast as H, + linters::StyleCodes, + parser::ast::BinOp_, +}; + +simple_visitor!( + EqualOperands, + fn visit_exp_custom(&mut self, e: &H::Exp) -> bool { + let H::UnannotatedExp_::BinopExp(lhs, op, rhs) = &e.exp.value else { + return false; + }; + + if same_value_exp(lhs, rhs) { + let resulting_value = match &op.value { + // warning reported elsewhere + BinOp_::Div | BinOp_::Mod if rhs.as_value().is_some_and(|v| v.value.is_zero()) => { + return false + } + BinOp_::Sub | BinOp_::Mod | BinOp_::Xor => "'0'", + BinOp_::Div => "'1'", + BinOp_::BitOr | BinOp_::BitAnd | BinOp_::And | BinOp_::Or => "the same value", + BinOp_::Neq | BinOp_::Lt | BinOp_::Gt => "'false'", + BinOp_::Eq | BinOp_::Le | BinOp_::Ge => "'true'", + BinOp_::Add + | BinOp_::Mul + | BinOp_::Shl + | BinOp_::Shr + | BinOp_::Range + | BinOp_::Implies + | BinOp_::Iff => return false, + }; + let msg = format!( + "Always equal operands detected in binary operation, \ + which will evaluate to {resulting_value}" + ); + let lhs_msg = "This expression"; + let rhs_msg = "Will always evaluate to the same value as this expression"; + self.reporter.add_diag(diag!( + StyleCodes::EqualOperands.diag_info(), + (e.exp.loc, msg), + (lhs.exp.loc, lhs_msg), + (rhs.exp.loc, rhs_msg) + )); + }; + false + } +); diff --git a/external-crates/move/crates/move-compiler/src/linters/loop_without_exit.rs b/external-crates/move/crates/move-compiler/src/linters/loop_without_exit.rs new file mode 100644 index 00000000000..cd32c7467c3 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/loop_without_exit.rs @@ -0,0 +1,49 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Detects empty loop expressions, including `while(true) {}` and `loop {}` without exit mechanisms, highlighting potential infinite loops. +//! Aims to identify and warn against loops that may lead to hangs or excessive resource consumption due to lack of content. +//! Encourages adding meaningful logic within loops or ensuring proper exit conditions to improve code reliability and maintainability. +use super::StyleCodes; +use crate::{ + diag, + typing::{ + ast::{self as T, UnannotatedExp_}, + visitor::{exp_satisfies, simple_visitor}, + }, +}; + +simple_visitor!( + LoopWithoutExit, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { + // we do not care about `while` since there is another lint that handles reporting + // that `while (true)` should be `loop` + let UnannotatedExp_::Loop { + name: _, + has_break: false, + body, + } = &exp.exp.value + else { + return false; + }; + // TODO maybe move this to Loop? Bit of an n^2 problem here in the worst case + if has_return(body) { + return false; + } + let diag = diag!( + StyleCodes::LoopWithoutExit.diag_info(), + ( + exp.exp.loc, + "'loop' without 'break' or 'return'. \ + This code will until it errors, e.g. reaching an 'abort' or running out of gas" + ) + ); + self.add_diag(diag); + false + } +); + +fn has_return(e: &T::Exp) -> bool { + exp_satisfies(e, |e| matches!(e.exp.value, UnannotatedExp_::Return(_))) +} diff --git a/external-crates/move/crates/move-compiler/src/linters/meaningless_math_operation.rs b/external-crates/move/crates/move-compiler/src/linters/meaningless_math_operation.rs new file mode 100644 index 00000000000..c1b1e063d1b --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/meaningless_math_operation.rs @@ -0,0 +1,118 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Detects meaningless math operations like `x * 0`, `x << 0`, `x >> 0`, `x * 1`, `x + 0`, `x - 0` +//! Aims to reduce code redundancy and improve clarity by flagging operations with no effect. +use crate::{ + cfgir::visitor::simple_visitor, + diag, + hlir::ast::{self as H, Value_}, + linters::StyleCodes, + parser::ast::BinOp_, +}; +use move_core_types::u256::U256; +use move_ir_types::location::Loc; + +simple_visitor!( + MeaninglessMathOperation, + fn visit_exp_custom(&mut self, exp: &H::Exp) -> bool { + let H::UnannotatedExp_::BinopExp(lhs, op, rhs) = &exp.exp.value else { + return false; + }; + + // unchanged operations + let is_unchanged = match op.value { + BinOp_::Mul => is_one(lhs).or(is_one(rhs)), + BinOp_::Div => is_one(rhs), + BinOp_::Add => is_zero(lhs).or(is_zero(rhs)), + BinOp_::Sub => is_zero(rhs), + BinOp_::Shl | BinOp_::Shr => is_zero(rhs), + _ => None, + }; + if let Some(meaningless_operand) = is_unchanged { + let msg = "This operation has no effect and can be removed"; + self.add_diag(diag!( + StyleCodes::MeaninglessMath.diag_info(), + (exp.exp.loc, msg), + (meaningless_operand, "Because of this operand"), + )); + } + + // always zero + let is_always_zero = match op.value { + BinOp_::Mul => is_zero(lhs).or(is_zero(rhs)), + BinOp_::Div => is_zero(lhs), + BinOp_::Mod => is_zero(lhs).or(is_one(rhs)), + _ => None, + }; + if let Some(zero_operand) = is_always_zero { + let msg = "This operation is always zero and can be replaced with '0'"; + self.add_diag(diag!( + StyleCodes::MeaninglessMath.diag_info(), + (exp.exp.loc, msg), + (zero_operand, "Because of this operand"), + )); + } + + // always one + let is_always_one = match op.value { + BinOp_::Mod => is_one(lhs), + _ => None, + }; + if let Some(one_operand) = is_always_one { + let msg = "This operation is always one and can be replaced with '1'"; + self.add_diag(diag!( + StyleCodes::MeaninglessMath.diag_info(), + (exp.exp.loc, msg), + (one_operand, "Because of this operand"), + )); + } + + // for aborts, e.g. x / 0, we will let the optimizer give a warning + + false + } +); + +fn is_zero(exp: &H::Exp) -> Option { + let H::UnannotatedExp_::Value(sp!(loc, value_)) = &exp.exp.value else { + return None; + }; + match value_ { + Value_::U8(0) | Value_::U16(0) | Value_::U32(0) | Value_::U64(0) | Value_::U128(0) => { + Some(*loc) + } + Value_::U256(u) if u == &U256::zero() => Some(*loc), + Value_::U8(_) + | Value_::U16(_) + | Value_::U32(_) + | Value_::U64(_) + | Value_::U128(_) + | Value_::U256(_) + | Value_::Address(_) + | Value_::Bool(_) + | Value_::Vector(_, _) => None, + } +} + +fn is_one(exp: &H::Exp) -> Option { + let H::UnannotatedExp_::Value(sp!(loc, value_)) = &exp.exp.value else { + return None; + }; + match value_ { + Value_::U8(1) | Value_::U16(1) | Value_::U32(1) | Value_::U64(1) | Value_::U128(1) => { + Some(*loc) + } + Value_::U256(u) if u == &U256::one() => Some(*loc), + Value_::U8(_) + | Value_::U16(_) + | Value_::U32(_) + | Value_::U64(_) + | Value_::U128(_) + | Value_::U256(_) + | Value_::Address(_) + | Value_::Bool(_) + | Value_::Vector(_, _) => None, + } +} diff --git a/external-crates/move/crates/move-compiler/src/linters/mod.rs b/external-crates/move/crates/move-compiler/src/linters/mod.rs index 8e49d7daee5..2f405208f76 100644 --- a/external-crates/move/crates/move-compiler/src/linters/mod.rs +++ b/external-crates/move/crates/move-compiler/src/linters/mod.rs @@ -5,11 +5,27 @@ use move_symbol_pool::Symbol; use crate::{ - command_line::compiler::Visitor, diagnostics::codes::WarningFilter, - linters::constant_naming::ConstantNamingVisitor, typing::visitor::TypingVisitor, + cfgir::visitor::CFGIRVisitor, + command_line::compiler::Visitor, + diagnostics::{ + codes::{custom, DiagnosticInfo, Severity}, + warning_filters::WarningFilter, + }, + typing::visitor::TypingVisitor, }; + +pub mod abort_constant; +pub mod combinable_comparisons; pub mod constant_naming; -mod unnecessary_while_loop; +pub mod equal_operands; +pub mod loop_without_exit; +pub mod meaningless_math_operation; +pub mod redundant_ref_deref; +pub mod self_assignment; +pub mod unnecessary_conditional; +pub mod unnecessary_unit; +pub mod unnecessary_while_loop; +pub mod unneeded_return; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum LintLevel { @@ -32,30 +48,154 @@ pub enum LinterDiagnosticCategory { Iota = 99, } +macro_rules! lints { + ( + $( + ($enum_name:ident, $category:expr, $filter_name:expr, $code_msg:expr) + ),* $(,)? + ) => { + #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, PartialOrd, Ord)] + #[repr(u8)] + pub enum StyleCodes { + DontStartAtZeroPlaceholder, + $( + $enum_name, + )* + } + + impl StyleCodes { + const fn category_code_and_message(&self) -> (u8, u8, &'static str) { + let code = *self as u8; + debug_assert!(code > 0); + match self { + Self::DontStartAtZeroPlaceholder => + panic!("ICE do not use placeholder error code"), + $(Self::$enum_name => ($category as u8, code, $code_msg),)* + } + } + + const fn category_code_and_filter_name(&self) -> (u8, u8, &'static str) { + let code = *self as u8; + debug_assert!(code > 0); + match self { + Self::DontStartAtZeroPlaceholder => + panic!("ICE do not use placeholder error code"), + $(Self::$enum_name => ($category as u8, code, $filter_name),)* + } + } + + const fn diag_info(&self) -> DiagnosticInfo { + let (category, code, msg) = self.category_code_and_message(); + custom( + LINT_WARNING_PREFIX, + Severity::Warning, + category, + code, + msg, + ) + } + } + + const STYLE_WARNING_FILTERS: &[(u8, u8, &str)] = &[ + $( + StyleCodes::$enum_name.category_code_and_filter_name(), + )* + ]; + } +} + +lints!( + ( + ConstantNaming, + LinterDiagnosticCategory::Style, + "constant_naming", + "constant should follow naming convention" + ), + ( + WhileTrueToLoop, + LinterDiagnosticCategory::Style, + "while_true", + "unnecessary 'while (true)', replace with 'loop'" + ), + ( + MeaninglessMath, + LinterDiagnosticCategory::Complexity, + "unnecessary_math", + "math operator can be simplified" + ), + ( + UnneededReturn, + LinterDiagnosticCategory::Style, + "unneeded_return", + "unneeded return" + ), + ( + AbortWithoutConstant, + LinterDiagnosticCategory::Style, + "abort_without_constant", + "'abort' or 'assert' without named constant" + ), + ( + LoopWithoutExit, + LinterDiagnosticCategory::Suspicious, + "loop_without_exit", + "'loop' without 'break' or 'return'" + ), + ( + UnnecessaryConditional, + LinterDiagnosticCategory::Complexity, + "unnecessary_conditional", + "'if' expression can be removed" + ), + ( + SelfAssignment, + LinterDiagnosticCategory::Suspicious, + "self_assignment", + "assignment preserves the same value" + ), + ( + RedundantRefDeref, + LinterDiagnosticCategory::Complexity, + "redundant_ref_deref", + "redundant reference/dereference" + ), + ( + UnnecessaryUnit, + LinterDiagnosticCategory::Style, + "unnecessary_unit", + "unit `()` expression can be removed or simplified" + ), + ( + EqualOperands, + LinterDiagnosticCategory::Suspicious, + "always_equal_operands", + "redundant, always-equal operands for binary operation" + ), + ( + CombinableComparisons, + LinterDiagnosticCategory::Complexity, + "combinable_comparisons", + "comparison operations condition can be simplified" + ) +); + pub const ALLOW_ATTR_CATEGORY: &str = "lint"; pub const LINT_WARNING_PREFIX: &str = "Lint "; -pub const CONSTANT_NAMING_FILTER_NAME: &str = "constant_naming"; -pub const CONSTANT_NAMING_DIAG_CODE: u8 = 1; -pub const WHILE_TRUE_TO_LOOP_FILTER_NAME: &str = "while_true"; -pub const WHILE_TRUE_TO_LOOP_DIAG_CODE: u8 = 4; pub fn known_filters() -> (Option, Vec) { ( Some(ALLOW_ATTR_CATEGORY.into()), - vec![ - WarningFilter::code( - Some(LINT_WARNING_PREFIX), - LinterDiagnosticCategory::Style as u8, - CONSTANT_NAMING_DIAG_CODE, - Some(CONSTANT_NAMING_FILTER_NAME), - ), - WarningFilter::code( - Some(LINT_WARNING_PREFIX), - LinterDiagnosticCategory::Complexity as u8, - WHILE_TRUE_TO_LOOP_DIAG_CODE, - Some(WHILE_TRUE_TO_LOOP_FILTER_NAME), - ), - ], + STYLE_WARNING_FILTERS + .iter() + .map(|(category, code, filter_name)| { + WarningFilter::code( + Some(LINT_WARNING_PREFIX), + *category, + *code, + Some(filter_name), + ) + }) + .collect(), ) } @@ -64,10 +204,18 @@ pub fn linter_visitors(level: LintLevel) -> Vec { LintLevel::None | LintLevel::Default => vec![], LintLevel::All => { vec![ - constant_naming::ConstantNamingVisitor::visitor(ConstantNamingVisitor), - unnecessary_while_loop::WhileTrueToLoop::visitor( - unnecessary_while_loop::WhileTrueToLoop, - ), + constant_naming::ConstantNaming.visitor(), + unnecessary_while_loop::WhileTrueToLoop.visitor(), + meaningless_math_operation::MeaninglessMathOperation.visitor(), + unneeded_return::UnneededReturn.visitor(), + abort_constant::AssertAbortNamedConstants.visitor(), + loop_without_exit::LoopWithoutExit.visitor(), + unnecessary_conditional::UnnecessaryConditional.visitor(), + self_assignment::SelfAssignment.visitor(), + redundant_ref_deref::RedundantRefDeref.visitor(), + unnecessary_unit::UnnecessaryUnit.visitor(), + equal_operands::EqualOperands.visitor(), + combinable_comparisons::CombinableComparisons.visitor(), ] } } diff --git a/external-crates/move/crates/move-compiler/src/linters/redundant_ref_deref.rs b/external-crates/move/crates/move-compiler/src/linters/redundant_ref_deref.rs new file mode 100644 index 00000000000..ef86c08ad6c --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/redundant_ref_deref.rs @@ -0,0 +1,132 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// Implements lint rule for Move code to detect redundant ref/deref patterns. +// It identifies and reports unnecessary temporary borrow followed by a deref, suggesting either +// removal or conversion to `copy`. + +use crate::linters::StyleCodes; +use crate::{ + diag, + typing::{ + ast::{Exp, UnannotatedExp_ as TE}, + visitor::simple_visitor, + }, +}; + +simple_visitor!( + RedundantRefDeref, + fn visit_exp_custom(&mut self, exp: &Exp) -> bool { + self.check_redundant_ref_deref(exp); + false + } +); + +impl Context<'_> { + // Check for &* pattern + fn check_redundant_ref_deref(&mut self, exp: &Exp) { + let TE::Dereference(deref_exp) = &exp.exp.value else { + return; + }; + // This is a carve-out to handle cases like `&(s.value), which generate a field borrow and + // dereference to perform a `copy`. In those cases, the location information is reused for + // both, meaning it was generated by typing, and thus not subject to warnings. + // TODO(cswords): In the future, we should mark which of these are generated during typing + // to handle paths. + if exp.exp.loc == deref_exp.exp.loc { + return; + } + match &deref_exp.exp.value { + TE::TempBorrow(_, inner) if is_simple_deref_ref_exp(inner) => self.add_diag(diag!( + StyleCodes::RedundantRefDeref.diag_info(), + ( + exp.exp.loc, + "Redundant borrow-dereference detected. \ + Remove this borrow-deref and use the expression directly." + ) + )), + TE::TempBorrow(_, inner) if all_deref_borrow(inner) => self.add_diag(diag!( + StyleCodes::RedundantRefDeref.diag_info(), + ( + exp.exp.loc, + "Redundant borrow-dereference detected. \ + Use the inner expression directly." + ) + )), + TE::Borrow(false, _, _) if exp.exp.loc != deref_exp.exp.loc => self.add_diag(diag!( + StyleCodes::RedundantRefDeref.diag_info(), + ( + exp.exp.loc, + "Redundant borrow-dereference detected. \ + Use the field access directly." + ) + )), + TE::Borrow(_, _, _) | TE::BorrowLocal(_, _) => self.add_diag(diag!( + StyleCodes::RedundantRefDeref.diag_info(), + ( + exp.exp.loc, + "Redundant borrow-dereference detected. \ + Replace this borrow-deref with 'copy'." + ) + )), + _ => (), + } + } +} + +/// Indicates if the expression is of the form `[&*]+....e` +fn all_deref_borrow(exp: &Exp) -> bool { + let TE::Dereference(deref_exp) = &exp.exp.value else { + return false; + }; + match &deref_exp.exp.value { + TE::TempBorrow(_, inner) => all_deref_borrow(inner), + TE::Borrow(_, _, _) | TE::BorrowLocal(_, _) => true, + _ => false, + } +} + +/// Indicates if the expression at hand is of a form where `&*&` can always be reduces to `&`, such +/// as function calls and constants. +fn is_simple_deref_ref_exp(exp: &Exp) -> bool { + match &exp.exp.value { + TE::Value(_) => true, + TE::Constant(_, _) => true, + TE::ErrorConstant { .. } => true, + TE::ModuleCall(_) => true, + TE::Vector(_, _, _, _) => true, + TE::Copy { .. } => true, + + TE::Cast(inner, _) | TE::Annotate(inner, _) => is_simple_deref_ref_exp(inner), + + TE::Move { .. } => false, // Copy case + TE::Use(_) => todo!(), + TE::IfElse(_, _, _) + | TE::Match(_, _) + | TE::VariantMatch(_, _, _) + | TE::Loop { .. } + | TE::NamedBlock(_, _) + | TE::Block(_) + | TE::Dereference(_) + | TE::UnaryExp(_, _) + | TE::BinopExp(_, _, _, _) + | TE::Pack(_, _, _, _) + | TE::PackVariant(_, _, _, _, _) + | TE::ExpList(_) + | TE::Borrow(_, _, _) + | TE::TempBorrow(_, _) + | TE::BorrowLocal(_, _) => false, + // These are already errors + TE::Unit { .. } + | TE::Builtin(_, _) + | TE::While(_, _, _) + | TE::Assign(_, _, _) + | TE::Return(_) + | TE::Abort(_) + | TE::Mutate(_, _) + | TE::Give(_, _) + | TE::Continue(_) + | TE::UnresolvedError => false, + } +} diff --git a/external-crates/move/crates/move-compiler/src/linters/self_assignment.rs b/external-crates/move/crates/move-compiler/src/linters/self_assignment.rs new file mode 100644 index 00000000000..468e0f6b8a1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/self_assignment.rs @@ -0,0 +1,175 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Detects and reports explicit self-assignments in code, such as `x = x;`, which are generally unnecessary +//! and could indicate potential errors or misunderstandings in the code logic. +use super::StyleCodes; +use crate::{ + diag, + naming::ast::Var, + typing::{ + ast::{self as T}, + visitor::{same_local, simple_visitor}, + }, +}; +use move_ir_types::location::Loc; +use move_proc_macros::growing_stack; + +simple_visitor!( + SelfAssignment, + fn visit_exp_custom(&mut self, e: &T::Exp) -> bool { + use T::UnannotatedExp_ as E; + match &e.exp.value { + E::Mutate(lhs, rhs) => check_mutate(self, e.exp.loc, lhs, rhs), + E::Assign(lvalues, _, rhs) => check_assign(self, lvalues, rhs), + _ => (), + } + false + } +); + +fn check_mutate(context: &mut Context, loc: Loc, lhs: &T::Exp, rhs: &T::Exp) { + #[growing_stack] + fn same_memory_location(lhs: &T::Exp, rhs: &T::Exp) -> Option<(Loc, Loc)> { + use T::UnannotatedExp_ as E; + let lhs = inner_exp(lhs); + let rhs = inner_exp(rhs); + match &lhs.exp.value { + E::Unit { .. } + | E::Value(_) + | E::Constant(_, _) + | E::ModuleCall(_) + | E::Vector(_, _, _, _) + | E::IfElse(_, _, _) + | E::Match(_, _) + | E::VariantMatch(_, _, _) + | E::While(_, _, _) + | E::Loop { .. } + | E::Assign(_, _, _) + | E::Mutate(_, _) + | E::Return(_) + | E::Abort(_) + | E::Continue(_) + | E::Give(_, _) + | E::Dereference(_) + | E::UnaryExp(_, _) + | E::BinopExp(_, _, _, _) + | E::Pack(_, _, _, _) + | E::PackVariant(_, _, _, _, _) + | E::ExpList(_) + | E::TempBorrow(_, _) + | E::Cast(_, _) + | E::ErrorConstant { .. } + | E::UnresolvedError => None, + E::Block(s) | E::NamedBlock(_, s) => { + debug_assert!(s.1.len() > 1); + None + } + + E::Move { var: l, .. } | E::Copy { var: l, .. } | E::Use(l) | E::BorrowLocal(_, l) => { + same_local(l, rhs) + } + E::Builtin(b1, l) => { + if !gives_memory_location(b1) { + return None; + } + match &rhs.exp.value { + E::Builtin(b2, r) if b1 == b2 => same_memory_location(l, r), + _ => None, + } + } + E::Borrow(_, l, lfield) => match &rhs.exp.value { + E::Borrow(_, r, rfield) if lfield == rfield => { + same_memory_location(l, r)?; + Some((lhs.exp.loc, rhs.exp.loc)) + } + _ => None, + }, + + E::Annotate(_, _) => unreachable!(), + } + } + + let rhs = inner_exp(rhs); + let rhs = match &rhs.exp.value { + T::UnannotatedExp_::Dereference(inner) => inner, + _ => rhs, + }; + let Some((lhs_loc, rhs_loc)) = same_memory_location(lhs, rhs) else { + return; + }; + report_self_assignment(context, "mutation", loc, lhs_loc, rhs_loc); +} + +fn check_assign(context: &mut Context, sp!(_, lvalues_): &T::LValueList, rhs: &T::Exp) { + let vars = lvalues_.iter().map(lvalue_var).collect::>(); + let rhs_items = exp_list_items(rhs); + for (lhs_opt, rhs) in vars.into_iter().zip(rhs_items) { + let Some((loc, lhs)) = lhs_opt else { + continue; + }; + if let Some((lhs_loc, rhs_loc)) = same_local(lhs, rhs) { + report_self_assignment(context, "assignment", loc, lhs_loc, rhs_loc); + } + } +} + +fn gives_memory_location(sp!(_, b_): &T::BuiltinFunction) -> bool { + match b_ { + T::BuiltinFunction_::Freeze(_) => true, + T::BuiltinFunction_::Assert(_) => false, + } +} + +fn inner_exp(mut e: &T::Exp) -> &T::Exp { + use T::UnannotatedExp_ as E; + loop { + match &e.exp.value { + E::Annotate(inner, _) => e = inner, + E::Block((_, seq)) | E::NamedBlock(_, (_, seq)) if seq.len() == 1 => { + match &seq[0].value { + T::SequenceItem_::Seq(inner) => e = inner, + T::SequenceItem_::Declare(_) | T::SequenceItem_::Bind(_, _, _) => break e, + } + } + _ => break e, + } + } +} + +fn lvalue_var(sp!(loc, lvalue_): &T::LValue) -> Option<(Loc, &Var)> { + use T::LValue_ as L; + match &lvalue_ { + L::Var { var, .. } => Some((*loc, var)), + L::Ignore + | L::Unpack(_, _, _, _) + | L::BorrowUnpack(_, _, _, _, _) + | L::UnpackVariant(_, _, _, _, _) + | L::BorrowUnpackVariant(_, _, _, _, _, _) => None, + } +} + +fn exp_list_items(e: &T::Exp) -> Vec<&T::Exp> { + match &inner_exp(e).exp.value { + T::UnannotatedExp_::ExpList(items) => items + .iter() + .flat_map(|item| match item { + T::ExpListItem::Single(e, _) => vec![e], + T::ExpListItem::Splat(_, e, _) => exp_list_items(e), + }) + .collect::>(), + _ => vec![e], + } +} + +fn report_self_assignment(context: &mut Context, case: &str, eloc: Loc, lloc: Loc, rloc: Loc) { + let msg = + format!("Unnecessary self-{case}. The {case} is redundant and will not change the value"); + context.add_diag(diag!( + StyleCodes::SelfAssignment.diag_info(), + (eloc, msg), + (lloc, "This location"), + (rloc, "Is the same as this location"), + )); +} diff --git a/external-crates/move/crates/move-compiler/src/linters/unnecessary_conditional.rs b/external-crates/move/crates/move-compiler/src/linters/unnecessary_conditional.rs new file mode 100644 index 00000000000..f9c2c393490 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/unnecessary_conditional.rs @@ -0,0 +1,97 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Detects and suggests simplification for `if (c) e1 else e2` can be removed +use move_proc_macros::growing_stack; + +use crate::expansion::ast::Value; +use crate::linters::StyleCodes; +use crate::{ + diag, + expansion::ast::Value_, + typing::{ + ast::{self as T, SequenceItem_, UnannotatedExp_}, + visitor::simple_visitor, + }, +}; + +simple_visitor!( + UnnecessaryConditional, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { + let UnannotatedExp_::IfElse(_, etrue, efalse) = &exp.exp.value else { + return false; + }; + let Some(vtrue) = extract_value(etrue) else { + return false; + }; + let Some(vfalse) = efalse.as_ref().and_then(|efalse| extract_value(efalse)) else { + return false; + }; + + match (&vtrue.value, &vfalse.value) { + (Value_::Bool(v1 @ true), Value_::Bool(false)) + | (Value_::Bool(v1 @ false), Value_::Bool(true)) => { + let negation = if *v1 { "" } else { "!" }; + let msg = format!( + "Detected an unnecessary conditional expression 'if (cond)'. Consider using \ + the condition directly, i.e. '{negation}cond'", + ); + self.add_diag(diag!( + StyleCodes::UnnecessaryConditional.diag_info(), + (exp.exp.loc, msg) + )); + } + (v1, v2) if v1 == v2 => { + let msg = + "Detected a redundant conditional expression 'if (..) v else v', where each \ + branch results in the same value 'v'. Consider using the value directly"; + self.add_diag(diag!( + StyleCodes::UnnecessaryConditional.diag_info(), + (exp.exp.loc, msg), + (vtrue.loc, "This value"), + (vfalse.loc, "is the same as this value"), + )); + } + _ => (), + } + + // if let (Some(if_bool), Some(else_bool)) = ( + // extract_bool_literal_from_block(if_block), + // extract_bool_literal_from_block(else_block), + // ) { + // if if_bool != else_bool { + // let msg = format!( + // "Detected a redundant conditional expression `if (...) {} else {}`. Consider using the condition directly.", + // if_bool, else_bool + // ); + // let diag = diag!( + // StyleCodes::UnnecessaryConditional.diag_info(), + // (exp.exp.loc, msg) + // ); + + // self.env.add_diag(diag); + // } + // } + // } + false + } +); + +#[growing_stack] +fn extract_value(block: &T::Exp) -> Option<&Value> { + match &block.exp.value { + UnannotatedExp_::Block((_, seq)) if seq.len() == 1 => extract_value_seq_item(&seq[0]), + UnannotatedExp_::Value(v) => Some(v), + UnannotatedExp_::Annotate(e, _) => extract_value(e), + _ => None, + } +} + +#[growing_stack] +fn extract_value_seq_item(sp!(_, item_): &T::SequenceItem) -> Option<&Value> { + match &item_ { + SequenceItem_::Declare(_) | SequenceItem_::Bind(_, _, _) => None, + SequenceItem_::Seq(e) => extract_value(e), + } +} diff --git a/external-crates/move/crates/move-compiler/src/linters/unnecessary_unit.rs b/external-crates/move/crates/move-compiler/src/linters/unnecessary_unit.rs new file mode 100644 index 00000000000..6aa684b460e --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/unnecessary_unit.rs @@ -0,0 +1,83 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Detects an unnecessary unit expression in a block, sequence, if, or else. + +use crate::{ + diag, ice, + linters::StyleCodes, + typing::{ + ast::{self as T, UnannotatedExp_}, + visitor::simple_visitor, + }, +}; +use move_ir_types::location::Loc; + +simple_visitor!( + UnnecessaryUnit, + fn visit_seq_custom(&mut self, loc: Loc, (_, seq_): &T::Sequence) -> bool { + let n = seq_.len(); + match n { + 0 => { + self.add_diag(ice!((loc, "Unexpected empty block without a value"))); + } + 1 => { + // TODO probably too noisy for now, we would need more information about + // blocks were added by the programmer + // self.env.add_diag(diag!( + // StyleCodes::UnnecessaryBlock.diag_info(), + // (e.exp.loc, "Unnecessary block expression '{}')" + // (e.exp.loc, if_msg), + // )); + } + n => { + let last = n - 1; + for (i, stmt) in seq_.iter().enumerate() { + if i != last && stmt.value.is_unit(&self.reporter) { + let msg = "Unnecessary unit in sequence '();'. Consider removing"; + self.add_diag(diag!( + StyleCodes::UnnecessaryUnit.diag_info(), + (stmt.loc, msg), + )); + } + } + } + } + false + }, + fn visit_exp_custom(&mut self, e: &T::Exp) -> bool { + use UnannotatedExp_ as TE; + let TE::IfElse(e_cond, e_true, e_false_opt) = &e.exp.value else { + return false; + }; + if e_true.is_unit(&self.reporter) { + let u_msg = "Unnecessary unit '()'"; + let if_msg = "Consider negating the 'if' condition and simplifying"; + let mut diag = diag!( + StyleCodes::UnnecessaryUnit.diag_info(), + (e_true.exp.loc, u_msg), + (e_cond.exp.loc, if_msg), + ); + diag.add_note("For example 'if (cond) () else e' can be simplified to 'if (!cond) e'"); + self.add_diag(diag); + } + if let Some(e_false) = e_false_opt { + if e_false.is_unit(&self.reporter) { + let u_msg = "Unnecessary 'else ()'."; + let if_msg = "An 'if' without an 'else' has an implicit 'else ()'. \ + Consider removing the 'else' branch"; + let mut diag = diag!( + StyleCodes::UnnecessaryUnit.diag_info(), + (e_false.exp.loc, u_msg), + (e.exp.loc, if_msg), + ); + diag.add_note( + "For example 'if (cond) e else ()' can be simplified to 'if (cond) e'", + ); + self.add_diag(diag); + } + } + false + } +); diff --git a/external-crates/move/crates/move-compiler/src/linters/unnecessary_while_loop.rs b/external-crates/move/crates/move-compiler/src/linters/unnecessary_while_loop.rs index b2878c2a740..683f90fa4b0 100644 --- a/external-crates/move/crates/move-compiler/src/linters/unnecessary_while_loop.rs +++ b/external-crates/move/crates/move-compiler/src/linters/unnecessary_while_loop.rs @@ -6,53 +6,19 @@ //! for clarity and conciseness. Identifies `while(true)` patterns, suggesting a //! more idiomatic approach using `loop`. Aims to enhance code readability and //! adherence to Rust idioms. - -use super::{LinterDiagnosticCategory, LINT_WARNING_PREFIX, WHILE_TRUE_TO_LOOP_DIAG_CODE}; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, expansion::ast::Value_, - shared::CompilationEnv, + linters::StyleCodes, typing::{ ast::{self as T, UnannotatedExp_}, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, + visitor::simple_visitor, }, }; -const WHILE_TRUE_TO_LOOP_DIAG: DiagnosticInfo = custom( - LINT_WARNING_PREFIX, - Severity::Warning, - LinterDiagnosticCategory::Complexity as u8, - WHILE_TRUE_TO_LOOP_DIAG_CODE, - "unnecessary 'while (true)', replace with 'loop'", -); - -pub struct WhileTrueToLoop; - -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} - -impl TypingVisitorConstructor for WhileTrueToLoop { - type Context<'a> = Context<'a>; - - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } - - fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { +simple_visitor!( + WhileTrueToLoop, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { let UnannotatedExp_::While(_, cond, _) = &exp.exp.value else { return false; }; @@ -61,13 +27,13 @@ impl TypingVisitorContext for Context<'_> { }; let msg = "'while (true)' can be always replaced with 'loop'"; - let mut diag = diag!(WHILE_TRUE_TO_LOOP_DIAG, (exp.exp.loc, msg)); + let mut diag = diag!(StyleCodes::WhileTrueToLoop.diag_info(), (exp.exp.loc, msg)); diag.add_note( "A 'loop' is more useful in these cases. Unlike 'while', 'loop' can have a \ 'break' with a value, e.g. 'let x = loop { break 42 };'", ); - self.env.add_diag(diag); + self.add_diag(diag); false } -} +); diff --git a/external-crates/move/crates/move-compiler/src/linters/unneeded_return.rs b/external-crates/move/crates/move-compiler/src/linters/unneeded_return.rs new file mode 100644 index 00000000000..0aab26f965b --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/linters/unneeded_return.rs @@ -0,0 +1,196 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! `UnneededReturnVisitor` enforces that users don't write `return ` where `` is a +//! value-like thing. + +use crate::{ + diag, + expansion::ast::ModuleIdent, + linters::StyleCodes, + parser::ast::FunctionName, + typing::{ast as T, visitor::simple_visitor}, +}; + +use move_ir_types::location::Loc; +use move_proc_macros::growing_stack; + +use std::collections::VecDeque; + +simple_visitor!( + UnneededReturn, + fn visit_function_custom( + &mut self, + _module: ModuleIdent, + _function_name: FunctionName, + fdef: &T::Function, + ) -> bool { + if let T::FunctionBody_::Defined((_, seq)) = &fdef.body.value { + tail_block(self, seq); + }; + true + } +); + +/// Recur down the tail (last) position of the sequence, looking for returns that +/// might occur in the function's taul/return position.. +#[growing_stack] +fn tail_block(context: &mut Context, seq: &VecDeque) { + let Some(last) = seq.back() else { return }; + match &last.value { + T::SequenceItem_::Seq(exp) => tail(context, exp), + // These don't make sense and shouldn't occur, but are irrelevant to us. + T::SequenceItem_::Declare(_) | T::SequenceItem_::Bind(_, _, _) => (), + } +} + +/// Recur down the tail (last) position of each expression, looking for returns that +/// might occur in the function's taul/return position. +#[growing_stack] +fn tail(context: &mut Context, exp: &T::Exp) { + match &exp.exp.value { + T::UnannotatedExp_::IfElse(_, conseq, alt_opt) => { + tail(context, conseq); + if let Some(alt) = alt_opt { + tail(context, alt); + } + } + T::UnannotatedExp_::Match(_, arms) => { + for arm in &arms.value { + tail(context, &arm.value.rhs); + } + } + T::UnannotatedExp_::VariantMatch(_, _, arms) => { + for (_, rhs) in arms { + tail(context, rhs); + } + } + T::UnannotatedExp_::NamedBlock(_, (_, seq)) => { + tail_block(context, seq); + } + T::UnannotatedExp_::Block((_, seq)) => { + tail_block(context, seq); + } + T::UnannotatedExp_::Return(rhs) => { + if returnable_value(context, rhs) { + report_unneeded_return(context, exp.exp.loc); + } + } + + // These cases we don't care about, because they are: + // - loops + // - effects + // - values already + T::UnannotatedExp_::Builtin(_, _) + | T::UnannotatedExp_::Vector(_, _, _, _) + | T::UnannotatedExp_::While(_, _, _) + | T::UnannotatedExp_::Loop { .. } + | T::UnannotatedExp_::Assign(_, _, _) + | T::UnannotatedExp_::Mutate(_, _) + | T::UnannotatedExp_::Abort(_) + | T::UnannotatedExp_::Give(_, _) + | T::UnannotatedExp_::Continue(_) + | T::UnannotatedExp_::Unit { .. } + | T::UnannotatedExp_::Value(_) + | T::UnannotatedExp_::Move { .. } + | T::UnannotatedExp_::Copy { .. } + | T::UnannotatedExp_::Use(_) + | T::UnannotatedExp_::Constant(_, _) + | T::UnannotatedExp_::ModuleCall(_) + | T::UnannotatedExp_::Dereference(_) + | T::UnannotatedExp_::UnaryExp(_, _) + | T::UnannotatedExp_::BinopExp(_, _, _, _) + | T::UnannotatedExp_::Pack(_, _, _, _) + | T::UnannotatedExp_::PackVariant(_, _, _, _, _) + | T::UnannotatedExp_::ExpList(_) + | T::UnannotatedExp_::Borrow(_, _, _) + | T::UnannotatedExp_::TempBorrow(_, _) + | T::UnannotatedExp_::BorrowLocal(_, _) + | T::UnannotatedExp_::Cast(_, _) + | T::UnannotatedExp_::Annotate(_, _) + | T::UnannotatedExp_::ErrorConstant { .. } + | T::UnannotatedExp_::UnresolvedError => (), + } +} + +/// Indicates if the expression is "value"-like, in that it produces a value. This is just to +/// reduce noise for the lint, because things like `return loop { abort 0 }` is technically an +/// unnecessary return, but we don't need to complain about weird code like that. +#[growing_stack] +fn returnable_value(context: &mut Context, exp: &T::Exp) -> bool { + match &exp.exp.value { + T::UnannotatedExp_::Return(rhs) => { + if returnable_value(context, rhs) { + report_unneeded_return(context, exp.exp.loc); + }; + false + } + + T::UnannotatedExp_::BinopExp(lhs, _, _, rhs) => { + returnable_value(context, lhs) && returnable_value(context, rhs) + } + T::UnannotatedExp_::ExpList(values) => values.iter().all(|v| match v { + T::ExpListItem::Single(exp, _) => returnable_value(context, exp), + T::ExpListItem::Splat(_, _, _) => false, + }), + T::UnannotatedExp_::Borrow(_, exp, _) + | T::UnannotatedExp_::Dereference(exp) + | T::UnannotatedExp_::UnaryExp(_, exp) + | T::UnannotatedExp_::TempBorrow(_, exp) + | T::UnannotatedExp_::Cast(exp, _) + | T::UnannotatedExp_::Annotate(exp, _) => returnable_value(context, exp), + + T::UnannotatedExp_::Pack(_, _, _, _) + | T::UnannotatedExp_::PackVariant(_, _, _, _, _) + | T::UnannotatedExp_::Unit { .. } + | T::UnannotatedExp_::Value(_) + | T::UnannotatedExp_::Move { .. } + | T::UnannotatedExp_::Copy { .. } + | T::UnannotatedExp_::Use(_) + | T::UnannotatedExp_::Constant(_, _) + | T::UnannotatedExp_::ModuleCall(_) + | T::UnannotatedExp_::Builtin(_, _) + | T::UnannotatedExp_::BorrowLocal(_, _) + | T::UnannotatedExp_::ErrorConstant { .. } + | T::UnannotatedExp_::Vector(_, _, _, _) => true, + + T::UnannotatedExp_::IfElse(_, _, _) + | T::UnannotatedExp_::Match(_, _) + | T::UnannotatedExp_::VariantMatch(_, _, _) => true, + + // While loops can't yield values, so there should already be other errors. + T::UnannotatedExp_::While(_, _, _) => false, + + // Non-while loops _can_ yield values, and should never appear after a return if the + // value is intended. + T::UnannotatedExp_::Loop { .. } => true, + + T::UnannotatedExp_::NamedBlock(_, (_, seq)) | T::UnannotatedExp_::Block((_, seq)) => { + let Some(last) = seq.back() else { return false }; + match &last.value { + T::SequenceItem_::Seq(exp) => returnable_value(context, exp), + T::SequenceItem_::Declare(_) | T::SequenceItem_::Bind(_, _, _) => false, + } + } + + // These don't really make sense in return position, so there should already be other + // errors. + T::UnannotatedExp_::Assign(_, _, _) + | T::UnannotatedExp_::Mutate(_, _) + | T::UnannotatedExp_::Abort(_) + | T::UnannotatedExp_::Give(_, _) + | T::UnannotatedExp_::Continue(_) => false, + T::UnannotatedExp_::UnresolvedError => false, + } +} + +fn report_unneeded_return(context: &mut Context, loc: Loc) { + context.add_diag(diag!( + StyleCodes::UnneededReturn.diag_info(), + ( + loc, + "Remove unnecessary 'return', the expression is already in a 'return' position" + ) + )); +} diff --git a/external-crates/move/crates/move-compiler/src/naming/ast.rs b/external-crates/move/crates/move-compiler/src/naming/ast.rs index f704c2661a9..b3c2cae1b20 100644 --- a/external-crates/move/crates/move-compiler/src/naming/ast.rs +++ b/external-crates/move/crates/move-compiler/src/naming/ast.rs @@ -6,6 +6,7 @@ use std::{ collections::{BTreeMap, BTreeSet, VecDeque}, fmt, + sync::Arc, }; use move_ir_types::location::*; @@ -13,15 +14,15 @@ use move_symbol_pool::Symbol; use once_cell::sync::Lazy; use crate::{ - diagnostics::WarningFilters, + diagnostics::warning_filters::{WarningFilters, WarningFiltersTable}, expansion::ast::{ - ability_constraints_ast_debug, ability_modifiers_ast_debug, AbilitySet, Attributes, - DottedUsage, Fields, Friend, ImplicitUseFunCandidate, ModuleIdent, Mutability, TargetKind, - Value, Value_, Visibility, + AbilitySet, Attributes, DottedUsage, Fields, Friend, ImplicitUseFunCandidate, ModuleIdent, + Mutability, TargetKind, Value, Value_, Visibility, ability_constraints_ast_debug, + ability_modifiers_ast_debug, }, parser::ast::{ - self as P, Ability_, BinOp, ConstantName, DatatypeName, Field, FunctionName, UnaryOp, - VariantName, ENTRY_MODIFIER, MACRO_MODIFIER, NATIVE_MODIFIER, + self as P, Ability_, BinOp, ConstantName, DatatypeName, ENTRY_MODIFIER, Field, + FunctionName, MACRO_MODIFIER, NATIVE_MODIFIER, UnaryOp, VariantName, }, shared::{ ast_debug::*, known_attributes::SyntaxAttribute, program_info::NamingProgramInfo, @@ -36,6 +37,9 @@ use crate::{ #[derive(Debug, Clone)] pub struct Program { pub info: NamingProgramInfo, + /// Safety: This table should not be dropped as long as any `WarningFilters` + /// are alive + pub warning_filters_table: Arc, pub inner: Program_, } @@ -232,6 +236,7 @@ pub struct Function { // index in the original order as defined in the source file pub index: usize, pub attributes: Attributes, + pub loc: Loc, pub visibility: Visibility, pub entry: Option, pub macro_: Option, @@ -304,7 +309,7 @@ pub struct TParam { } #[derive(Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] -pub struct TVar(u64); +pub struct TVar(pub u64); #[derive(Debug, Eq, PartialEq, Clone)] #[allow(clippy::large_enum_variant)] @@ -360,9 +365,10 @@ pub type LambdaLValues = Spanned; #[derive(Debug, PartialEq, Clone)] pub enum ExpDotted_ { Exp(Box), - Dot(Box, Field), + Dot(Box, /* dot loation */ Loc, Field), Index(Box, Spanned>), - DotAutocomplete(Loc, Box), // Dot (and its location) where Field could not be parsed + DotAutocomplete(Loc, Box), /* Dot (and its location) where Field could not be + * parsed */ } pub type ExpDotted = Spanned; @@ -420,6 +426,7 @@ pub enum Exp_ { ), MethodCall( ExpDotted, + Loc, // location of the dot Name, // is_macro Option, @@ -430,7 +437,7 @@ pub enum Exp_ { Builtin(BuiltinFunction, Spanned>), Vector(Loc, Option, Spanned>), - IfElse(Box, Box, Box), + IfElse(Box, Box, Option>), Match(Box, Spanned>), While(BlockLabel, Box, Box), Loop(BlockLabel, Box), @@ -720,12 +727,6 @@ impl TParamID { } } -impl TVar { - pub fn next() -> TVar { - TVar(Counter::next()) - } -} - static BUILTIN_FUNCTION_ALL_NAMES: Lazy> = Lazy::new(|| { [BuiltinFunction_::FREEZE, BuiltinFunction_::ASSERT_MACRO] .into_iter() @@ -759,12 +760,10 @@ impl BuiltinFunction_ { } impl TypeName_ { - pub fn is( - &self, - address: impl AsRef, - module: impl AsRef, - name: impl AsRef, - ) -> bool { + pub fn is(&self, address: &Addr, module: impl AsRef, name: impl AsRef) -> bool + where + NumericalAddress: PartialEq, + { match self { TypeName_::Builtin(_) | TypeName_::Multiple(_) => false, TypeName_::ModuleType(mident, n) => { @@ -896,12 +895,10 @@ impl Type_ { } } - pub fn is( - &self, - address: impl AsRef, - module: impl AsRef, - name: impl AsRef, - ) -> bool { + pub fn is(&self, address: &Addr, module: impl AsRef, name: impl AsRef) -> bool + where + NumericalAddress: PartialEq, + { self.type_name() .is_some_and(|tn| tn.value.is(address, module, name)) } @@ -1006,22 +1003,18 @@ impl Value_ { impl fmt::Display for BuiltinTypeName_ { fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { use BuiltinTypeName_ as BT; - write!( - f, - "{}", - match self { - BT::Address => BT::ADDRESS, - BT::Signer => BT::SIGNER, - BT::U8 => BT::U_8, - BT::U16 => BT::U_16, - BT::U32 => BT::U_32, - BT::U64 => BT::U_64, - BT::U128 => BT::U_128, - BT::U256 => BT::U_256, - BT::Bool => BT::BOOL, - BT::Vector => BT::VECTOR, - } - ) + write!(f, "{}", match self { + BT::Address => BT::ADDRESS, + BT::Signer => BT::SIGNER, + BT::U8 => BT::U_8, + BT::U16 => BT::U_16, + BT::U32 => BT::U_32, + BT::U64 => BT::U_64, + BT::U128 => BT::U_128, + BT::U256 => BT::U_256, + BT::Bool => BT::BOOL, + BT::Vector => BT::VECTOR, + }) } } @@ -1038,15 +1031,11 @@ impl fmt::Display for TypeName_ { impl std::fmt::Display for NominalBlockUsage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - match self { - NominalBlockUsage::Return => "return", - NominalBlockUsage::Break => "break", - NominalBlockUsage::Continue => "continue", - } - ) + write!(f, "{}", match self { + NominalBlockUsage::Return => "return", + NominalBlockUsage::Break => "break", + NominalBlockUsage::Continue => "continue", + }) } } @@ -1073,7 +1062,7 @@ impl AstDebug for Program_ { fn ast_debug(&self, w: &mut AstWriter) { let Self { modules } = self; for (m, mdef) in modules.key_cloned_iter() { - w.write(&format!("module {}", m)); + w.write(format!("module {}", m)); w.block(|w| mdef.ast_debug(w)); w.new_line(); } @@ -1111,7 +1100,7 @@ impl AstDebug for UseFun { UseFunKind::FunctionDeclaration => "#fundecl", }; let usage = if *used { "#used" } else { "#unused" }; - w.write(&format!("use{kind_str}{usage} {target_m}::{target_f}")); + w.write(format!("use{kind_str}{usage} {target_m}::{target_f}")); } } @@ -1122,7 +1111,7 @@ impl AstDebug for (&TypeName, &UniqueMap) { use_fun.ast_debug(w); w.write(" as "); tn.ast_debug(w); - w.writeln(&format!(".{method_f};")); + w.writeln(format!(".{method_f};")); } } } @@ -1142,7 +1131,7 @@ impl AstDebug for UseFuns { resolved, implicit_candidates, } = self; - w.write(&format!("use_funs#{} ", color)); + w.write(format!("use_funs#{} ", color)); resolved.ast_debug(w); if !implicit_candidates.is_empty() { w.write("unresolved "); @@ -1166,7 +1155,7 @@ impl AstDebug for SyntaxMethod { kind, } = self; let kind_str = format!("{:?}", kind.value); - w.write(&format!( + w.write(format!( "syntax({kind_str}) for {tname} -> {target_m}::{target_f}\n" )); } @@ -1214,7 +1203,7 @@ impl AstDebug for ModuleDefinition { } = self; warning_filter.ast_debug(w); if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); w.writeln(match target_kind { @@ -1229,7 +1218,7 @@ impl AstDebug for ModuleDefinition { use_funs.ast_debug(w); syntax_methods.ast_debug(w); for (mident, _loc) in friends.key_cloned_iter() { - w.write(&format!("friend {};", mident)); + w.write(format!("friend {};", mident)); w.new_line(); } for sdef in structs.key_cloned_iter() { @@ -1270,7 +1259,7 @@ impl AstDebug for (DatatypeName, &StructDefinition) { if let StructFields::Native(_) = fields { w.write("native "); } - w.write(&format!("struct#{index} {name}")); + w.write(format!("struct#{index} {name}")); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); if let StructFields::Defined(is_positional, fields) = fields { @@ -1280,7 +1269,7 @@ impl AstDebug for (DatatypeName, &StructDefinition) { w.block(|w| { w.list(fields, ",", |w, (_, f, idx_st)| { let (idx, st) = idx_st; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); st.ast_debug(w); true }) @@ -1306,7 +1295,7 @@ impl AstDebug for (DatatypeName, &EnumDefinition) { warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("enum#{index} {name}")); + w.write(format!("enum#{index} {name}")); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); w.block(|w| { @@ -1328,7 +1317,7 @@ impl AstDebug for (VariantName, &VariantDefinition) { }, ) = self; - w.write(&format!("variant#{index} {name}")); + w.write(format!("variant#{index} {name}")); match fields { VariantFields::Defined(is_positional, fields) => { if *is_positional { @@ -1337,7 +1326,7 @@ impl AstDebug for (VariantName, &VariantDefinition) { w.block(|w| { w.list(fields, ",", |w, (_, f, idx_st)| { let (idx, st) = idx_st; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); st.ast_debug(w); true }); @@ -1356,6 +1345,7 @@ impl AstDebug for (FunctionName, &Function) { warning_filter, index, attributes, + loc: _, visibility, macro_, entry, @@ -1367,15 +1357,15 @@ impl AstDebug for (FunctionName, &Function) { attributes.ast_debug(w); visibility.ast_debug(w); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if macro_.is_some() { - w.write(&format!("{} ", MACRO_MODIFIER)); + w.write(format!("{} ", MACRO_MODIFIER)); } if let FunctionBody_::Native = &body.value { - w.write(&format!("{} ", NATIVE_MODIFIER)); + w.write(format!("{} ", NATIVE_MODIFIER)); } - w.write(&format!("fun#{index} {name}")); + w.write(format!("fun#{index} {name}")); signature.ast_debug(w); match &body.value { FunctionBody_::Defined(body) => body.ast_debug(w), @@ -1409,12 +1399,12 @@ impl AstDebug for Var_ { let Self { name, id, color } = self; let id = *id; let color = *color; - w.write(&format!("{name}")); + w.write(format!("{name}")); if id != 0 { - w.write(&format!("#{id}")); + w.write(format!("#{id}")); } if color != 0 { - w.write(&format!("#{color}")); + w.write(format!("#{color}")); } } } @@ -1425,12 +1415,12 @@ impl AstDebug for BlockLabel { is_implicit: _, label: sp!(_, Var_ { name, id, color }), } = self; - w.write(&format!("'{name}")); + w.write(format!("'{name}")); if *id != 0 { - w.write(&format!("#{id}")); + w.write(format!("#{id}")); } if *color != 0 { - w.write(&format!("#{color}")); + w.write(format!("#{color}")); } } } @@ -1470,7 +1460,7 @@ impl AstDebug for (ConstantName, &Constant) { ) = self; warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("const#{index} {name}:")); + w.write(format!("const#{index} {name}:")); signature.ast_debug(w); w.write(" = "); value.ast_debug(w); @@ -1480,16 +1470,16 @@ impl AstDebug for (ConstantName, &Constant) { impl AstDebug for BuiltinTypeName_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)); + w.write(format!("{}", self)); } } impl AstDebug for TypeName_ { fn ast_debug(&self, w: &mut AstWriter) { match self { - TypeName_::Multiple(len) => w.write(&format!("Multiple({})", len)), + TypeName_::Multiple(len) => w.write(format!("Multiple({})", len)), TypeName_::Builtin(bt) => bt.ast_debug(w), - TypeName_::ModuleType(m, s) => w.write(&format!("{}::{}", m, s)), + TypeName_::ModuleType(m, s) => w.write(format!("{}::{}", m, s)), } } } @@ -1501,7 +1491,7 @@ impl AstDebug for TParam { user_specified_name, abilities, } = self; - w.write(&format!("{}#{}", user_specified_name, id.0)); + w.write(format!("{}#{}", user_specified_name, id.0)); ability_constraints_ast_debug(w, abilities); } } @@ -1569,7 +1559,7 @@ impl AstDebug for Type_ { w.write("|"); result.ast_debug(w); } - Type_::Var(tv) => w.write(&format!("#{}", tv.0)), + Type_::Var(tv) => w.write(format!("#{}", tv.0)), Type_::Anything => w.write("_"), Type_::UnresolvedError => w.write("_|_"), } @@ -1624,9 +1614,9 @@ impl AstDebug for Exp_ { } => w.write("/*()*/"), E::Value(v) => v.ast_debug(w), E::Var(v) => v.ast_debug(w), - E::Constant(m, c) => w.write(&format!("{}::{}", m, c)), + E::Constant(m, c) => w.write(format!("{}::{}", m, c)), E::ModuleCall(m, f, is_macro, tys_opt, sp!(_, rhs)) => { - w.write(&format!("{}::{}", m, f)); + w.write(format!("{}::{}", m, f)); if is_macro.is_some() { w.write("!"); } @@ -1639,9 +1629,9 @@ impl AstDebug for Exp_ { w.comma(rhs, |w, e| e.ast_debug(w)); w.write(")"); } - E::MethodCall(e, f, is_macro, tys_opt, sp!(_, rhs)) => { + E::MethodCall(e, _, f, is_macro, tys_opt, sp!(_, rhs)) => { e.ast_debug(w); - w.write(&format!(".{}", f)); + w.write(format!(".{}", f)); if is_macro.is_some() { w.write("!"); } @@ -1678,7 +1668,7 @@ impl AstDebug for Exp_ { w.write("]"); } E::Pack(m, s, tys_opt, fields) => { - w.write(&format!("{}::{}", m, s)); + w.write(format!("{}::{}", m, s)); if let Some(ss) = tys_opt { w.write("<"); ss.ast_debug(w); @@ -1687,13 +1677,13 @@ impl AstDebug for Exp_ { w.write("{"); w.comma(fields, |w, (_, f, idx_e)| { let (idx, e) = idx_e; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); e.ast_debug(w); }); w.write("}"); } E::PackVariant(m, e, v, tys_opt, fields) => { - w.write(&format!("{}::{}::{}", m, e, v)); + w.write(format!("{}::{}::{}", m, e, v)); if let Some(ss) = tys_opt { w.write("<"); ss.ast_debug(w); @@ -1702,18 +1692,20 @@ impl AstDebug for Exp_ { w.write("{"); w.comma(fields, |w, (_, f, idx_e)| { let (idx, e) = idx_e; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); e.ast_debug(w); }); w.write("}"); } - E::IfElse(b, t, f) => { + E::IfElse(b, t, f_opt) => { w.write("if ("); b.ast_debug(w); w.write(") "); t.ast_debug(w); - w.write(" else "); - f.ast_debug(w); + if let Some(f) = f_opt { + w.write(" else "); + f.ast_debug(w); + } } E::Match(subject, arms) => { w.write("match ("); @@ -1774,7 +1766,7 @@ impl AstDebug for Exp_ { e.ast_debug(w); } E::Give(usage, name, e) => { - w.write(&format!("give#{usage} '")); + w.write(format!("give#{usage} '")); name.ast_debug(w); w.write(" "); e.ast_debug(w); @@ -1846,7 +1838,7 @@ impl AstDebug for Lambda { w.write(" -> "); ty.ast_debug(w); } - w.write(&format!("use_funs#{}", use_fun_color)); + w.write(format!("use_funs#{}", use_fun_color)); e.ast_debug(w); } } @@ -1890,9 +1882,9 @@ impl AstDebug for ExpDotted_ { use ExpDotted_ as D; match self { D::Exp(e) => e.ast_debug(w), - D::Dot(e, n) => { + D::Dot(e, _, n) => { e.ast_debug(w); - w.write(&format!(".{}", n)) + w.write(format!(".{}", n)) } D::Index(e, sp!(_, args)) => { e.ast_debug(w); @@ -2021,7 +2013,7 @@ impl AstDebug for LValue_ { } } L::Unpack(m, s, tys_opt, fields) => { - w.write(&format!("{}::{}", m, s)); + w.write(format!("{}::{}", m, s)); if let Some(ss) = tys_opt { w.write("<"); ss.ast_debug(w); @@ -2030,7 +2022,7 @@ impl AstDebug for LValue_ { w.write("{"); w.comma(fields, |w, (_, f, idx_b)| { let (idx, b) = idx_b; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); b.ast_debug(w); }); w.write("}"); diff --git a/external-crates/move/crates/move-compiler/src/naming/fake_natives.rs b/external-crates/move/crates/move-compiler/src/naming/fake_natives.rs index 4d0033a8850..933c486bae7 100644 --- a/external-crates/move/crates/move-compiler/src/naming/fake_natives.rs +++ b/external-crates/move/crates/move-compiler/src/naming/fake_natives.rs @@ -14,15 +14,16 @@ use move_symbol_pool::symbol; use crate::{ diag, + diagnostics::DiagnosticReporter, expansion::ast::{Address, ModuleIdent, ModuleIdent_}, naming::ast as N, parser::ast::FunctionName, - shared::{known_attributes::NativeAttribute, CompilationEnv, Identifier}, + shared::{known_attributes::NativeAttribute, Identifier}, }; /// verify fake native attribute usage usage pub fn function( - env: &mut CompilationEnv, + reporter: &DiagnosticReporter, module: ModuleIdent, function_name: FunctionName, function: &N::Function, @@ -48,7 +49,7 @@ pub fn function( (loc, attr_msg), (function_name.loc(), name_msg), ); - env.add_diag(diag); + reporter.add_diag(diag); } match &function.body.value { N::FunctionBody_::Native => (), @@ -58,7 +59,7 @@ pub fn function( NativeAttribute::BYTECODE_INSTRUCTION ); let diag = diag!(Attributes::InvalidBytecodeInst, (loc, attr_msg)); - env.add_diag(diag); + reporter.add_diag(diag); } } } diff --git a/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs b/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs index 545b02d3dcc..8eb90ee8b8d 100644 --- a/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs +++ b/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs @@ -7,6 +7,7 @@ use move_proc_macros::growing_stack; use crate::{ diag, + diagnostics::{Diagnostic, DiagnosticReporter, Diagnostics, warning_filters::WarningFilters}, expansion::ast::{self as E, ModuleIdent}, ice, naming::ast as N, @@ -20,30 +21,50 @@ use crate::{ //************************************************************************************************** struct Context<'env, 'info> { - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, + reporter: DiagnosticReporter<'env>, info: &'info NamingProgramInfo, current_module: ModuleIdent, } impl<'env, 'info> Context<'env, 'info> { fn new( - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, info: &'info NamingProgramInfo, current_module: ModuleIdent, ) -> Self { + let reporter = env.diagnostic_reporter_at_top_level(); Self { env, + reporter, info, current_module, } } + + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } } //************************************************************************************************** // Entry //************************************************************************************************** -pub fn program(env: &mut CompilationEnv, info: &mut NamingProgramInfo, inner: &mut N::Program_) { +pub fn program(env: &CompilationEnv, info: &mut NamingProgramInfo, inner: &mut N::Program_) { let N::Program_ { modules } = inner; for (mident, mdef) in modules.key_cloned_iter_mut() { module(env, info, mident, mdef); @@ -64,15 +85,13 @@ pub fn program(env: &mut CompilationEnv, info: &mut NamingProgramInfo, inner: &m } fn module( - env: &mut CompilationEnv, + env: &CompilationEnv, info: &mut NamingProgramInfo, mident: ModuleIdent, mdef: &mut N::ModuleDefinition, ) { let context = &mut Context::new(env, info, mident); - context - .env - .add_warning_filter_scope(mdef.warning_filter.clone()); + context.push_warning_filter_scope(mdef.warning_filter); use_funs(context, &mut mdef.use_funs); for (_, _, c) in &mut mdef.constants { constant(context, c); @@ -80,25 +99,21 @@ fn module( for (_, _, f) in &mut mdef.functions { function(context, f); } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } fn constant(context: &mut Context, c: &mut N::Constant) { - context - .env - .add_warning_filter_scope(c.warning_filter.clone()); + context.push_warning_filter_scope(c.warning_filter); exp(context, &mut c.value); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } fn function(context: &mut Context, function: &mut N::Function) { - context - .env - .add_warning_filter_scope(function.warning_filter.clone()); + context.push_warning_filter_scope(function.warning_filter); if let N::FunctionBody_::Defined(seq) = &mut function.body.value { sequence(context, seq) } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } //************************************************************************************************** @@ -133,7 +148,7 @@ fn use_funs(context: &mut Context, uf: &mut N::UseFuns) { if let Some(public_loc) = nuf.is_public { let defining_module = match &tn.value { N::TypeName_::Multiple(_) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( tn.loc, "ICE tuple type should not be reachable from use fun" ))); @@ -160,7 +175,7 @@ fn use_funs(context: &mut Context, uf: &mut N::UseFuns) { format!("The type '{tn}' is defined here"), )) } - context.env.add_diag(diag); + context.add_diag(diag); nuf.is_public = None; } } @@ -178,7 +193,7 @@ fn use_funs(context: &mut Context, uf: &mut N::UseFuns) { } None => format!("But '{m}::{f}' takes no arguments"), }; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidUseFun, (loc, msg), (first_ty_loc, first_tn_msg), @@ -205,9 +220,7 @@ fn use_funs(context: &mut Context, uf: &mut N::UseFuns) { let Some((target_f, tn)) = is_valid_method(context, &target_m, target_f) else { if matches!(ekind, E::ImplicitUseFunKind::UseAlias { used: false }) { let msg = format!("Unused 'use' of alias '{}'. Consider removing it", method); - context - .env - .add_diag(diag!(UnusedItem::Alias, (method.loc, msg),)) + context.add_diag(diag!(UnusedItem::Alias, (method.loc, msg),)) } continue; }; @@ -245,7 +258,7 @@ fn use_funs(context: &mut Context, uf: &mut N::UseFuns) { argument is a type defined in the same module" } }; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (nuf_loc, msg), (prev, "Previously declared here"), @@ -342,10 +355,12 @@ fn exp(context: &mut Context, sp!(_, e_): &mut N::Exp) { use_fun_color: _, body: e, }) => exp(context, e), - N::Exp_::IfElse(econd, et, ef) => { + N::Exp_::IfElse(econd, et, ef_opt) => { exp(context, econd); exp(context, et); - exp(context, ef); + if let Some(ef) = ef_opt { + exp(context, ef); + } } N::Exp_::Match(esubject, arms) => { exp(context, esubject); @@ -392,7 +407,7 @@ fn exp(context: &mut Context, sp!(_, e_): &mut N::Exp) { exp(context, e) } } - N::Exp_::MethodCall(ed, _, _, _, sp!(_, es)) => { + N::Exp_::MethodCall(ed, _, _, _, _, sp!(_, es)) => { exp_dotted(context, ed); for e in es { exp(context, e) @@ -407,7 +422,7 @@ fn exp(context: &mut Context, sp!(_, e_): &mut N::Exp) { fn exp_dotted(context: &mut Context, sp!(_, ed_): &mut N::ExpDotted) { match ed_ { N::ExpDotted_::Exp(e) => exp(context, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { + N::ExpDotted_::Dot(ed, _, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { exp_dotted(context, ed) } N::ExpDotted_::Index(ed, sp!(_, es)) => { diff --git a/external-crates/move/crates/move-compiler/src/naming/syntax_methods.rs b/external-crates/move/crates/move-compiler/src/naming/syntax_methods.rs index 6ed8a60a2fb..a40403ef549 100644 --- a/external-crates/move/crates/move-compiler/src/naming/syntax_methods.rs +++ b/external-crates/move/crates/move-compiler/src/naming/syntax_methods.rs @@ -17,7 +17,7 @@ use crate::{ translate::Context, }, parser::ast::FunctionName, - shared::{known_attributes::SyntaxAttribute, CompilationEnv}, + shared::known_attributes::SyntaxAttribute, }; #[derive(PartialEq, Eq, Ord, PartialOrd)] @@ -44,9 +44,9 @@ pub(super) fn resolve_syntax_attributes( let attr = function.attributes.get_(&SyntaxAttribute::Syntax.into())?; let attr_loc = attr.loc; - let syntax_method_prekinds = resolve_syntax_method_prekind(context.env, attr)?; + let syntax_method_prekinds = resolve_syntax_method_prekind(context, attr)?; - if !context.env.check_feature( + if !context.check_feature( context.current_package, FeatureGate::SyntaxMethods, attr_loc, @@ -70,7 +70,7 @@ pub(super) fn resolve_syntax_attributes( if let Some(macro_loc) = function.macro_ { let msg = "Syntax attributes may not appear on macro definitions"; let fn_msg = "This function is a macro"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (attr_loc, msg), (macro_loc, fn_msg) @@ -127,7 +127,7 @@ fn prev_syntax_defn_error( kind_string, type_name ); let prev_msg = "This syntax method was previously defined here."; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidAttribute, (sloc, msg), (prev.loc, prev_msg) @@ -150,7 +150,7 @@ fn attr_param_from_str(loc: Loc, name_str: &str) -> Option /// Resolve the mapping for a function + syntax attribute into a /// SyntaxMethodKind. fn resolve_syntax_method_prekind( - env: &mut CompilationEnv, + context: &Context, sp!(loc, attr_): &Attribute, ) -> Option> { match attr_ { @@ -160,7 +160,7 @@ fn resolve_syntax_method_prekind( SyntaxAttribute::SYNTAX, SyntaxAttribute::INDEX ); - env.add_diag(diag!(Declarations::InvalidAttribute, (*loc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (*loc, msg))); None } Attribute_::Parameterized(_, inner) => { @@ -172,7 +172,7 @@ fn resolve_syntax_method_prekind( if let Some(prev_kind) = kinds.replace(kind) { let msg = "Repeated syntax method identifier".to_string(); let prev = "Initially defined here".to_string(); - env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidAttribute, (loc, msg), (prev_kind.loc, prev) @@ -180,7 +180,7 @@ fn resolve_syntax_method_prekind( } } else { let msg = format!("Invalid syntax method identifier '{}'", name); - env.add_diag(diag!(Declarations::InvalidAttribute, (loc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (loc, msg))); } } Attribute_::Assigned(n, _) => { @@ -189,7 +189,7 @@ fn resolve_syntax_method_prekind( SyntaxAttribute::SYNTAX, n ); - env.add_diag(diag!(Declarations::InvalidAttribute, (loc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (loc, msg))); } Attribute_::Parameterized(n, _) => { let msg = format!( @@ -197,7 +197,7 @@ fn resolve_syntax_method_prekind( SyntaxAttribute::SYNTAX, n ); - env.add_diag(diag!(Declarations::InvalidAttribute, (loc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (loc, msg))); } } } @@ -224,7 +224,7 @@ fn determine_valid_kind( SyntaxAttribute::INDEX, ); let ty_msg = "This type is not a reference"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidAttribute, (sloc, msg), (subject_type.loc, ty_msg) @@ -234,9 +234,7 @@ fn determine_valid_kind( } SyntaxMethodPrekind_::For => { let msg = "'for' syntax attributes are not currently supported"; - context - .env - .add_diag(diag!(Declarations::InvalidAttribute, (sloc, msg),)); + context.add_diag(diag!(Declarations::InvalidAttribute, (sloc, msg),)); return None; } // SyntaxMethodPrekind_::For => match mut_opt { @@ -246,9 +244,7 @@ fn determine_valid_kind( // }, SyntaxMethodPrekind_::Assign => { let msg = "'assign' syntax attributes are not currently supported"; - context - .env - .add_diag(diag!(Declarations::InvalidAttribute, (sloc, msg),)); + context.add_diag(diag!(Declarations::InvalidAttribute, (sloc, msg),)); return None; } // SyntaxMethodPrekind_::Assign => match mut_opt { // Some((loc, true)) => SK::Assign, @@ -258,7 +254,7 @@ fn determine_valid_kind( // SyntaxAttribute::INDEX, // ); // let ty_msg = "This type is not a reference"; - // context.env.add_diag(diag!( + // context.add_diag(diag!( // Declarations::InvalidAttribute, // (sloc, msg), // (*ty_loc, msg) @@ -290,7 +286,7 @@ fn determine_subject_type_name( let msg = "Invalid type for syntax method definition"; let mut diag = diag!(Declarations::InvalidSyntaxMethod, (*loc, msg)); diag.add_note("Syntax methods may only be defined for single base types"); - context.env.add_diag(diag); + context.add_diag(diag); return None; } N::TypeName_::Builtin(sp!(_, bt_)) => context.env.primitive_definer(*bt_), @@ -299,7 +295,7 @@ fn determine_subject_type_name( if Some(cur_module) == defining_module { Some(type_name.clone()) } else { - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*ann_loc, INVALID_MODULE_MSG), (*loc, INVALID_MODULE_TYPE_MSG) @@ -317,7 +313,7 @@ fn determine_subject_type_name( "But '{}' was declared as a type parameter here", param.user_specified_name ); - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*ann_loc, msg), (*loc, tmsg) @@ -332,7 +328,7 @@ fn determine_subject_type_name( let msg = "Invalid type for syntax method definition"; let mut diag = diag!(Declarations::InvalidSyntaxMethod, (*loc, msg)); diag.add_note("Syntax methods may only be defined for single base types"); - context.env.add_diag(diag); + context.add_diag(diag); None } } @@ -351,7 +347,7 @@ fn valid_return_type( } else if valid_mut_ref(ty) { let msg = format!("Invalid {} annotation", SyntaxAttribute::SYNTAX); let tmsg = "This syntax method must return an immutable reference to match its subject type"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*loc, msg), (ty.loc, tmsg), @@ -364,7 +360,7 @@ fn valid_return_type( SyntaxAttribute::SYNTAX ); let tmsg = "This is not an immutable reference"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*loc, msg), (ty.loc, tmsg), @@ -381,7 +377,7 @@ fn valid_return_type( let msg = format!("Invalid {} annotation", SyntaxAttribute::SYNTAX); let tmsg = "This syntax method must return a mutable reference to match its subject type"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*loc, msg), (ty.loc, tmsg), @@ -394,7 +390,7 @@ fn valid_return_type( SyntaxAttribute::SYNTAX ); let tmsg = "This is not a mutable reference"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*loc, msg), (ty.loc, tmsg), @@ -428,7 +424,7 @@ fn valid_index_return_type( SyntaxAttribute::SYNTAX ); let tmsg = "Unit type occurs as the return type for this function"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*kind_loc, msg), (*tloc, tmsg) @@ -441,7 +437,7 @@ fn valid_index_return_type( SyntaxAttribute::SYNTAX ); let tmsg = "But a function type appears in this return type"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidSyntaxMethod, (*kind_loc, msg), (*tloc, tmsg) @@ -468,9 +464,7 @@ fn get_first_type( "Invalid attribute. {} is only valid if the function takes at least one parameter", SyntaxAttribute::SYNTAX ); - context - .env - .add_diag(diag!(Declarations::InvalidAttribute, (*attr_loc, msg))); + context.add_diag(diag!(Declarations::InvalidAttribute, (*attr_loc, msg))); None } } diff --git a/external-crates/move/crates/move-compiler/src/naming/translate.rs b/external-crates/move/crates/move-compiler/src/naming/translate.rs index 1e954a2ab4a..01fcd67b857 100644 --- a/external-crates/move/crates/move-compiler/src/naming/translate.rs +++ b/external-crates/move/crates/move-compiler/src/naming/translate.rs @@ -13,16 +13,16 @@ use move_proc_macros::growing_stack; use move_symbol_pool::Symbol; use crate::{ - debug_display, diag, + FullyCompiledProgram, debug_display, diag, diagnostics::{ - self, + self, Diagnostic, DiagnosticReporter, Diagnostics, codes::{self, *}, - Diagnostic, + warning_filters::WarningFilters, }, editions::FeatureGate, expansion::{ ast::{self as E, AbilitySet, Ellipsis, ModuleIdent, Mutability, Visibility}, - translate::is_valid_datatype_or_constant_name as is_constant_name, + name_validation::is_valid_datatype_or_constant_name as is_constant_name, }, ice, naming::{ @@ -31,12 +31,14 @@ use crate::{ syntax_methods::resolve_syntax_attributes, }, parser::ast::{ - self as P, ConstantName, DatatypeName, Field, FunctionName, VariantName, MACRO_MODIFIER, + self as P, ConstantName, DatatypeName, Field, FunctionName, MACRO_MODIFIER, VariantName, }, shared::{ - ide::EllipsisMatchEntries, program_info::NamingProgramInfo, unique_map::UniqueMap, *, + ide::{EllipsisMatchEntries, IDEAnnotation, IDEInfo}, + program_info::NamingProgramInfo, + unique_map::UniqueMap, + *, }, - FullyCompiledProgram, }; //************************************************************************************************** @@ -531,14 +533,20 @@ pub fn build_member_map( // Context //************************************************************************************************** -pub(super) struct Context<'env> { - pub env: &'env mut CompilationEnv, - current_module: Option, +pub(super) struct OuterContext { /// Nothing should ever use this directly, and should instead go through /// `resolve_module_access` because it preserves source location /// information. module_members: ModuleMembers, + unscoped_types: BTreeMap, +} + +pub(super) struct Context<'outer, 'env> { + pub env: &'env CompilationEnv, + outer: &'outer OuterContext, + reporter: DiagnosticReporter<'env>, unscoped_types: Vec>, + current_module: ModuleIdent, local_scopes: Vec>, local_count: BTreeMap, used_locals: BTreeSet, @@ -561,7 +569,7 @@ macro_rules! resolve_from_module_access { Some(other) => { let diag = make_invalid_module_member_kind_error($context, &$expected_kind, $loc, &other); - $context.env.add_diag(diag); + $context.add_diag(diag); None } None => { @@ -572,28 +580,43 @@ macro_rules! resolve_from_module_access { }}; } -impl<'env> Context<'env> { +impl OuterContext { fn new( - compilation_env: &'env mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: &E::Program, ) -> Self { use ResolvedType as RT; let module_members = build_member_map(compilation_env, pre_compiled_lib, prog); - let unscoped_types = vec![ - N::BuiltinTypeName_::all_names() - .iter() - .map(|s| { - let b_ = RT::BuiltinType(N::BuiltinTypeName_::resolve(s.as_str()).unwrap()); - (*s, b_) - }) - .collect(), - ]; + let unscoped_types = N::BuiltinTypeName_::all_names() + .iter() + .map(|s| { + let b_ = RT::BuiltinType(N::BuiltinTypeName_::resolve(s.as_str()).unwrap()); + (*s, b_) + }) + .collect(); Self { - env: compilation_env, - current_module: None, module_members, unscoped_types, + } + } +} + +impl<'outer, 'env> Context<'outer, 'env> { + fn new( + env: &'env CompilationEnv, + outer: &'outer OuterContext, + current_package: Option, + current_module: ModuleIdent, + ) -> Self { + let unscoped_types = vec![outer.unscoped_types.clone()]; + let reporter = env.diagnostic_reporter_at_top_level(); + Self { + env, + outer, + reporter, + unscoped_types, + current_module, local_scopes: vec![], local_count: BTreeMap::new(), nominal_blocks: vec![], @@ -601,15 +624,46 @@ impl<'env> Context<'env> { used_locals: BTreeSet::new(), used_fun_tparams: BTreeSet::new(), translating_fun: false, - current_package: None, + current_package, } } + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + #[allow(unused)] + pub fn extend_ide_info(&self, info: IDEInfo) { + self.reporter.extend_ide_info(info); + } + + pub fn add_ide_annotation(&self, loc: Loc, info: IDEAnnotation) { + self.reporter.add_ide_annotation(loc, info); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + + pub fn check_feature(&self, package: Option, feature: FeatureGate, loc: Loc) -> bool { + self.env + .check_feature(&self.reporter, package, feature, loc) + } + fn valid_module(&mut self, m: &ModuleIdent) -> bool { - let resolved = self.module_members.contains_key(m); + let resolved = self.outer.module_members.contains_key(m); if !resolved { let diag = make_unbound_module_error(self, m.loc, m); - self.env.add_diag(diag); + self.add_diag(diag); } resolved } @@ -624,14 +678,14 @@ impl<'env> Context<'env> { m: &ModuleIdent, n: &Name, ) -> Option { - let Some(members) = self.module_members.get(m) else { - self.env.add_diag(make_unbound_module_error(self, m.loc, m)); + let Some(members) = self.outer.module_members.get(m) else { + self.add_diag(make_unbound_module_error(self, m.loc, m)); return None; }; let result = members.get(&n.value); if result.is_none() { let diag = make_unbound_module_member_error(self, kind, loc, *m, n.value); - self.env.add_diag(diag); + self.add_diag(diag); } result.map(|inner| { let mut result = inner.clone(); @@ -702,13 +756,12 @@ impl<'env> Context<'env> { match ma_ { EN::Name(sp!(_, n)) if n == symbol!("_") => { let current_package = self.current_package; - self.env - .check_feature(current_package, FeatureGate::TypeHoles, nloc); + self.check_feature(current_package, FeatureGate::TypeHoles, nloc); ResolvedType::Hole } EN::Name(n) => match self.resolve_unscoped_type(nloc, n) { ResolvedType::ModuleType(mut module_type) => { - module_type.set_name_info(self.current_module.unwrap(), nloc); + module_type.set_name_info(self.current_module, nloc); ResolvedType::ModuleType(module_type) } ty @ (ResolvedType::BuiltinType(_) @@ -743,7 +796,7 @@ impl<'env> Context<'env> { { None => { let diag = make_unbound_local_name_error(self, &ErrorKind::Type, loc, n); - self.env.add_diag(diag); + self.add_diag(diag); ResolvedType::Unbound } Some(rn) => rn.clone(), @@ -751,8 +804,8 @@ impl<'env> Context<'env> { } fn resolve_call_subject(&mut self, sp!(mloc, ma_): E::ModuleAccess) -> ResolvedCallSubject { - use ErrorKind as EK; use E::ModuleAccess_ as EA; + use ErrorKind as EK; use N::BuiltinFunction_ as B; match ma_ { EA::ModuleAccess(m, n) => { @@ -766,7 +819,7 @@ impl<'env> Context<'env> { Some(c @ ResolvedModuleMember::Constant(_)) => { let diag = make_invalid_module_member_kind_error(self, &EK::Function, mloc, &c); - self.env.add_diag(diag); + self.add_diag(diag); ResolvedCallSubject::Unbound } Some(e @ ResolvedModuleMember::Datatype(ResolvedDatatype::Enum(_))) => { @@ -776,7 +829,7 @@ impl<'env> Context<'env> { "Enums cannot be instantiated directly. \ Instead, you must instantiate a variant.", ); - self.env.add_diag(diag); + self.add_diag(diag); ResolvedCallSubject::Unbound } None => { @@ -794,7 +847,7 @@ impl<'env> Context<'env> { _ => { let diag = make_unbound_local_name_error(self, &EK::Function, n.loc, n.value); - self.env.add_diag(diag); + self.add_diag(diag); return ResolvedCallSubject::Unbound; } }; @@ -833,7 +886,7 @@ impl<'env> Context<'env> { ResolvedCallSubject::Constructor(Box::new(variant)) } Some(ResolvedConstructor::Struct(struct_)) => { - self.env.add_diag(diag!( + self.add_diag(diag!( NameResolution::NamePositionMismatch, (sloc, "Invalid constructor. Expected an enum".to_string()), ( @@ -880,7 +933,7 @@ impl<'env> Context<'env> { _ => { let diag = make_unbound_local_name_error(self, &ErrorKind::Function, n.loc, n); - self.env.add_diag(diag); + self.add_diag(diag); return ResolvedUseFunFunction::Unbound; } }; @@ -890,11 +943,11 @@ impl<'env> Context<'env> { } EA::Name(n) => { let diag = make_unbound_local_name_error(self, &ErrorKind::Function, n.loc, n); - self.env.add_diag(diag); + self.add_diag(diag); ResolvedUseFunFunction::Unbound } EA::Variant(_, _) => { - self.env.add_diag(ice!(( + self.add_diag(ice!(( mloc, "Tried to resolve variant '{}' as a function in current scope" ),)); @@ -942,7 +995,7 @@ impl<'env> Context<'env> { } else { format!("Invalid {}. Expected a struct name", verb) }; - self.env.add_diag(diag!( + self.add_diag(diag!( NameResolution::NamePositionMismatch, (ma.loc, msg), (rtloc, rtmsg) @@ -962,7 +1015,7 @@ impl<'env> Context<'env> { "Invalid {verb}. Variant '{variant_name}' is not part of this enum", ); let decl_msg = format!("Enum '{}' is defined here", enum_type.name); - self.env.add_diag(diag!( + self.add_diag(diag!( NameResolution::UnboundVariant, (ma.loc, primary_msg), (enum_type.decl_loc, decl_msg), @@ -978,7 +1031,7 @@ impl<'env> Context<'env> { Some(ResolvedConstructor::Variant(Box::new(variant_info))) } (EN::Name(_) | EN::ModuleAccess(_, _), D::Enum(enum_type)) => { - self.env.add_diag(diag!( + self.add_diag(diag!( NameResolution::NamePositionMismatch, (ma.loc, format!("Invalid {verb}. Expected a struct")), ( @@ -989,7 +1042,7 @@ impl<'env> Context<'env> { None } (EN::Variant(sp!(sloc, _), _), D::Struct(stype)) => { - self.env.add_diag(diag!( + self.add_diag(diag!( NameResolution::NamePositionMismatch, (*sloc, format!("Invalid {verb}. Expected an enum")), (stype.decl_loc, format!("But '{}' is an struct", stype.name)) @@ -1021,7 +1074,7 @@ impl<'env> Context<'env> { } } E::ModuleAccess_::Name(name) => { - self.env.add_diag(diag!( + self.add_diag(diag!( NameResolution::UnboundUnscopedName, (mloc, format!("Unbound constant '{}'", name)), )); @@ -1083,7 +1136,7 @@ impl<'env> Context<'env> { } ResolvedModuleMember::Constant(_) => (), }; - self.env.add_diag(diag); + self.add_diag(diag); ResolvedTerm::Unbound } }, @@ -1094,8 +1147,7 @@ impl<'env> Context<'env> { } } ma_ @ E::ModuleAccess_::Variant(_, _) => { - self.env - .check_feature(self.current_package, FeatureGate::Enums, mloc); + self.check_feature(self.current_package, FeatureGate::Enums, mloc); let Some(result) = self.resolve_datatype_constructor(sp(mloc, ma_), "construction") else { assert!(self.env.has_errors()); @@ -1116,13 +1168,12 @@ impl<'env> Context<'env> { fn resolve_pattern_term(&mut self, sp!(mloc, ma_): E::ModuleAccess) -> ResolvedPatternTerm { match ma_ { E::ModuleAccess_::Name(name) if !is_constant_name(&name.value) => { - self.env - .add_diag(ice!((mloc, "This should have become a binder"))); + self.add_diag(ice!((mloc, "This should have become a binder"))); ResolvedPatternTerm::Unbound } // If we have a name, try to resolve it in our module. E::ModuleAccess_::Name(name) => { - let mut mident = self.current_module.unwrap(); + let mut mident = self.current_module; mident.loc = mloc; let maccess = sp(mloc, E::ModuleAccess_::ModuleAccess(mident, name)); self.resolve_pattern_term(maccess) @@ -1135,7 +1186,8 @@ impl<'env> Context<'env> { } _ => match self.resolve_datatype_constructor(sp(mloc, ma_), "pattern") { Some(ctor) => ResolvedPatternTerm::Constructor(Box::new(ctor)), - None => todo!(), + None => ResolvedPatternTerm::Unbound, /* TODO: some cases here may be + * handled */ }, } } @@ -1199,7 +1251,7 @@ impl<'env> Context<'env> { match id_opt { None => { let msg = variable_msg(name); - self.env.add_diag(diag!(code, (loc, msg))); + self.add_diag(diag!(code, (loc, msg))); None } Some(id) => { @@ -1221,7 +1273,7 @@ impl<'env> Context<'env> { match id_opt { None => { let msg = format!("Failed to resolve pattern binder {}", name); - self.env.add_diag(ice!((loc, msg))); + self.add_diag(ice!((loc, msg))); None } Some(id) => { @@ -1261,8 +1313,7 @@ impl<'env> Context<'env> { "Invalid usage of '{usage}'. \ '{usage}' can only be used inside a loop body or lambda", ); - self.env - .add_diag(diag!(TypeSafety::InvalidLoopControl, (loc, msg))); + self.add_diag(diag!(TypeSafety::InvalidLoopControl, (loc, msg))); return None; }; if *name_type == NominalBlockType::LambdaLoopCapture { @@ -1300,7 +1351,7 @@ impl<'env> Context<'env> { }; diag.add_secondary_label((loop_label.label.loc, msg)); } - self.env.add_diag(diag); + self.add_diag(diag); return None; } Some(*label) @@ -1356,13 +1407,12 @@ impl<'env> Context<'env> { not 'continue'." } }); - self.env.add_diag(diag); + self.add_diag(diag); None } } else { let msg = format!("Invalid {usage}. Unbound label '{name}"); - self.env - .add_diag(diag!(NameResolution::UnboundLabel, (loc, msg))); + self.add_diag(diag!(NameResolution::UnboundLabel, (loc, msg))); None } } @@ -1414,15 +1464,11 @@ impl std::fmt::Display for LoopType { impl std::fmt::Display for NominalBlockType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - match self { - NominalBlockType::Loop(_) => "loop", - NominalBlockType::Block => "named", - NominalBlockType::LambdaReturn | NominalBlockType::LambdaLoopCapture => "lambda", - } - ) + write!(f, "{}", match self { + NominalBlockType::Loop(_) => "loop", + NominalBlockType::Block => "named", + NominalBlockType::LambdaReturn | NominalBlockType::LambdaLoopCapture => "lambda", + }) } } @@ -1568,7 +1614,7 @@ fn make_unbound_module_member_error( name: impl std::fmt::Display, ) -> Diagnostic { let expected = expected.as_ref().unwrap_or(&ErrorKind::ModuleMember); - let same_module = context.current_module == Some(mident); + let same_module = context.current_module == mident; let (prefix, postfix) = if same_module { ("", " in current scope".to_string()) } else { @@ -1591,7 +1637,7 @@ fn make_invalid_module_member_kind_error( actual: &ResolvedModuleMember, ) -> Diagnostic { let mident = actual.mident(); - let same_module = context.current_module == Some(mident); + let same_module = context.current_module == mident; let (prefix, postfix) = if same_module { ("", " in current scope".to_string()) } else { @@ -1623,32 +1669,40 @@ fn arity_string(arity: usize) -> &'static str { //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: E::Program, ) -> N::Program { - let mut context = Context::new(compilation_env, pre_compiled_lib.clone(), &prog); - let E::Program { modules: emodules } = prog; - let modules = modules(&mut context, emodules); + let outer_context = OuterContext::new(compilation_env, pre_compiled_lib.clone(), &prog); + let E::Program { + warning_filters_table, + modules: emodules, + } = prog; + let modules = modules(compilation_env, &outer_context, emodules); let mut inner = N::Program_ { modules }; let mut info = NamingProgramInfo::new(pre_compiled_lib, &inner); super::resolve_use_funs::program(compilation_env, &mut info, &mut inner); - N::Program { info, inner } + N::Program { + info, + warning_filters_table, + inner, + } } fn modules( - context: &mut Context, + env: &CompilationEnv, + outer: &OuterContext, modules: UniqueMap, ) -> UniqueMap { - modules.map(|ident, mdef| module(context, ident, mdef)) + modules.map(|ident, mdef| module(env, outer, ident, mdef)) } fn module( - context: &mut Context, + env: &CompilationEnv, + outer: &OuterContext, ident: ModuleIdent, mdef: E::ModuleDefinition, ) -> N::ModuleDefinition { - context.current_module = Some(ident); let E::ModuleDefinition { loc, warning_filter, @@ -1662,8 +1716,8 @@ fn module( functions: efunctions, constants: econstants, } = mdef; - context.current_package = package_name; - context.env.add_warning_filter_scope(warning_filter.clone()); + let context = &mut Context::new(env, outer, package_name, ident); + context.push_warning_filter_scope(warning_filter); let mut use_funs = use_funs(context, euse_funs); let mut syntax_methods = N::SyntaxMethods::new(); let friends = efriends.filter_map(|mident, f| friend(context, mident, f)); @@ -1720,8 +1774,7 @@ fn module( if has_macro { mark_all_use_funs_as_used(&mut use_funs); } - context.env.pop_warning_filter_scope(); - context.current_package = None; + context.pop_warning_filter_scope(); N::ModuleDefinition { loc, warning_filter, @@ -1757,7 +1810,7 @@ fn use_funs(context: &mut Context, eufs: E::UseFuns) -> N::UseFuns { let nuf_loc = nuf.loc; if let Err((_, prev)) = methods.add(method, nuf) { let msg = format!("Duplicate 'use fun' for '{}.{}'", tn, method); - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (nuf_loc, msg), (prev, "Previously declared here"), @@ -1795,9 +1848,7 @@ fn explicit_use_fun( } ResolvedUseFunFunction::Builtin(_) => { let msg = "Invalid 'use fun'. Cannot use a builtin function as a method"; - context - .env - .add_diag(diag!(Declarations::InvalidUseFun, (loc, msg))); + context.add_diag(diag!(Declarations::InvalidUseFun, (loc, msg))); None } ResolvedUseFunFunction::Unbound => { @@ -1830,7 +1881,7 @@ fn explicit_use_fun( ResolvedType::Hole => { let msg = "Invalid 'use fun'. Cannot associate a method with an inferred type"; let tmsg = "The '_' type is a placeholder for type inference"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidUseFun, (loc, msg), (ty_loc, tmsg) @@ -1843,7 +1894,7 @@ fn explicit_use_fun( "But '{}' was declared as a type parameter here", tp.user_specified_name ); - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidUseFun, (loc, msg,), (tloc, tmsg) @@ -1876,7 +1927,7 @@ fn check_use_fun_scope( return true; }; let current_module = context.current_module; - let Err(def_loc_opt) = use_fun_module_defines(context, use_fun_loc, current_module, rtype) + let Err(def_loc_opt) = use_fun_module_defines(context, use_fun_loc, ¤t_module, rtype) else { return true; }; @@ -1895,22 +1946,19 @@ fn check_use_fun_scope( if let Some(def_loc) = def_loc_opt { diag.add_secondary_label((def_loc, "Type defined in another module here")); } - context.env.add_diag(diag); + context.add_diag(diag); false } fn use_fun_module_defines( context: &mut Context, use_fun_loc: &Loc, - specified: Option, + specified: &ModuleIdent, rtype: &ResolvedType, ) -> Result<(), Option> { match rtype { ResolvedType::ModuleType(mtype) => { - if specified - .as_ref() - .is_some_and(|mident| mident == &mtype.mident()) - { + if specified == &mtype.mident() { Ok(()) } else { Err(Some(mtype.decl_loc())) @@ -1918,11 +1966,10 @@ fn use_fun_module_defines( } ResolvedType::BuiltinType(b_) => { let definer_opt = context.env.primitive_definer(*b_); - match (definer_opt, &specified) { - (None, _) => Err(None), - (Some(d), None) => Err(Some(d.loc)), - (Some(d), Some(s)) => { - if d == s { + match definer_opt { + None => Err(None), + Some(d) => { + if d == specified { Ok(()) } else { Err(Some(d.loc)) @@ -1931,7 +1978,7 @@ fn use_fun_module_defines( } } ResolvedType::TParam(_, _) | ResolvedType::Hole | ResolvedType::Unbound => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( *use_fun_loc, "Tried to validate use fun for invalid type" ))); @@ -1964,21 +2011,21 @@ fn mark_all_use_funs_as_used(use_funs: &mut N::UseFuns) { //************************************************************************************************** fn friend(context: &mut Context, mident: ModuleIdent, friend: E::Friend) -> Option { - let current_mident = context.current_module.as_ref().unwrap(); + let current_mident = &context.current_module; if mident.value.address != current_mident.value.address { // NOTE: in alignment with the bytecode verifier, this constraint is a policy // decision rather than a technical requirement. The compiler, VM, and // bytecode verifier DO NOT rely on the assumption that friend modules // must reside within the same account address. let msg = "Cannot declare modules out of the current address as a friend"; - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidFriendDeclaration, (friend.loc, "Invalid friend declaration"), (mident.loc, msg), )); None } else if &mident == current_mident { - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidFriendDeclaration, (friend.loc, "Invalid friend declaration"), (mident.loc, "Cannot declare the module itself as a friend"), @@ -2007,7 +2054,7 @@ fn function( warning_filter, index, attributes, - loc: _, + loc, visibility, macro_, entry, @@ -2020,7 +2067,7 @@ fn function( assert!(context.nominal_block_id == 0); assert!(context.used_fun_tparams.is_empty()); assert!(context.used_locals.is_empty()); - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); context.local_scopes = vec![BTreeMap::new()]; context.local_count = BTreeMap::new(); context.translating_fun = true; @@ -2037,9 +2084,7 @@ fn function( if !context.used_fun_tparams.contains(&tparam.id) { let sp!(loc, n) = tparam.user_specified_name; let msg = format!("Unused type parameter '{}'.", n); - context - .env - .add_diag(diag!(UnusedItem::FunTypeParam, (loc, msg))) + context.add_diag(diag!(UnusedItem::FunTypeParam, (loc, msg))) } } } @@ -2048,6 +2093,7 @@ fn function( warning_filter, index, attributes, + loc, visibility, macro_, entry, @@ -2055,7 +2101,7 @@ fn function( body, }; resolve_syntax_attributes(context, syntax_methods, &module, &name, &f); - fake_natives::function(context.env, module, name, &f); + fake_natives::function(&context.reporter, module, name, &f); let used_locals = std::mem::take(&mut context.used_locals); remove_unused_bindings_function(context, &used_locals, &mut f); context.local_count = BTreeMap::new(); @@ -2063,7 +2109,7 @@ fn function( context.nominal_block_id = 0; context.used_fun_tparams = BTreeSet::new(); context.used_locals = BTreeSet::new(); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); context.translating_fun = false; f } @@ -2094,14 +2140,14 @@ fn function_signature( ); let mut diag = diag!(NameResolution::InvalidMacroParameter, (mutloc, msg)); diag.add_note(ASSIGN_SYNTAX_IDENTIFIER_NOTE); - context.env.add_diag(diag); + context.add_diag(diag); mut_ = Mutability::Imm; } } if let Err((param, prev_loc)) = declared.add(param, ()) { if !is_underscore { let msg = format!("Duplicate parameter with name '{}'", param); - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (param.loc(), msg), (prev_loc, "Previously declared here"), @@ -2150,10 +2196,10 @@ fn struct_def( type_parameters, fields, } = sdef; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let type_parameters = datatype_type_parameters(context, type_parameters); let fields = struct_fields(context, fields); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); N::StructDefinition { warning_filter, index, @@ -2208,10 +2254,10 @@ fn enum_def( type_parameters, variants, } = edef; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); let type_parameters = datatype_type_parameters(context, type_parameters); let variants = enum_variants(context, variants); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); N::EnumDefinition { warning_filter, index, @@ -2280,7 +2326,7 @@ fn constant(context: &mut Context, _name: ConstantName, econstant: E::Constant) assert!(context.local_scopes.is_empty()); assert!(context.local_count.is_empty()); assert!(context.used_locals.is_empty()); - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); context.local_scopes = vec![BTreeMap::new()]; let signature = type_(context, TypeAnnotation::ConstantSignature, esignature); let value = *exp(context, Box::new(evalue)); @@ -2288,7 +2334,7 @@ fn constant(context: &mut Context, _name: ConstantName, econstant: E::Constant) context.local_count = BTreeMap::new(); context.used_locals = BTreeSet::new(); context.nominal_block_id = 0; - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); N::Constant { warning_filter, index, @@ -2346,7 +2392,7 @@ fn type_parameter( context.bind_type(name.value, ResolvedType::TParam(loc, tp.clone())); if let Err((name, old_loc)) = unique_tparams.add(name, ()) { let msg = format!("Duplicate type parameter declared with name '{}'", name); - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::DuplicateItem, (loc, msg), (old_loc, "Type parameter previously defined here"), @@ -2368,9 +2414,9 @@ fn types(context: &mut Context, case: TypeAnnotation, tys: Vec) -> Vec< } fn type_(context: &mut Context, case: TypeAnnotation, sp!(loc, ety_): E::Type) -> N::Type { - use ResolvedType as RT; use E::Type_ as ET; - use N::{TypeName_ as NN, Type_ as NT}; + use N::{Type_ as NT, TypeName_ as NN}; + use ResolvedType as RT; let ty_ = match ety_ { ET::Unit => NT::Unit, ET::Multiple(tys) => NT::multiple_( @@ -2413,7 +2459,7 @@ fn type_(context: &mut Context, case: TypeAnnotation, sp!(loc, ety_): E::Type) - if let TypeAnnotation::FunctionSignature = case { diag.add_note("Only 'macro' functions can use '_' in their signatures"); } - context.env.add_diag(diag); + context.add_diag(diag); NT::UnresolvedError } else { // replaced with a type variable during type instantiation @@ -2429,7 +2475,7 @@ fn type_(context: &mut Context, case: TypeAnnotation, sp!(loc, ety_): E::Type) - } RT::TParam(_, tp) => { if !tys.is_empty() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::NamePositionMismatch, (loc, "Generic type parameters cannot take type arguments"), )); @@ -2504,7 +2550,7 @@ fn check_type_instantiation_arity String>( arity, args_len ); - context.env.add_diag(diag!(diag_code, (loc, msg))); + context.add_diag(diag!(diag_code, (loc, msg))); } while ty_args.len() > arity { @@ -2637,7 +2683,11 @@ fn exp(context: &mut Context, e: Box) -> Box { } } - EE::IfElse(eb, et, ef) => NE::IfElse(exp(context, eb), exp(context, et), exp(context, ef)), + EE::IfElse(eb, et, ef_opt) => NE::IfElse( + exp(context, eb), + exp(context, et), + ef_opt.map(|ef| exp(context, ef)), + ), // EE::Match(esubject, sp!(_aloc, arms)) if arms.is_empty() => { // exp(context, esubject); // for error effect // let msg = "Invalid 'match' form. 'match' must have at least one arm"; @@ -2741,7 +2791,14 @@ fn exp(context: &mut Context, e: Box) -> Box { NE::Mutate(nel, ner) } - EE::Abort(es) => NE::Abort(exp(context, es)), + EE::Abort(Some(es)) => NE::Abort(exp(context, es)), + EE::Abort(None) => { + context.check_feature(context.current_package, FeatureGate::CleverAssertions, eloc); + let abort_const_expr = sp(eloc, N::Exp_::ErrorConstant { + line_number_loc: eloc, + }); + NE::Abort(Box::new(abort_const_expr)) + } EE::Return(Some(block_name), es) => { let out_rhs = exp(context, es); context @@ -2863,7 +2920,7 @@ fn exp(context: &mut Context, e: Box) -> Box { EE::Call(ma, is_macro, tys_opt, rhs) => { resolve_call(context, eloc, ma, is_macro, tys_opt, rhs) } - EE::MethodCall(edot, n, is_macro, tys_opt, rhs) => match dotted(context, *edot) { + EE::MethodCall(edot, dot_loc, n, is_macro, tys_opt, rhs) => match dotted(context, *edot) { None => { assert!(context.env.has_errors()); NE::UnresolvedError @@ -2872,13 +2929,9 @@ fn exp(context: &mut Context, e: Box) -> Box { let ty_args = tys_opt.map(|tys| types(context, TypeAnnotation::Expression, tys)); let nes = call_args(context, rhs); if is_macro.is_some() { - context.env.check_feature( - context.current_package, - FeatureGate::MacroFuns, - eloc, - ); + context.check_feature(context.current_package, FeatureGate::MacroFuns, eloc); } - NE::MethodCall(d, n, is_macro, ty_args, nes) + NE::MethodCall(d, dot_loc, n, is_macro, ty_args, nes) } }, EE::Vector(vec_loc, tys_opt, rhs) => { @@ -2909,7 +2962,7 @@ fn exp(context: &mut Context, e: Box) -> Box { "ICE compiler should not have parsed this form as a specification" )); diag.add_note(format!("Compiler parsed: {}", debug_display!(e))); - context.env.add_diag(diag); + context.add_diag(diag); NE::UnresolvedError } }; @@ -2938,13 +2991,15 @@ fn dotted(context: &mut Context, edot: E::ExpDotted) -> Option { modified by path operations.\n\ Path operations include 'move', 'copy', '&', '&mut', and field references", ); - context.env.add_diag(diag); + context.add_diag(diag); N::ExpDotted_::Exp(Box::new(sp(ne.loc, N::Exp_::UnresolvedError))) } _ => N::ExpDotted_::Exp(ne), } } - E::ExpDotted_::Dot(d, f) => N::ExpDotted_::Dot(Box::new(dotted(context, *d)?), Field(f)), + E::ExpDotted_::Dot(d, loc, f) => { + N::ExpDotted_::Dot(Box::new(dotted(context, *d)?), loc, Field(f)) + } E::ExpDotted_::DotUnresolved(loc, d) => { N::ExpDotted_::DotAutocomplete(loc, Box::new(dotted(context, *d)?)) } @@ -3025,7 +3080,7 @@ fn check_constructor_form( } else { diag.add_note(named_note!()); } - context.env.add_diag(diag); + context.add_diag(diag); } CF::Parens if stype.field_info.is_positional() => (), CF::Parens => { @@ -3035,7 +3090,7 @@ fn check_constructor_form( (loc, &msg), (stype.decl_loc, defn_loc_error(&name)), ); - context.env.add_diag(diag); + context.add_diag(diag); } CF::Braces if stype.field_info.is_positional() => { let msg = invalid_inst_msg!("struct", POSNL_UPCASE, POSNL); @@ -3044,7 +3099,7 @@ fn check_constructor_form( (loc, &msg), (stype.decl_loc, defn_loc_error(&name)), ); - context.env.add_diag(diag); + context.add_diag(diag); } CF::Braces => (), }, @@ -3070,7 +3125,7 @@ fn check_constructor_form( } else { diag.add_note(named_note!()); } - context.env.add_diag(diag); + context.add_diag(diag); } CF::Parens if vfields.is_empty() => { let msg = invalid_inst_msg!("variant", EMPTY_UPCASE, EMPTY); @@ -3080,7 +3135,7 @@ fn check_constructor_form( (vloc, defn_loc_error(&name)), ); diag.add_note(format!("Remove '()' arguments from this {position}")); - context.env.add_diag(diag); + context.add_diag(diag); } CF::Parens if vfields.is_positional() => (), CF::Parens => { @@ -3091,7 +3146,7 @@ fn check_constructor_form( (vloc, defn_loc_error(&name)), ); diag.add_note(named_note!()); - context.env.add_diag(diag); + context.add_diag(diag); } CF::Braces if vfields.is_empty() => { let msg = invalid_inst_msg!("variant", EMPTY_UPCASE, EMPTY); @@ -3101,7 +3156,7 @@ fn check_constructor_form( (vloc, defn_loc_error(&name)), ); diag.add_note(format!("Remove '{{ }}' arguments from this {position}")); - context.env.add_diag(diag); + context.add_diag(diag); } CF::Braces if vfields.is_positional() => { let msg = invalid_inst_msg!("variant", POSNL_UPCASE, POSNL); @@ -3111,7 +3166,7 @@ fn check_constructor_form( (vloc, defn_loc_error(&name)), ); diag.add_note(posnl_note!()); - context.env.add_diag(diag); + context.add_diag(diag); } CF::Braces => (), } @@ -3234,7 +3289,7 @@ fn unique_pattern_binders( diag.add_secondary_label((*loc, "and repeated here")); } diag.add_note("A pattern variable must be unique, and must appear once in each or-pattern alternative."); - context.env.add_diag(diag); + context.add_diag(diag); } enum OrPosn { @@ -3252,7 +3307,7 @@ fn unique_pattern_binders( let mut diag = diag!(NameResolution::InvalidPattern, (var.loc(), primary_msg)); diag.add_secondary_label((other_loc, secondary_msg)); diag.add_note("Both sides of an or-pattern must bind the same variables."); - context.env.add_diag(diag); + context.add_diag(diag); } fn report_mismatched_or_mutability( @@ -3273,7 +3328,7 @@ fn unique_pattern_binders( diag.add_note( "Both sides of an or-pattern must bind the same variables with the same mutability.", ); - context.env.add_diag(diag); + context.add_diag(diag); } type Bindings = BTreeMap>; @@ -3435,7 +3490,7 @@ fn expand_positional_ellipsis( let entries = (0..=missing).map(|_| "_".into()).collect::>(); let info = EllipsisMatchEntries::Positional(entries); let info = ide::IDEAnnotation::EllipsisMatchEntries(Box::new(info)); - context.env.add_ide_annotation(eloc, info); + context.add_ide_annotation(eloc, info); } result } @@ -3472,7 +3527,7 @@ fn expand_named_ellipsis( let entries = fields.iter().map(|field| field.value()).collect::>(); let info = EllipsisMatchEntries::Named(entries); let info = ide::IDEAnnotation::EllipsisMatchEntries(Box::new(info)); - context.env.add_ide_annotation(ellipsis_loc, info); + context.add_ide_annotation(ellipsis_loc, info); } let start_idx = args.len(); @@ -3574,7 +3629,7 @@ fn match_pattern(context: &mut Context, in_pat: Box) -> Box { if etys_opt.is_some() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::TooManyTypeArguments, (ploc, "Constants in patterns do not take type arguments") )); @@ -3660,8 +3715,8 @@ fn lvalue( case: LValueCase, sp!(loc, l_): E::LValue, ) -> Option { - use LValueCase as C; use E::LValue_ as EL; + use LValueCase as C; use N::LValue_ as NL; let nl_ = match l_ { EL::Var(mut_, sp!(_, E::ModuleAccess_::Name(n)), None) => { @@ -3687,9 +3742,7 @@ fn lvalue( ((var.loc, msg), (prev_loc, "Previously assigned here")) } }; - context - .env - .add_diag(diag!(Declarations::DuplicateItem, primary, secondary)); + context.add_diag(diag!(Declarations::DuplicateItem, primary, secondary)); } if v.is_syntax_identifier() { debug_assert!( @@ -3703,7 +3756,7 @@ fn lvalue( ); let mut diag = diag!(TypeSafety::CannotExpandMacro, (loc, msg)); diag.add_note(ASSIGN_SYNTAX_IDENTIFIER_NOTE); - context.env.add_diag(diag); + context.add_diag(diag); return None; } let nv = match case { @@ -3749,7 +3802,7 @@ fn lvalue( stype } Some(ResolvedConstructor::Variant(variant)) => { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::NamePositionMismatch, (tn.loc, format!("Invalid {}. Expected a struct", msg)), ( @@ -3819,7 +3872,7 @@ fn lvalue( "ICE compiler should not have parsed this form as a specification" )); diag.add_note(format!("Compiler parsed: {}", debug_display!(e))); - context.env.add_diag(diag); + context.add_diag(diag); NL::Ignore } }; @@ -3832,9 +3885,7 @@ fn check_mut_underscore(context: &mut Context, mut_: Option) { return; }; let msg = "Invalid 'mut' declaration. 'mut' is applied to variables and cannot be applied to the '_' pattern"; - context - .env - .add_diag(diag!(NameResolution::InvalidMut, (loc, msg))); + context.add_diag(diag!(NameResolution::InvalidMut, (loc, msg))); } fn bind_list(context: &mut Context, ls: E::LValueList) -> Option { @@ -3908,9 +3959,7 @@ fn resolve_call( } = *mf; // TODO This is a weird place to check this feature gate. if let Some(mloc) = is_macro { - context - .env - .check_feature(context.current_package, FeatureGate::MacroFuns, mloc); + context.check_feature(context.current_package, FeatureGate::MacroFuns, mloc); } // TODO. We could check arities here, but we don't; type dones that, instead. let tyargs_opt = types_opt(context, TypeAnnotation::Expression, in_tyargs_opt); @@ -3931,9 +3980,7 @@ fn resolve_call( match tyargs_opt.as_deref() { Some([ty]) => B::Freeze(Some(ty.clone())), Some(_tys) => { - context - .env - .add_diag(ice!((call_loc, "Builtin tyarg arity failure"))); + context.add_diag(ice!((call_loc, "Builtin tyarg arity failure"))); return N::Exp_::UnresolvedError; } None => B::Freeze(None), @@ -3954,7 +4001,7 @@ fn resolve_call( let mut diag = diag!(Uncategorized::DeprecatedWillBeRemoved, (call_loc, dep_msg),); diag.add_note(help_msg); - context.env.add_diag(diag); + context.add_diag(diag); } exp_types_opt_with_arity_check( context, @@ -3967,17 +4014,14 @@ fn resolve_call( // If no abort code is given for the assert, we add in the abort code as the // bitset-line-number if `CleverAssertions` is set. if args.value.len() == 1 && is_macro.is_some() { - context.env.check_feature( + context.check_feature( context.current_package, FeatureGate::CleverAssertions, subject_loc, ); - args.value.push(sp( - call_loc, - N::Exp_::ErrorConstant { - line_number_loc: subject_loc, - }, - )); + args.value.push(sp(call_loc, N::Exp_::ErrorConstant { + line_number_loc: subject_loc, + })); } B::Assert(is_macro) } @@ -3985,7 +4029,7 @@ fn resolve_call( N::Exp_::Builtin(sp(subject_loc, builtin_), args) } ResolvedCallSubject::Constructor(_) => { - context.env.check_feature( + context.check_feature( context.current_package, FeatureGate::PositionalFields, call_loc, @@ -4030,14 +4074,12 @@ fn resolve_call( } } ResolvedCallSubject::Var(var) => { - context - .env - .check_feature(context.current_package, FeatureGate::Lambda, call_loc); + context.check_feature(context.current_package, FeatureGate::Lambda, call_loc); check_is_not_macro(context, is_macro, &var.value.name); let tyargs_opt = types_opt(context, TypeAnnotation::Expression, in_tyargs_opt); if tyargs_opt.is_some() { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::TooManyTypeArguments, ( subject_loc, @@ -4058,7 +4100,7 @@ fn resolve_call( ); let mut diag = diag!(TypeSafety::InvalidCallTarget, (var.loc, msg)); diag.add_note(note); - context.env.add_diag(diag); + context.add_diag(diag); N::Exp_::UnresolvedError } else if var.value.id != 0 { let msg = format!( @@ -4066,9 +4108,7 @@ fn resolve_call( Only lambda-typed syntax parameters may be invoked", var.value.name ); - context - .env - .add_diag(diag!(TypeSafety::InvalidCallTarget, (var.loc, msg))); + context.add_diag(diag!(TypeSafety::InvalidCallTarget, (var.loc, msg))); N::Exp_::UnresolvedError } else { N::Exp_::VarCall(sp(subject_loc, var.value), args) @@ -4089,9 +4129,7 @@ fn check_is_not_macro(context: &mut Context, is_macro: Option, name: &str) macro", name ); - context - .env - .add_diag(diag!(TypeSafety::InvalidCallTarget, (mloc, msg))); + context.add_diag(diag!(TypeSafety::InvalidCallTarget, (mloc, msg))); } } @@ -4101,9 +4139,7 @@ fn report_invalid_macro(context: &mut Context, is_macro: Option, kind: &str "Unexpected macro invocation. {} cannot be invoked as macros", kind ); - context - .env - .add_diag(diag!(NameResolution::PositionalCallMismatch, (mloc, msg))); + context.add_diag(diag!(NameResolution::PositionalCallMismatch, (mloc, msg))); } } @@ -4128,7 +4164,7 @@ fn exp_types_opt_with_arity_check( }; let msg = fmsg(); let targs_msg = format!("Expected {} type argument(s) but got {}", arity, args_len); - context.env.add_diag(diag!( + context.add_diag(diag!( diag_code, (msg_loc, msg), (tyarg_error_loc, targs_msg) @@ -4251,10 +4287,12 @@ fn remove_unused_bindings_exp( | N::Exp_::Loop(_, e) | N::Exp_::Give(_, _, e) | N::Exp_::Annotate(e, _) => remove_unused_bindings_exp(context, used, e), - N::Exp_::IfElse(econd, et, ef) => { + N::Exp_::IfElse(econd, et, ef_opt) => { remove_unused_bindings_exp(context, used, econd); remove_unused_bindings_exp(context, used, et); - remove_unused_bindings_exp(context, used, ef); + if let Some(ef) = ef_opt { + remove_unused_bindings_exp(context, used, ef); + } } N::Exp_::Match(esubject, arms) => { remove_unused_bindings_exp(context, used, esubject); @@ -4315,7 +4353,7 @@ fn remove_unused_bindings_exp( remove_unused_bindings_exp(context, used, e) } } - N::Exp_::MethodCall(ed, _, _, _, sp!(_, es)) => { + N::Exp_::MethodCall(ed, _, _, _, _, sp!(_, es)) => { remove_unused_bindings_exp_dotted(context, used, ed); for e in es { remove_unused_bindings_exp(context, used, e) @@ -4333,7 +4371,7 @@ fn remove_unused_bindings_exp_dotted( ) { match ed_ { N::ExpDotted_::Exp(e) => remove_unused_bindings_exp(context, used, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { + N::ExpDotted_::Dot(ed, _, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { remove_unused_bindings_exp_dotted(context, used, ed) } N::ExpDotted_::Index(ed, sp!(_, es)) => { @@ -4400,7 +4438,5 @@ fn report_unused_local(context: &mut Context, sp!(loc, unused_): &N::Var) { let msg = format!( "Unused {kind} '{name}'. Consider removing or prefixing with an underscore: '_{name}'", ); - context - .env - .add_diag(diag!(UnusedItem::Variable, (*loc, msg))); + context.add_diag(diag!(UnusedItem::Variable, (*loc, msg))); } diff --git a/external-crates/move/crates/move-compiler/src/parser/ast.rs b/external-crates/move/crates/move-compiler/src/parser/ast.rs index 4451fcfc6ba..0000ff94e31 100644 --- a/external-crates/move/crates/move-compiler/src/parser/ast.rs +++ b/external-crates/move/crates/move-compiler/src/parser/ast.rs @@ -614,7 +614,7 @@ pub enum Exp_ { Assign(Box, Box), // abort e - Abort(Box), + Abort(Option>), // return e Return(Option, Option>), // break @@ -633,11 +633,12 @@ pub enum Exp_ { // &mut e Borrow(bool, Box), - // e.f - Dot(Box, Name), + // e.f (along with the location of the dot) + Dot(Box, /* dot location */ Loc, Name), // e.f(earg,*) DotCall( Box, + Loc, // location of the dot Name, // is_macro Option, @@ -1358,7 +1359,7 @@ fn ast_debug_package_definition( def, } = pkg; match package { - Some(n) => w.writeln(&format!("package: {}", n)), + Some(n) => w.writeln(format!("package: {}", n)), None => w.writeln("no package"), } named_address_maps.get(*named_address_map).ast_debug(w); @@ -1368,7 +1369,7 @@ fn ast_debug_package_definition( impl AstDebug for NamedAddressMap { fn ast_debug(&self, w: &mut AstWriter) { for (sym, addr) in self { - w.write(&format!("{} => {}", sym, addr)); + w.write(format!("{} => {}", sym, addr)); w.new_line() } } @@ -1392,7 +1393,7 @@ impl AstDebug for AddressDefinition { modules, } = self; attributes.ast_debug(w); - w.write(&format!("address {}", addr)); + w.write(format!("address {}", addr)); w.writeln(" {{"); for m in modules { m.ast_debug(w) @@ -1413,14 +1414,14 @@ impl AstDebug for AttributeValue_ { impl AstDebug for Attribute_ { fn ast_debug(&self, w: &mut AstWriter) { match self { - Attribute_::Name(n) => w.write(&format!("{}", n)), + Attribute_::Name(n) => w.write(format!("{}", n)), Attribute_::Assigned(n, v) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write(" = "); v.ast_debug(w); } Attribute_::Parameterized(n, inners) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write("("); w.list(&inners.value, ", ", |w, inner| { inner.ast_debug(w); @@ -1465,12 +1466,12 @@ impl AstDebug for ModuleDefinition { } = self; attributes.ast_debug(w); match address { - None => w.write(&format!( + None => w.write(format!( "module {}{}", if *is_spec_module { "spec " } else { "" }, name )), - Some(addr) => w.write(&format!("module {}::{}", addr, name)), + Some(addr) => w.write(format!("module {}::{}", addr, name)), }; w.block(|w| { for mem in members { @@ -1510,12 +1511,12 @@ impl AstDebug for ModuleUse { fn ast_debug(&self, w: &mut AstWriter) { match self { ModuleUse::Module(alias) => { - alias.map(|alias| w.write(&format!("as {}", alias))); + alias.map(|alias| w.write(format!("as {}", alias))); } ModuleUse::Members(members) => w.block(|w| { w.comma(members, |w, (name, alias)| { - w.write(&format!("{}", name)); - alias.map(|alias| w.write(&format!("as {}", alias.value))); + w.write(format!("{}", name)); + alias.map(|alias| w.write(format!("as {}", alias.value))); }) }), ModuleUse::Partial { @@ -1534,14 +1535,14 @@ impl AstDebug for Use { w.write("use "); match self { Use::ModuleUse(mident, use_) => { - w.write(&format!("{}", mident)); + w.write(format!("{}", mident)); use_.ast_debug(w); } Use::NestedModuleUses(addr, entries) => { - w.write(&format!("{}::", addr)); + w.write(format!("{}::", addr)); w.block(|w| { w.comma(entries, |w, (name, use_)| { - w.write(&format!("{}::", name)); + w.write(format!("{}::", name)); use_.ast_debug(w); }) }) @@ -1581,7 +1582,7 @@ impl AstDebug for FriendDecl { friend, } = self; attributes.ast_debug(w); - w.write(&format!("friend {}", friend)); + w.write(format!("friend {}", friend)); } } @@ -1606,7 +1607,7 @@ impl AstDebug for EnumDefinition { w.write("]"); } - w.write(&format!(" enum {}", name)); + w.write(format!(" enum {}", name)); type_parameters.ast_debug(w); w.block(|w| { w.list(variants, ",", |w, variant| { @@ -1624,17 +1625,17 @@ impl AstDebug for VariantDefinition { name, fields, } = self; - w.write(&format!("{}", name)); + w.write(format!("{}", name)); match fields { VariantFields::Named(fields) => w.block(|w| { w.semicolon(fields, |w, (f, st)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); st.ast_debug(w); }); }), VariantFields::Positional(types) => w.block(|w| { w.semicolon(types.iter().enumerate(), |w, (i, st)| { - w.write(&format!("pos{}: ", i)); + w.write(format!("pos{}: ", i)); st.ast_debug(w); }); }), @@ -1664,18 +1665,18 @@ impl AstDebug for StructDefinition { w.write("native "); } - w.write(&format!("struct {}", name)); + w.write(format!("struct {}", name)); type_parameters.ast_debug(w); match fields { StructFields::Named(fields) => w.block(|w| { w.semicolon(fields, |w, (f, st)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); st.ast_debug(w); }); }), StructFields::Positional(types) => w.block(|w| { w.semicolon(types.iter().enumerate(), |w, (i, st)| { - w.write(&format!("pos{}: ", i)); + w.write(format!("pos{}: ", i)); st.ast_debug(w); }); }), @@ -1699,15 +1700,15 @@ impl AstDebug for Function { attributes.ast_debug(w); visibility.ast_debug(w); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if macro_.is_some() { - w.write(&format!("{} ", MACRO_MODIFIER)); + w.write(format!("{} ", MACRO_MODIFIER)); } if let FunctionBody_::Native = &body.value { - w.write(&format!("{} ", NATIVE_MODIFIER)); + w.write(format!("{} ", NATIVE_MODIFIER)); } - w.write(&format!("fun {}", name)); + w.write(format!("fun {}", name)); signature.ast_debug(w); match &body.value { FunctionBody_::Defined(body) => w.block(|w| body.ast_debug(w)), @@ -1718,7 +1719,7 @@ impl AstDebug for Function { impl AstDebug for Visibility { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{} ", self)) + w.write(format!("{} ", self)) } } @@ -1735,7 +1736,7 @@ impl AstDebug for FunctionSignature { if mut_.is_some() { w.write("mut "); } - w.write(&format!("{}: ", v)); + w.write(format!("{}: ", v)); st.ast_debug(w); }); w.write(")"); @@ -1754,7 +1755,7 @@ impl AstDebug for Constant { value, } = self; attributes.ast_debug(w); - w.write(&format!("const {}:", name)); + w.write(format!("const {}:", name)); signature.ast_debug(w); w.write(" = "); value.ast_debug(w); @@ -1817,7 +1818,7 @@ fn ability_constraints_ast_debug(w: &mut AstWriter, abilities: &[Ability]) { impl AstDebug for Ability_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)) + w.write(format!("{}", self)) } } @@ -2006,7 +2007,7 @@ impl AstDebug for Exp_ { ma.ast_debug(w); w.write("{"); w.comma(fields, |w, (f, e)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); e.ast_debug(w); }); w.write("}"); @@ -2089,8 +2090,11 @@ impl AstDebug for Exp_ { rhs.ast_debug(w); } E::Abort(e) => { - w.write("abort "); - e.ast_debug(w); + w.write("abort"); + if let Some(e) = e { + w.write(" "); + e.ast_debug(w); + } } E::Return(name, e) => { w.write("return"); @@ -2135,13 +2139,13 @@ impl AstDebug for Exp_ { } e.ast_debug(w); } - E::Dot(e, n) => { + E::Dot(e, _, n) => { e.ast_debug(w); - w.write(&format!(".{}", n)); + w.write(format!(".{}", n)); } - E::DotCall(e, n, is_macro, tyargs, sp!(_, rhs)) => { + E::DotCall(e, _, n, is_macro, tyargs, sp!(_, rhs)) => { e.ast_debug(w); - w.write(&format!(".{}", n)); + w.write(format!(".{}", n)); if is_macro.is_some() { w.write("!"); } @@ -2221,7 +2225,7 @@ impl AstDebug for Ellipsis<(Field, MatchPattern)> { w.write(".."); } Ellipsis::Binder((n, p)) => { - w.write(&format!("{}: ", n)); + w.write(format!("{}: ", n)); p.ast_debug(w); } } @@ -2268,13 +2272,13 @@ impl AstDebug for MatchPattern_ { impl AstDebug for BinOp_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)); + w.write(format!("{}", self)); } } impl AstDebug for UnaryOp_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)); + w.write(format!("{}", self)); } } @@ -2354,7 +2358,7 @@ impl AstDebug for Bind_ { if mut_.is_some() { w.write("mut "); } - w.write(&format!("{}", v)) + w.write(format!("{}", v)) } B::Unpack(ma, fields) => { ma.ast_debug(w); @@ -2385,7 +2389,7 @@ impl AstDebug for Ellipsis<(Field, Bind)> { w.write(".."); } Ellipsis::Binder((n, b)) => { - w.write(&format!("{}: ", n)); + w.write(format!("{}: ", n)); b.ast_debug(w); } } diff --git a/external-crates/move/crates/move-compiler/src/parser/lexer.rs b/external-crates/move/crates/move-compiler/src/parser/lexer.rs index e2a885de22f..69686f168f1 100644 --- a/external-crates/move/crates/move-compiler/src/parser/lexer.rs +++ b/external-crates/move/crates/move-compiler/src/parser/lexer.rs @@ -9,12 +9,11 @@ use move_command_line_common::{character_sets::DisplayChar, files::FileHash}; use move_ir_types::location::Loc; use crate::{ - diag, + FileCommentMap, MatchedFileCommentMap, diag, diagnostics::Diagnostic, - editions::{create_feature_error, Edition, FeatureGate}, + editions::{Edition, FeatureGate, create_feature_error}, parser::{syntax::make_loc, token_set::TokenSet}, shared::CompilationEnv, - FileCommentMap, MatchedFileCommentMap, }; // This should be replaced with std::mem::variant::count::() if it ever @@ -106,12 +105,12 @@ impl fmt::Display for Tok { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { use Tok::*; let s = match *self { - EOF => "[end-of-file]", - NumValue => "[Num]", - NumTypedValue => "[NumTyped]", - ByteStringValue => "[ByteString]", - Identifier => "[Identifier]", - SyntaxIdentifier => "[SyntaxIdentifier]", + EOF => "", + NumValue => "", + NumTypedValue => "", + ByteStringValue => "", + Identifier => "", + SyntaxIdentifier => "$", Exclaim => "!", ExclaimEqual => "!=", Percent => "%", @@ -175,12 +174,12 @@ impl fmt::Display for Tok { Friend => "friend", NumSign => "#", AtSign => "@", - RestrictedIdentifier => "r#[Identifier]", + RestrictedIdentifier => "r#", Mut => "mut", Enum => "enum", Type => "type", Match => "match", - BlockLabel => "'[Identifier]", + BlockLabel => "'", MinusGreater => "->", For => "for", }; @@ -198,6 +197,7 @@ pub struct Lexer<'input> { cur_start: usize, cur_end: usize, token: Tok, + preceded_by_eol: bool, // last token was preceded by end-of-line } impl<'input> Lexer<'input> { @@ -212,6 +212,7 @@ impl<'input> Lexer<'input> { cur_start: 0, cur_end: 0, token: Tok::EOF, + preceded_by_eol: false, } } @@ -263,6 +264,10 @@ impl<'input> Lexer<'input> { self.edition } + pub fn last_token_preceded_by_eol(&self) -> bool { + self.preceded_by_eol + } + /// Strips line and block comments from input source, and collects /// documentation comments, putting them into a map indexed by the span /// of the comment region. Comments in the original source will be @@ -277,7 +282,8 @@ impl<'input> Lexer<'input> { fn trim_whitespace_and_comments( &mut self, offset: usize, - ) -> Result<&'input str, Box> { + ) -> Result<(&'input str, bool), Box> { + let mut trimmed_preceding_eol; let mut text = &self.text[offset..]; // A helper function to compute the index of the start of the given substring. @@ -288,68 +294,12 @@ impl<'input> Lexer<'input> { // a multi-line or single-line comment. loop { // Trim the start whitespace characters. - text = trim_start_whitespace(text); + (text, trimmed_preceding_eol) = trim_start_whitespace(text); if text.starts_with("/*") { - // Strip multi-line comments like '/* ... */' or '/** ... */'. - // These can be nested, as in '/* /* ... */ */', so record the - // start locations of each nested comment as a stack. The - // boolean indicates whether it's a documentation comment. - let mut locs: Vec<(usize, bool)> = vec![]; - loop { - text = text.trim_start_matches(|c: char| c != '/' && c != '*'); - if text.is_empty() { - // We've reached the end of string while searching for a - // terminating '*/'. - let loc = *locs.last().unwrap(); - // Highlight the '/**' if it's a documentation comment, or the '/*' - // otherwise. - let location = - make_loc(self.file_hash, loc.0, loc.0 + if loc.1 { 3 } else { 2 }); - return Err(Box::new(diag!( - Syntax::InvalidDocComment, - (location, "Unclosed block comment"), - ))); - } else if text.starts_with("/*") { - // We've found a (perhaps nested) multi-line comment. - let start = get_offset(text); - text = &text[2..]; - - // Check if this is a documentation comment: '/**', but not '/***'. - // A documentation comment cannot be nested within another comment. - let is_doc = - text.starts_with('*') && !text.starts_with("**") && locs.is_empty(); - - locs.push((start, is_doc)); - } else if text.starts_with("*/") { - // We've found a multi-line comment terminator that ends - // our innermost nested comment. - let loc = locs.pop().unwrap(); - text = &text[2..]; - - // If this was a documentation comment, record it in our map. - if loc.1 { - let end = get_offset(text); - self.doc_comments.insert( - (loc.0 as u32, end as u32), - self.text[(loc.0 + 3)..(end - 2)].to_string(), - ); - } - - // If this terminated our last comment, exit the loop. - if locs.is_empty() { - break; - } - } else { - // This is a solitary '/' or '*' that isn't part of any comment delimiter. - // Skip over it. - let c = text.chars().next().unwrap(); - text = &text[c.len_utf8()..]; - } - } - // Continue the loop immediately after the multi-line comment. // There may be whitespace or another comment following this one. + text = self.parse_block_comment(get_offset(text))?; continue; } else if text.starts_with("//") { let start = get_offset(text); @@ -360,7 +310,7 @@ impl<'input> Lexer<'input> { if is_doc { let end = get_offset(text); let mut comment = &self.text[(start + 3)..end]; - comment = comment.trim_end_matches(|c: char| c == '\r'); + comment = comment.trim_end_matches('\r'); self.doc_comments .insert((start as u32, end as u32), comment.to_string()); @@ -372,6 +322,81 @@ impl<'input> Lexer<'input> { } break; } + Ok((text, trimmed_preceding_eol)) + } + + fn parse_block_comment(&mut self, offset: usize) -> Result<&'input str, Box> { + struct CommentEntry { + start: usize, + is_doc_comment: bool, + } + + let text = &self.text[offset..]; + + // A helper function to compute the index of the start of the given substring. + let len = text.len(); + let get_offset = |substring: &str| offset + len - substring.len(); + + let block_doc_comment_start: &str = "/**"; + + assert!(text.starts_with("/*")); + let initial_entry = CommentEntry { + start: get_offset(text), + is_doc_comment: text.starts_with(block_doc_comment_start), + }; + let mut comment_queue: Vec = vec![initial_entry]; + + // This is a _rough_ apporximation which disregards doc comments in order to + // handle the case where we have `/**/` or similar. + let mut text = &text[2..]; + + while let Some(comment) = comment_queue.pop() { + text = text.trim_start_matches(|c: char| c != '/' && c != '*'); + if text.is_empty() { + // We've reached the end of string while searching for a terminating '*/'. + // Highlight the '/**' if it's a documentation comment, or the '/*' otherwise. + let location = make_loc( + self.file_hash, + comment.start, + comment.start + if comment.is_doc_comment { 3 } else { 2 }, + ); + return Err(Box::new(diag!( + Syntax::InvalidDocComment, + (location, "Unclosed block comment"), + ))); + }; + + match &text[..2] { + "*/" => { + let end = get_offset(text); + // If the comment was not empty -- fuzzy ot handle `/**/`, which triggers the + // doc comment check but is not actually a doc comment. + if comment.start + 3 < end && comment.is_doc_comment { + self.doc_comments.insert( + (comment.start as u32, end as u32), + self.text[(comment.start + 3)..end].to_string(), + ); + } + text = &text[2..]; + } + "/*" => { + comment_queue.push(comment); + let new_comment = CommentEntry { + start: get_offset(text), + is_doc_comment: text.starts_with(block_doc_comment_start), + }; + comment_queue.push(new_comment); + text = &text[2..]; + } + _ => { + // This is a solitary '/' or '*' that isn't part of any comment delimiter. + // Skip over it. + comment_queue.push(comment); + let c = text.chars().next().unwrap(); + text = &text[c.len_utf8()..]; + } + } + } Ok(text) } @@ -395,7 +420,7 @@ impl<'input> Lexer<'input> { // Look ahead to the next token after the current one and return it, and its // starting offset, without advancing the state of the lexer. pub fn lookahead(&mut self) -> Result> { - let text = self.trim_whitespace_and_comments(self.cur_end)?; + let (text, _) = self.trim_whitespace_and_comments(self.cur_end)?; let next_start = self.text.len() - text.len(); let (result, _) = find_token( // panic_mode @@ -412,7 +437,7 @@ impl<'input> Lexer<'input> { // Look ahead to the next two tokens after the current one and return them // without advancing the state of the lexer. pub fn lookahead2(&mut self) -> Result<(Tok, Tok), Box> { - let text = self.trim_whitespace_and_comments(self.cur_end)?; + let (text, _) = self.trim_whitespace_and_comments(self.cur_end)?; let offset = self.text.len() - text.len(); let (result, length) = find_token( // panic_mode @@ -423,7 +448,7 @@ impl<'input> Lexer<'input> { offset, ); let first = result.map_err(|diag_opt| diag_opt.unwrap())?; - let text2 = self.trim_whitespace_and_comments(offset + length)?; + let (text2, _) = self.trim_whitespace_and_comments(offset + length)?; let offset2 = self.text.len() - text2.len(); let (result2, _) = find_token( // panic_mode @@ -494,10 +519,7 @@ impl<'input> Lexer<'input> { // At the end of parsing, checks whether there are any unmatched documentation // comments, producing errors if so. Otherwise returns a map from file // position to associated documentation. - pub fn check_and_get_doc_comments( - &mut self, - env: &mut CompilationEnv, - ) -> MatchedFileCommentMap { + pub fn check_and_get_doc_comments(&mut self, env: &CompilationEnv) -> MatchedFileCommentMap { let msg = "Documentation comment cannot be matched to a language item"; let diags = self .doc_comments @@ -507,7 +529,7 @@ impl<'input> Lexer<'input> { diag!(Syntax::InvalidDocComment, (loc, msg)) }) .collect(); - env.add_diags(diags); + env.diagnostic_reporter_at_top_level().add_diags(diags); std::mem::take(&mut self.matched_doc_comments) } @@ -526,7 +548,7 @@ impl<'input> Lexer<'input> { let token = loop { let mut cur_end = self.cur_end; // loop until the next text snippet which may contain a valid token is found) - let text = loop { + let (text, trimmed_preceding_eol) = loop { match self.trim_whitespace_and_comments(cur_end) { Ok(t) => break t, Err(diag) => { @@ -540,6 +562,7 @@ impl<'input> Lexer<'input> { } }; }; + self.preceded_by_eol = trimmed_preceding_eol; let new_start = self.text.len() - text.len(); // panic_mode determines if a diag should be actually recorded in find_token (so // that only first one is recorded) @@ -958,19 +981,27 @@ fn get_name_token(edition: Edition, name: &str) -> Tok { // Trim the start whitespace characters, include: space, tab, lf(\n) and // crlf(\r\n). -fn trim_start_whitespace(text: &str) -> &str { +fn trim_start_whitespace(text: &str) -> (&str, bool) { + let mut trimmed_eof = false; let mut pos = 0; let mut iter = text.chars(); while let Some(chr) = iter.next() { match chr { - ' ' | '\t' | '\n' => pos += 1, - '\r' if matches!(iter.next(), Some('\n')) => pos += 2, + '\n' => { + pos += 1; + trimmed_eof = true; + } + ' ' | '\t' => pos += 1, + '\r' if matches!(iter.next(), Some('\n')) => { + pos += 2; + trimmed_eof = true; + } _ => break, }; } - &text[pos..] + (&text[pos..], trimmed_eof) } #[cfg(test)] @@ -979,45 +1010,45 @@ mod tests { #[test] fn test_trim_start_whitespace() { - assert_eq!(trim_start_whitespace("\r"), "\r"); - assert_eq!(trim_start_whitespace("\rxxx"), "\rxxx"); - assert_eq!(trim_start_whitespace("\t\rxxx"), "\rxxx"); - assert_eq!(trim_start_whitespace("\r\n\rxxx"), "\rxxx"); - - assert_eq!(trim_start_whitespace("\n"), ""); - assert_eq!(trim_start_whitespace("\r\n"), ""); - assert_eq!(trim_start_whitespace("\t"), ""); - assert_eq!(trim_start_whitespace(" "), ""); - - assert_eq!(trim_start_whitespace("\nxxx"), "xxx"); - assert_eq!(trim_start_whitespace("\r\nxxx"), "xxx"); - assert_eq!(trim_start_whitespace("\txxx"), "xxx"); - assert_eq!(trim_start_whitespace(" xxx"), "xxx"); - - assert_eq!(trim_start_whitespace(" \r\n"), ""); - assert_eq!(trim_start_whitespace("\t\r\n"), ""); - assert_eq!(trim_start_whitespace("\n\r\n"), ""); - assert_eq!(trim_start_whitespace("\r\n "), ""); - assert_eq!(trim_start_whitespace("\r\n\t"), ""); - assert_eq!(trim_start_whitespace("\r\n\n"), ""); - - assert_eq!(trim_start_whitespace(" \r\nxxx"), "xxx"); - assert_eq!(trim_start_whitespace("\t\r\nxxx"), "xxx"); - assert_eq!(trim_start_whitespace("\n\r\nxxx"), "xxx"); - assert_eq!(trim_start_whitespace("\r\n xxx"), "xxx"); - assert_eq!(trim_start_whitespace("\r\n\txxx"), "xxx"); - assert_eq!(trim_start_whitespace("\r\n\nxxx"), "xxx"); - - assert_eq!(trim_start_whitespace(" \r\n\r\n"), ""); - assert_eq!(trim_start_whitespace("\r\n \t\n"), ""); - - assert_eq!(trim_start_whitespace(" \r\n\r\nxxx"), "xxx"); - assert_eq!(trim_start_whitespace("\r\n \t\nxxx"), "xxx"); - - assert_eq!(trim_start_whitespace(" \r\n\r\nxxx\n"), "xxx\n"); - assert_eq!(trim_start_whitespace("\r\n \t\nxxx\r\n"), "xxx\r\n"); - assert_eq!(trim_start_whitespace("\r\n\u{A0}\n"), "\u{A0}\n"); - assert_eq!(trim_start_whitespace("\r\n\u{A0}\n"), "\u{A0}\n"); - assert_eq!(trim_start_whitespace("\t \u{0085}\n"), "\u{0085}\n") + assert_eq!(trim_start_whitespace("\r").0, "\r"); + assert_eq!(trim_start_whitespace("\rxxx").0, "\rxxx"); + assert_eq!(trim_start_whitespace("\t\rxxx").0, "\rxxx"); + assert_eq!(trim_start_whitespace("\r\n\rxxx").0, "\rxxx"); + + assert_eq!(trim_start_whitespace("\n").0, ""); + assert_eq!(trim_start_whitespace("\r\n").0, ""); + assert_eq!(trim_start_whitespace("\t").0, ""); + assert_eq!(trim_start_whitespace(" ").0, ""); + + assert_eq!(trim_start_whitespace("\nxxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\r\nxxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\txxx").0, "xxx"); + assert_eq!(trim_start_whitespace(" xxx").0, "xxx"); + + assert_eq!(trim_start_whitespace(" \r\n").0, ""); + assert_eq!(trim_start_whitespace("\t\r\n").0, ""); + assert_eq!(trim_start_whitespace("\n\r\n").0, ""); + assert_eq!(trim_start_whitespace("\r\n ").0, ""); + assert_eq!(trim_start_whitespace("\r\n\t").0, ""); + assert_eq!(trim_start_whitespace("\r\n\n").0, ""); + + assert_eq!(trim_start_whitespace(" \r\nxxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\t\r\nxxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\n\r\nxxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\r\n xxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\r\n\txxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\r\n\nxxx").0, "xxx"); + + assert_eq!(trim_start_whitespace(" \r\n\r\n").0, ""); + assert_eq!(trim_start_whitespace("\r\n \t\n").0, ""); + + assert_eq!(trim_start_whitespace(" \r\n\r\nxxx").0, "xxx"); + assert_eq!(trim_start_whitespace("\r\n \t\nxxx").0, "xxx"); + + assert_eq!(trim_start_whitespace(" \r\n\r\nxxx\n").0, "xxx\n"); + assert_eq!(trim_start_whitespace("\r\n \t\nxxx\r\n").0, "xxx\r\n"); + assert_eq!(trim_start_whitespace("\r\n\u{A0}\n").0, "\u{A0}\n"); + assert_eq!(trim_start_whitespace("\r\n\u{A0}\n").0, "\u{A0}\n"); + assert_eq!(trim_start_whitespace("\t \u{0085}\n").0, "\u{0085}\n") } } diff --git a/external-crates/move/crates/move-compiler/src/parser/mod.rs b/external-crates/move/crates/move-compiler/src/parser/mod.rs index 909812f5a76..0d89792279b 100644 --- a/external-crates/move/crates/move-compiler/src/parser/mod.rs +++ b/external-crates/move/crates/move-compiler/src/parser/mod.rs @@ -12,21 +12,42 @@ pub(crate) mod syntax; mod token_set; pub(crate) mod verification_attribute_filter; -use crate::{ - parser::{self, ast::PackageDefinition, syntax::parse_file_string}, - shared::{files::MappedFiles, CompilationEnv, IndexedVfsPackagePath, NamedAddressMaps}, -}; +use std::{collections::BTreeSet, sync::Arc}; + use anyhow::anyhow; use comments::*; use move_command_line_common::files::FileHash; use move_symbol_pool::Symbol; -use std::{collections::BTreeSet, sync::Arc}; +use rayon::iter::*; use vfs::VfsPath; +use crate::{ + parser::{self, ast::PackageDefinition, syntax::parse_file_string}, + shared::{ + CompilationEnv, IndexedVfsPackagePath, NamedAddressMapIndex, NamedAddressMaps, + files::MappedFiles, + }, +}; + +struct ParsedFile { + fname: Symbol, + defs: Vec, + comments: MatchedFileCommentMap, + hash: FileHash, + text: Arc, +} + +struct ParsedPackageFile { + is_dep: bool, + package: Option, + named_address_map: NamedAddressMapIndex, + file: ParsedFile, +} + /// Parses program's targets and dependencies, both of which are read from /// different virtual file systems (vfs and deps_out_vfs, respectively). pub(crate) fn parse_program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, named_address_maps: NamedAddressMaps, mut targets: Vec, mut deps: Vec, @@ -41,35 +62,51 @@ pub(crate) fn parse_program( let mut source_comments = CommentMap::new(); let mut lib_definitions = Vec::new(); - for IndexedVfsPackagePath { - package, - path, - named_address_map, - } in targets - { - let (defs, comments, file_hash) = parse_file(&path, compilation_env, &mut files, package)?; - source_definitions.extend(defs.into_iter().map(|def| PackageDefinition { + let parsed = targets + .into_par_iter() + .map(|p| (false, p)) + .chain(deps.into_par_iter().map(|p| (true, p))) + .map(|(is_dep, package_path)| { + let IndexedVfsPackagePath { + package, + path, + named_address_map, + } = package_path; + let file = parse_file(&path, compilation_env, package)?; + Ok(ParsedPackageFile { + is_dep, + package, + named_address_map, + file, + }) + }) + .collect::>>()?; + for parsed_package_file in parsed { + let ParsedPackageFile { + is_dep, package, named_address_map, - def, - })); - source_comments.insert(file_hash, comments); - } - - for IndexedVfsPackagePath { - package, - path, - named_address_map, - } in deps - { - let (defs, dep_comment_map, fhash) = - parse_file(&path, compilation_env, &mut files, package)?; - lib_definitions.extend(defs.into_iter().map(|def| PackageDefinition { + file, + } = parsed_package_file; + let ParsedFile { + fname, + defs, + comments, + hash, + text, + } = file; + files.add(hash, fname, text); + source_comments.insert(hash, comments); + let defs = defs.into_iter().map(|def| PackageDefinition { package, named_address_map, def, - })); - source_comments.insert(fhash, dep_comment_map); + }); + if is_dep { + lib_definitions.extend(defs); + } else { + source_definitions.extend(defs) + } } let pprog = parser::ast::Program { @@ -114,32 +151,38 @@ fn ensure_targets_deps_dont_intersect( fn parse_file( path: &VfsPath, - compilation_env: &mut CompilationEnv, - files: &mut MappedFiles, + compilation_env: &CompilationEnv, package: Option, -) -> anyhow::Result<( - Vec, - MatchedFileCommentMap, - FileHash, -)> { +) -> anyhow::Result { let mut source_buffer = String::new(); path.open_file()?.read_to_string(&mut source_buffer)?; let file_hash = FileHash::new(&source_buffer); let fname = Symbol::from(path.as_str()); let source_str = Arc::from(source_buffer); + let reporter = compilation_env.diagnostic_reporter_at_top_level(); if let Err(ds) = verify_string(file_hash, &source_str) { - compilation_env.add_diags(ds); - files.add(file_hash, fname, source_str); - return Ok((vec![], MatchedFileCommentMap::new(), file_hash)); + reporter.add_diags(ds); + return Ok(ParsedFile { + fname, + defs: vec![], + comments: MatchedFileCommentMap::new(), + hash: file_hash, + text: source_str, + }); } let (defs, comments) = match parse_file_string(compilation_env, file_hash, &source_str, package) { Ok(defs_and_comments) => defs_and_comments, Err(ds) => { - compilation_env.add_diags(ds); + reporter.add_diags(ds); (vec![], MatchedFileCommentMap::new()) } }; - files.add(file_hash, fname, source_str); - Ok((defs, comments, file_hash)) + Ok(ParsedFile { + fname, + defs, + comments, + hash: file_hash, + text: source_str, + }) } diff --git a/external-crates/move/crates/move-compiler/src/parser/syntax.rs b/external-crates/move/crates/move-compiler/src/parser/syntax.rs index 72a5b348814..31b9eaaca7f 100644 --- a/external-crates/move/crates/move-compiler/src/parser/syntax.rs +++ b/external-crates/move/crates/move-compiler/src/parser/syntax.rs @@ -10,34 +10,36 @@ use move_command_line_common::files::FileHash; use move_ir_types::location::*; use move_proc_macros::growing_stack; -use move_symbol_pool::{symbol, Symbol}; +use move_symbol_pool::{Symbol, symbol}; use crate::{ - diag, - diagnostics::{Diagnostic, Diagnostics}, + MatchedFileCommentMap, diag, + diagnostics::{Diagnostic, DiagnosticReporter, Diagnostics}, editions::{Edition, FeatureGate, UPGRADE_NOTE}, parser::{ast::*, lexer::*, token_set::*}, shared::{string_utils::*, *}, - MatchedFileCommentMap, }; struct Context<'env, 'lexer, 'input> { current_package: Option, - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, + reporter: DiagnosticReporter<'env>, tokens: &'lexer mut Lexer<'input>, stop_set: TokenSet, } impl<'env, 'lexer, 'input> Context<'env, 'lexer, 'input> { fn new( - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, tokens: &'lexer mut Lexer<'input>, package_name: Option, ) -> Self { let stop_set = TokenSet::from([Tok::EOF]); + let reporter = env.diagnostic_reporter_at_top_level(); Self { current_package: package_name, env, + reporter, tokens, stop_set, } @@ -73,8 +75,13 @@ impl<'env, 'lexer, 'input> Context<'env, 'lexer, 'input> { } } - fn add_diag(&mut self, diag: Diagnostic) { - self.env.add_diag(diag); + fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + fn check_feature(&self, package: Option, feature: FeatureGate, loc: Loc) -> bool { + self.env + .check_feature(&self.reporter, package, feature, loc) } } @@ -419,7 +426,14 @@ where let loc = make_loc(context.tokens.file_hash(), current_loc, current_loc); let diag = diag!( Syntax::UnexpectedToken, - (loc, format!("Expected {}", item_description)) + ( + loc, + format!( + "Unexpected '{}'. Expected {}", + context.tokens.peek(), + item_description + ) + ) ); advance_separated_items_error( context, @@ -767,15 +781,13 @@ fn parse_name_access_chain_<'a, F: Fn() -> &'a str>( "Macro invocation are disallowed here. Expected {}", item_description() ); - context - .env - .add_diag(diag!(Syntax::InvalidName, (*loc, msg))); + context.add_diag(diag!(Syntax::InvalidName, (*loc, msg))); is_macro = None; } } if let Some(sp!(ty_loc, _)) = tys { if !tyargs_allowed { - context.env.add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidName, ( ty_loc, @@ -854,7 +866,7 @@ fn parse_name_access_chain_<'a, F: Fn() -> &'a str>( parse_macro_opt_and_tyargs_opt(context, tyargs_whitespace_allowed, name.loc); if let Some(loc) = &is_macro { if !macros_allowed { - context.env.add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidName, ( *loc, @@ -866,7 +878,7 @@ fn parse_name_access_chain_<'a, F: Fn() -> &'a str>( } if let Some(sp!(ty_loc, _)) = tys { if !tyargs_allowed { - context.env.add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidName, ( ty_loc, @@ -879,7 +891,7 @@ fn parse_name_access_chain_<'a, F: Fn() -> &'a str>( path.push_path_entry(name, tys, is_macro) .into_iter() - .for_each(|diag| context.env.add_diag(diag)); + .for_each(|diag| context.add_diag(diag)); } Ok(NameAccessChain_::Path(path)) } @@ -1292,7 +1304,7 @@ fn parse_bind(context: &mut Context) -> Result> { )?; let args = if context.tokens.peek() == Tok::LParen { let current_loc = current_token_loc(context.tokens); - context.env.check_feature( + context.check_feature( context.current_package, FeatureGate::PositionalFields, current_loc, @@ -1512,6 +1524,43 @@ fn parse_sequence_item(context: &mut Context) -> Result bool { + context.add_diag(diag); + // This is intended to handle a rather specific case when a valid sequence item + // is on the following line from the parsing error. This is particularly + // useful for the IDE use case when a programmer starts typing an incomplete + // (and unparsable) line right before the line containing a valid expression. + // In this case, we would like to still report the error but try to avoid + // dropping the valid expression itself, particularly as it might lead to + // unnecessary cascading errors to appear if this expression is a variable + // declaration as in the example below where we want to avoid `_tmp1` being + // undefined in the following lines. + // + // let v = + // let _tmp1 = 42; + // let _tmp2 = _tmp1 * param; + // let _tmp3 = _tmp1 + param; + + if context.at_stop_set() { + // don't continue if we are at the stop set + return false; + } + let tok = context.tokens.peek(); + if context.tokens.last_token_preceded_by_eol() + && (SEQ_ITEM_START_SET.contains(tok, context.tokens.content()) + // ANY identfier can start a sequence item + || tok == Tok::Identifier + || tok == Tok::SyntaxIdentifier + || tok == Tok::RestrictedIdentifier) + { + // if the last token was preceded by EOL, and it's in the start set for sequence + // items, continue parsing the sequence + return true; + } + false +} + // Parse a sequence: // Sequence = * ( ";")* ? "}" // @@ -1556,6 +1605,9 @@ fn parse_sequence(context: &mut Context) -> Result> { seq.push(item); last_semicolon_loc = Some(current_token_loc(context.tokens)); if let Err(diag) = consume_token(context.tokens, Tok::Semicolon) { + if should_continue_sequence_after_error(context, diag.as_ref().clone()) { + continue; + } advance_separated_items_error( context, Tok::LBrace, @@ -1572,10 +1624,13 @@ fn parse_sequence(context: &mut Context) -> Result> { } } Err(diag) => { + context.stop_set.remove(Tok::Semicolon); + if should_continue_sequence_after_error(context, diag.as_ref().clone()) { + continue; + } let err_exp = sp(context.tokens.current_token_loc(), Exp_::UnresolvedError); let err_seq_item = SequenceItem_::Seq(Box::new(err_exp)); seq.push(sp(context.tokens.current_token_loc(), err_seq_item)); - context.stop_set.remove(Tok::Semicolon); advance_separated_items_error( context, Tok::LBrace, @@ -1935,8 +1990,13 @@ fn parse_control_exp(context: &mut Context) -> Result<(Exp, bool), Box { context.tokens.advance()?; - let (e, ends_in_block) = parse_exp_or_sequence(context)?; - (Exp_::Abort(Box::new(e)), ends_in_block) + let (e, ends_in_block) = if !at_start_of_exp(context) { + (None, false) + } else { + let (e, ends_in_block) = parse_exp_or_sequence(context)?; + (Some(Box::new(e)), ends_in_block) + }; + (Exp_::Abort(e), ends_in_block) } Tok::Break => { context.tokens.advance()?; @@ -2083,27 +2143,36 @@ fn parse_match_arm(context: &mut Context) -> Result> { } _ => None, }; - consume_token(context.tokens, Tok::EqualGreater)?; - let rhs = match context.tokens.peek() { - Tok::LBrace => { - let block_start_loc = context.tokens.start_loc(); - context.tokens.advance()?; // consume the LBrace - let block_ = Exp_::Block(parse_sequence(context)?); - let block_end_loc = context.tokens.previous_end_loc(); - let exp = spanned( - context.tokens.file_hash(), - block_start_loc, - block_end_loc, - block_, - ); - Box::new(exp) + if let Err(diag) = consume_token(context.tokens, Tok::EqualGreater) { + // report incomplete pattern so that auto-completion can work + context.add_diag(*diag); + MatchArm_ { + pattern, + guard, + rhs: Box::new(sp(Loc::invalid(), Exp_::UnresolvedError)), + } + } else { + let rhs = match context.tokens.peek() { + Tok::LBrace => { + let block_start_loc = context.tokens.start_loc(); + context.tokens.advance()?; // consume the LBrace + let block_ = Exp_::Block(parse_sequence(context)?); + let block_end_loc = context.tokens.previous_end_loc(); + let exp = spanned( + context.tokens.file_hash(), + block_start_loc, + block_end_loc, + block_, + ); + Box::new(exp) + } + _ => Box::new(parse_exp(context)?), + }; + MatchArm_ { + pattern, + guard, + rhs, } - _ => Box::new(parse_exp(context)?), - }; - MatchArm_ { - pattern, - guard, - rhs, } }) } @@ -2152,7 +2221,7 @@ fn parse_match_pattern(context: &mut Context) -> Result Result Result { let field_access = Name::new(loc, format!("{parsed}").into()); - Exp_::Dot(Box::new(lhs), field_access) + Exp_::Dot(Box::new(lhs), first_token_loc, field_access) } Ok((_, NumberFormat::Hex)) => { let msg = "Invalid field access. Expected a decimal number but was given a hexadecimal"; @@ -2635,7 +2704,7 @@ fn parse_dot_or_index_chain(context: &mut Context) -> Result { let msg = format!( @@ -2647,7 +2716,7 @@ fn parse_dot_or_index_chain(context: &mut Context) -> Result Result { if context.at_stop_set() { - context - .env - .add_diag(*unexpected_token_error(context.tokens, "a type name")); + context.add_diag(*unexpected_token_error(context.tokens, "a type name")); Type_::UnresolvedError } else { let tn = if whitespace_sensitive_ty_args { @@ -3220,18 +3294,16 @@ fn parse_function_decl( ); let return_type = parse_ret_type(context, name) - .map_err(|diag| { + .inspect_err(|diag| { context.advance_until_stop_set(Some(*diag.clone())); - diag }) .ok(); context.stop_set.remove(Tok::LBrace); let body = parse_body(context, native) - .map_err(|diag| { + .inspect_err(|diag| { context.advance_until_stop_set(Some(*diag.clone())); - diag }) .ok(); @@ -3487,9 +3559,7 @@ fn parse_enum_variant_fields(context: &mut Context) -> Result { let current_package = context.current_package; let loc = current_token_loc(context.tokens); - context - .env - .check_feature(current_package, FeatureGate::PositionalFields, loc); + context.check_feature(current_package, FeatureGate::PositionalFields, loc); let list = parse_comma_list( context, @@ -3522,9 +3592,7 @@ fn check_enum_visibility(visibility: Option, context: &mut Context) // vis. support. match &visibility { Some(Visibility::Public(loc)) => { - context - .env - .check_feature(current_package, FeatureGate::Enums, *loc); + context.check_feature(current_package, FeatureGate::Enums, *loc); } vis => { let (loc, vis_str) = match vis { @@ -3540,7 +3608,7 @@ fn check_enum_visibility(visibility: Option, context: &mut Context) let note = "Visibility annotations are required on enum declarations."; let mut err = diag!(Syntax::InvalidModifier, (loc, msg)); err.add_note(note); - context.env.add_diag(err); + context.add_diag(err); } } } @@ -3596,12 +3664,11 @@ fn parse_struct_decl( let mut abilities = if infix_ability_declaration_loc.is_some() { parse_infix_ability_declarations(context) - .map_err(|diag| { + .inspect_err(|diag| { // if parsing failed, assume no abilities present even if `has` keyword was // present infix_ability_declaration_loc = None; context.advance_until_stop_set(Some(*diag.clone())); - diag }) .unwrap_or_default() } else { @@ -3647,9 +3714,8 @@ fn parse_struct_decl( infix_ability_declaration_loc, &mut abilities, ) - .map_err(|diag| { + .inspect_err(|diag| { context.advance_until_stop_set(Some(*diag.clone())); - diag }) .ok(); } @@ -3766,7 +3832,7 @@ fn parse_postfix_ability_declarations( let has_location = current_token_loc(context.tokens); if postfix_ability_declaration { - context.env.check_feature( + context.check_feature( context.current_package, FeatureGate::PostFixAbilities, has_location, @@ -3815,9 +3881,7 @@ fn parse_struct_fields(context: &mut Context) -> Result Result, context: &mut Context) { let current_package = context.current_package; if let Some(Visibility::Public(loc)) = &visibility { - context - .env - .check_feature(current_package, FeatureGate::StructTypeVisibility, *loc); + context.check_feature(current_package, FeatureGate::StructTypeVisibility, *loc); } let supports_public = context @@ -3995,9 +4057,7 @@ fn parse_address_block( addr_name.loc.start() as usize, context.tokens.current_token_loc().end() as usize, ); - context - .env - .add_diag(diag!(Migration::AddressRemove, (loc, "address decl"))); + context.add_diag(diag!(Migration::AddressRemove, (loc, "address decl"))); } context.tokens.advance()?; let mut modules = vec![]; @@ -4012,7 +4072,7 @@ fn parse_address_block( let (module, next_mod_attributes) = parse_module(attributes, context)?; if in_migration_mode { - context.env.add_diag(diag!( + context.add_diag(diag!( Migration::AddressAdd, ( module.name.loc(), @@ -4032,7 +4092,7 @@ fn parse_address_block( } for module in &modules { if matches!(module.definition_mode, ModuleDefinitionMode::Semicolon) { - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidModule, ( module.name.loc(), @@ -4044,9 +4104,7 @@ fn parse_address_block( if in_migration_mode { let loc = context.tokens.current_token_loc(); - context - .env - .add_diag(diag!(Migration::AddressRemove, (loc, "close lbrace"))); + context.add_diag(diag!(Migration::AddressRemove, (loc, "close lbrace"))); } consume_token(context.tokens, context.tokens.peek())?; @@ -4066,7 +4124,7 @@ fn parse_address_block( format!("Replace with '{}::{}'", addr, module.name), )); } - context.env.add_diag(diag); + context.add_diag(diag); } Ok(AddressDefinition { @@ -4099,7 +4157,7 @@ fn parse_friend_decl( || "a friend declaration", )?; if friend.value.is_macro().is_some() || friend.value.has_tyargs() { - context.env.add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidName, (friend.loc, "Invalid 'friend' name") )) @@ -4233,13 +4291,10 @@ fn parse_use_decl( address_start_loc, end_loc, ); - let module_ident = sp( - loc, - ModuleIdent_ { - address, - module: name, - }, - ); + let module_ident = sp(loc, ModuleIdent_ { + address, + module: name, + }); Use::ModuleUse(module_ident, use_) } Err(diag) => { @@ -4408,7 +4463,7 @@ fn parse_module( consume_token(context.tokens, Tok::LBrace)?; } Tok::Semicolon => { - context.env.check_feature( + context.check_feature( context.current_package, FeatureGate::ModuleLabel, name.loc(), @@ -4593,19 +4648,15 @@ fn parse_module_member(context: &mut Context) -> Result { context.tokens, &format!( "a module member: {}", - format_oxford_list!( - "or", - "'{}'", - [ - Tok::Spec, - Tok::Use, - Tok::Friend, - Tok::Const, - Tok::Fun, - Tok::Struct, - Tok::Enum - ] - ) + format_oxford_list!("or", "'{}'", [ + Tok::Spec, + Tok::Use, + Tok::Friend, + Tok::Const, + Tok::Fun, + Tok::Struct, + Tok::Enum + ]) ), ) } else { @@ -4613,18 +4664,14 @@ fn parse_module_member(context: &mut Context) -> Result { context.tokens, &format!( "a module member: {}", - format_oxford_list!( - "or", - "'{}'", - [ - Tok::Spec, - Tok::Use, - Tok::Friend, - Tok::Const, - Tok::Fun, - Tok::Struct - ] - ) + format_oxford_list!("or", "'{}'", [ + Tok::Spec, + Tok::Use, + Tok::Friend, + Tok::Const, + Tok::Fun, + Tok::Struct + ]) ), ) }; @@ -4656,7 +4703,7 @@ fn consume_spec_string(context: &mut Context) -> Result, Box { contents }'", ); - context.env.add_diag(diag); + context.add_diag(diag); } } defs.push(Definition::Module(module)); @@ -4744,7 +4791,7 @@ fn parse_file_def( /// Diagnostics. The `file` name is used to identify source locations in error /// messages. pub fn parse_file_string( - env: &mut CompilationEnv, + env: &CompilationEnv, file_hash: FileHash, input: &str, package: Option, diff --git a/external-crates/move/crates/move-compiler/src/parser/token_set.rs b/external-crates/move/crates/move-compiler/src/parser/token_set.rs index 802c13ac26d..a6acc08dae7 100644 --- a/external-crates/move/crates/move-compiler/src/parser/token_set.rs +++ b/external-crates/move/crates/move-compiler/src/parser/token_set.rs @@ -95,10 +95,18 @@ const EXP_STARTS: &[Tok] = &[ Tok::Return, Tok::While, Tok::BlockLabel, + Tok::Match, ]; pub static EXP_START_SET: Lazy = Lazy::new(|| TokenSet::from(EXP_STARTS)); +pub static SEQ_ITEM_START_SET: Lazy = Lazy::new(|| { + let mut token_set = TokenSet::new(); + token_set.add_all(EXP_STARTS); + token_set.add(Tok::Let); + token_set +}); + const TYPE_STARTS: &[Tok] = &[ Tok::Identifier, Tok::Amp, diff --git a/external-crates/move/crates/move-compiler/src/parser/verification_attribute_filter.rs b/external-crates/move/crates/move-compiler/src/parser/verification_attribute_filter.rs index f113ed82391..729e4f357a5 100644 --- a/external-crates/move/crates/move-compiler/src/parser/verification_attribute_filter.rs +++ b/external-crates/move/crates/move-compiler/src/parser/verification_attribute_filter.rs @@ -8,23 +8,27 @@ use move_symbol_pool::Symbol; use crate::{ diag, + diagnostics::DiagnosticReporter, parser::{ ast as P, - filter::{filter_program, FilterContext}, + filter::{FilterContext, filter_program}, }, - shared::{known_attributes, CompilationEnv}, + shared::{CompilationEnv, known_attributes}, }; struct Context<'env> { - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, + reporter: DiagnosticReporter<'env>, is_source_def: bool, current_package: Option, } impl<'env> Context<'env> { - fn new(env: &'env mut CompilationEnv) -> Self { + fn new(env: &'env CompilationEnv) -> Self { + let reporter = env.diagnostic_reporter_at_top_level(); Self { env, + reporter, is_source_def: false, current_package: None, } @@ -65,7 +69,7 @@ impl FilterContext for Context<'_> { "The '{}' attribute has been deprecated along with specification blocks", VerificationAttribute::VERIFY_ONLY ); - self.env + self.reporter .add_diag(diag!(Uncategorized::DeprecatedWillBeRemoved, (*loc, msg))); } } @@ -80,7 +84,7 @@ impl FilterContext for Context<'_> { // This filters out all AST elements annotated with verify-only annotated from // `prog` if the `verify` flag in `compilation_env` is not set. If the `verify` // flag is set, no filtering is performed. -pub fn program(compilation_env: &mut CompilationEnv, prog: P::Program) -> P::Program { +pub fn program(compilation_env: &CompilationEnv, prog: P::Program) -> P::Program { let mut context = Context::new(compilation_env); filter_program(&mut context, prog) } diff --git a/external-crates/move/crates/move-compiler/src/shared/ide.rs b/external-crates/move/crates/move-compiler/src/shared/ide.rs index ad6016cd574..886fe6c563e 100644 --- a/external-crates/move/crates/move-compiler/src/shared/ide.rs +++ b/external-crates/move/crates/move-compiler/src/shared/ide.rs @@ -17,7 +17,7 @@ use crate::{ unit_test::filter_test_members::UNIT_TEST_POISON_FUN_NAME, }; -use move_command_line_common::address::NumericalAddress; +use move_core_types::parsing::address::NumericalAddress; use move_ir_types::location::Loc; use move_symbol_pool::Symbol; diff --git a/external-crates/move/crates/move-compiler/src/shared/matching.rs b/external-crates/move/crates/move-compiler/src/shared/matching.rs index 6dd8be08357..2327d0c86c5 100644 --- a/external-crates/move/crates/move-compiler/src/shared/matching.rs +++ b/external-crates/move/crates/move-compiler/src/shared/matching.rs @@ -3,15 +3,14 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + diagnostics::DiagnosticReporter, expansion::ast::{Fields, ModuleIdent, Mutability, Value}, hlir::translate::NEW_NAME_DELIM, + ice, naming::ast::{self as N, Type, Var}, parser::ast::{BinOp_, ConstantName, Field, VariantName}, shared::{program_info::ProgramInfo, unique_map::UniqueMap, CompilationEnv}, - { - ice, - typing::ast::{self as T, MatchArm_, MatchPattern, UnannotatedPat_ as TP}, - }, + typing::ast::{self as T, MatchArm_, MatchPattern, UnannotatedPat_ as TP}, }; use move_ir_types::location::*; use move_proc_macros::growing_stack; @@ -68,8 +67,8 @@ pub struct ArmResult { /// A shared match context trait for use with counterexample generation in Typing and match /// compilation in HLIR lowering. pub trait MatchContext { - fn env(&mut self) -> &mut CompilationEnv; - fn env_ref(&self) -> &CompilationEnv; + fn env(&self) -> &CompilationEnv; + fn reporter(&self) -> &DiagnosticReporter; fn new_match_var(&mut self, name: String, loc: Loc) -> N::Var; fn program_info(&self) -> &ProgramInfo; @@ -482,7 +481,7 @@ impl PatternMatrix { // Make a match pattern that only holds guard binders let guard_binders = guard_binders.union_with(&const_binders, |k, _, x| { let msg = "Match compilation made a binder for this during const compilation"; - context.env().add_diag(ice!((k.loc, msg))); + context.reporter().add_diag(ice!((k.loc, msg))); *x }); let pat = apply_pattern_subst(pat, &guard_binders); @@ -519,9 +518,10 @@ impl PatternMatrix { .any(|pat| pat.is_wild_arm() && pat.guard.is_none()) } - pub fn wild_arm_opt(&mut self, fringe: &VecDeque) -> Option> { + pub fn wild_tree_opt(&mut self, fringe: &VecDeque) -> Option> { // NB: If the first row is all wild, we need to collect _all_ wild rows that have guards - // until we find one that does not. + // until we find one that does not. If we do not find one without a guard, then this isn't + // a wild tree. if let Some(arm) = self.patterns[0].all_wild_arm(fringe) { if arm.guard.is_none() { return Some(vec![arm]); @@ -536,7 +536,7 @@ impl PatternMatrix { } } } - Some(result) + None } else { None } diff --git a/external-crates/move/crates/move-compiler/src/shared/mod.rs b/external-crates/move/crates/move-compiler/src/shared/mod.rs index efd5820fcb1..829f4c8ab3c 100644 --- a/external-crates/move/crates/move-compiler/src/shared/mod.rs +++ b/external-crates/move/crates/move-compiler/src/shared/mod.rs @@ -3,6 +3,23 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use std::{ + collections::{BTreeMap, BTreeSet}, + fmt, + hash::Hash, + sync::{ + Arc, Mutex, OnceLock, RwLock, + atomic::{AtomicUsize, Ordering as AtomicOrdering}, + }, +}; + +use clap::*; +use move_command_line_common::files::FileHash; +use move_ir_types::location::*; +use move_symbol_pool::Symbol; +use petgraph::{algo::astar as petgraph_astar, graphmap::DiGraphMap}; +use vfs::{VfsError, VfsPath}; + use crate::{ cfgir::{ ast as G, @@ -10,44 +27,28 @@ use crate::{ }, command_line as cli, diagnostics::{ - codes::{Category, Declarations, DiagnosticsID, Severity, WarningFilter}, - Diagnostic, Diagnostics, DiagnosticsFormat, WarningFilters, - }, - editions::{ - check_feature_or_error as edition_check_feature, feature_edition_error_msg, Edition, - FeatureGate, Flavor, + DiagnosticReporter, Diagnostics, DiagnosticsFormat, + codes::{DiagnosticsID, Severity}, + warning_filters::{ + FILTER_ALL, FilterName, FilterPrefix, WarningFilter, WarningFiltersBuilder, + WarningFiltersScope, WarningFiltersTable, + }, }, + editions::{Edition, FeatureGate, Flavor, check_feature_or_error, feature_edition_error_msg}, expansion::ast as E, hlir::ast as H, + iota_mode, naming::ast as N, parser::ast as P, shared::{ files::{FileName, MappedFiles}, - ide::{IDEAnnotation, IDEInfo}, + ide::IDEInfo, }, - iota_mode, typing::{ ast as T, visitor::{TypingVisitor, TypingVisitorObj}, }, }; -use clap::*; -use move_command_line_common::files::FileHash; -use move_ir_types::location::*; -use move_symbol_pool::Symbol; -use petgraph::{algo::astar as petgraph_astar, graphmap::DiGraphMap}; -use std::{ - cell::RefCell, - collections::{BTreeMap, BTreeSet}, - fmt, - hash::Hash, - rc::Rc, - sync::{ - atomic::{AtomicUsize, Ordering as AtomicOrdering}, - Arc, - }, -}; -use vfs::{VfsError, VfsPath}; pub mod ast_debug; pub mod files; @@ -61,21 +62,17 @@ pub mod unique_map; pub mod unique_set; pub use ast_debug::AstDebug; - //************************************************************************************************** -// Numbers +// Address //************************************************************************************************** - -pub use move_command_line_common::parser::{ - parse_address_number as parse_address, parse_u128, parse_u16, parse_u256, parse_u32, parse_u64, - parse_u8, NumberFormat, -}; - +pub use move_core_types::parsing::address::NumericalAddress; //************************************************************************************************** -// Address +// Numbers //************************************************************************************************** - -pub use move_command_line_common::address::NumericalAddress; +pub use move_core_types::parsing::parser::{ + NumberFormat, parse_address_number as parse_address, parse_u8, parse_u16, parse_u32, parse_u64, + parse_u128, parse_u256, +}; pub fn parse_named_address(s: &str) -> anyhow::Result<(String, NumericalAddress)> { let before_after = s.split('=').collect::>(); @@ -173,28 +170,6 @@ pub fn shortest_cycle<'a, T: Ord + Hash>( // Compilation Env //************************************************************************************************** -pub const FILTER_ALL: &str = "all"; -pub const FILTER_UNUSED: &str = "unused"; -pub const FILTER_MISSING_PHANTOM: &str = "missing_phantom"; -pub const FILTER_UNUSED_USE: &str = "unused_use"; -pub const FILTER_UNUSED_VARIABLE: &str = "unused_variable"; -pub const FILTER_UNUSED_ASSIGNMENT: &str = "unused_assignment"; -pub const FILTER_UNUSED_TRAILING_SEMI: &str = "unused_trailing_semi"; -pub const FILTER_UNUSED_ATTRIBUTE: &str = "unused_attribute"; -pub const FILTER_UNUSED_TYPE_PARAMETER: &str = "unused_type_parameter"; -pub const FILTER_UNUSED_FUNCTION: &str = "unused_function"; -pub const FILTER_UNUSED_STRUCT_FIELD: &str = "unused_field"; -pub const FILTER_UNUSED_CONST: &str = "unused_const"; -pub const FILTER_DEAD_CODE: &str = "dead_code"; -pub const FILTER_UNUSED_LET_MUT: &str = "unused_let_mut"; -pub const FILTER_UNUSED_MUT_REF: &str = "unused_mut_ref"; -pub const FILTER_UNUSED_MUT_PARAM: &str = "unused_mut_parameter"; -pub const FILTER_IMPLICIT_CONST_COPY: &str = "implicit_const_copy"; -pub const FILTER_DUPLICATE_ALIAS: &str = "duplicate_alias"; -pub const FILTER_DEPRECATED: &str = "deprecated_usage"; -pub const FILTER_IDE_PATH_AUTOCOMPLETE: &str = "ide_path_autocomplete"; -pub const FILTER_IDE_DOT_AUTOCOMPLETE: &str = "ide_dot_autocomplete"; - pub type NamedAddressMap = BTreeMap; #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -236,17 +211,11 @@ pub struct PackagePaths = Symbol, NamedAddress: Into pub named_address_map: BTreeMap, } -/// None for the default 'allow'. -/// Some(prefix) for a custom set of warnings, e.g. 'allow(lint(_))'. -pub type FilterPrefix = Option; -pub type FilterName = Symbol; - pub struct CompilationEnv { flags: Flags, - // filters warnings when added. - warning_filter: Vec, - diags: Diagnostics, - visitors: Rc, + top_level_warning_filter_scope: Option<&'static WarningFiltersBuilder>, + diags: RwLock, + visitors: Visitors, package_configs: BTreeMap, /// Config for any package not found in `package_configs`, or for inputs /// without a package. @@ -256,27 +225,12 @@ pub struct CompilationEnv { known_filters: BTreeMap>>, /// Maps a diagnostics ID to a known filter name. known_filter_names: BTreeMap, - prim_definers: - BTreeMap, + prim_definers: OnceLock>, // TODO(tzakian): Remove the global counter and use this counter instead // pub counter: u64, mapped_files: MappedFiles, save_hooks: Vec, - pub ide_information: IDEInfo, -} - -macro_rules! known_code_filter { - ($name:ident, $category:ident::$code:ident) => { - ( - Symbol::from($name), - BTreeSet::from([WarningFilter::Code { - prefix: None, - category: Category::$category as u8, - code: $category::$code as u8, - name: Some($name), - }]), - ) - }; + ide_information: RwLock, } impl CompilationEnv { @@ -284,66 +238,18 @@ impl CompilationEnv { flags: Flags, mut visitors: Vec, save_hooks: Vec, + warning_filters: Option, package_configs: BTreeMap, default_config: Option, ) -> Self { - use crate::diagnostics::codes::{TypeSafety, UnusedItem, IDE}; visitors.extend([ iota_mode::id_leak::IDLeakVerifier.visitor(), iota_mode::typing::IotaTypeChecks.visitor(), ]); - let mut known_filters_: BTreeMap> = BTreeMap::from([ - ( - FILTER_ALL.into(), - BTreeSet::from([WarningFilter::All(None)]), - ), - ( - FILTER_UNUSED.into(), - BTreeSet::from([WarningFilter::Category { - prefix: None, - category: Category::UnusedItem as u8, - name: Some(FILTER_UNUSED), - }]), - ), - known_code_filter!(FILTER_MISSING_PHANTOM, Declarations::InvalidNonPhantomUse), - known_code_filter!(FILTER_UNUSED_USE, UnusedItem::Alias), - known_code_filter!(FILTER_UNUSED_VARIABLE, UnusedItem::Variable), - known_code_filter!(FILTER_UNUSED_ASSIGNMENT, UnusedItem::Assignment), - known_code_filter!(FILTER_UNUSED_TRAILING_SEMI, UnusedItem::TrailingSemi), - known_code_filter!(FILTER_UNUSED_ATTRIBUTE, UnusedItem::Attribute), - known_code_filter!(FILTER_UNUSED_FUNCTION, UnusedItem::Function), - known_code_filter!(FILTER_UNUSED_STRUCT_FIELD, UnusedItem::StructField), - ( - FILTER_UNUSED_TYPE_PARAMETER.into(), - BTreeSet::from([ - WarningFilter::Code { - prefix: None, - category: Category::UnusedItem as u8, - code: UnusedItem::StructTypeParam as u8, - name: Some(FILTER_UNUSED_TYPE_PARAMETER), - }, - WarningFilter::Code { - prefix: None, - category: Category::UnusedItem as u8, - code: UnusedItem::FunTypeParam as u8, - name: Some(FILTER_UNUSED_TYPE_PARAMETER), - }, - ]), - ), - known_code_filter!(FILTER_UNUSED_CONST, UnusedItem::Constant), - known_code_filter!(FILTER_DEAD_CODE, UnusedItem::DeadCode), - known_code_filter!(FILTER_UNUSED_LET_MUT, UnusedItem::MutModifier), - known_code_filter!(FILTER_UNUSED_MUT_REF, UnusedItem::MutReference), - known_code_filter!(FILTER_UNUSED_MUT_PARAM, UnusedItem::MutParam), - known_code_filter!(FILTER_IMPLICIT_CONST_COPY, TypeSafety::ImplicitConstantCopy), - known_code_filter!(FILTER_DUPLICATE_ALIAS, Declarations::DuplicateAlias), - known_code_filter!(FILTER_DEPRECATED, TypeSafety::DeprecatedUsage), - ]); + let mut known_filters_: BTreeMap> = + WarningFilter::compiler_known_filters(); if flags.ide_mode() { - known_filters_.extend([ - known_code_filter!(FILTER_IDE_PATH_AUTOCOMPLETE, IDE::PathAutocomplete), - known_code_filter!(FILTER_IDE_DOT_AUTOCOMPLETE, IDE::DotAutocomplete), - ]); + known_filters_.extend(WarningFilter::ide_known_filters()); } let known_filters: BTreeMap>> = BTreeMap::from([(None, known_filters_)]); @@ -369,30 +275,35 @@ impl CompilationEnv { }) .collect(); - let warning_filter = if flags.silence_warnings() { - let mut f = WarningFilters::new_for_source(); + let top_level_warning_filter_opt = if flags.silence_warnings() { + let mut f = WarningFiltersBuilder::new_for_source(); f.add(WarningFilter::All(None)); - vec![f] + Some(f) } else { - vec![] + warning_filters }; + let top_level_warning_filter_scope: Option<&'static WarningFiltersBuilder> = + top_level_warning_filter_opt.map(|f| { + let f: &'static WarningFiltersBuilder = Box::leak(Box::new(f)); + f + }); let mut diags = Diagnostics::new(); if flags.json_errors() { diags.set_format(DiagnosticsFormat::JSON); } Self { flags, - warning_filter, - diags, - visitors: Rc::new(Visitors::new(visitors)), + top_level_warning_filter_scope, + diags: RwLock::new(diags), + visitors: Visitors::new(visitors), package_configs, default_config: default_config.unwrap_or_default(), known_filters, known_filter_names, - prim_definers: BTreeMap::new(), + prim_definers: OnceLock::new(), mapped_files: MappedFiles::empty(), save_hooks, - ide_information: IDEInfo::new(), + ide_information: RwLock::new(IDEInfo::new()), } } @@ -409,53 +320,18 @@ impl CompilationEnv { &self.mapped_files } - pub fn add_diag(&mut self, mut diag: Diagnostic) { - if diag.info().severity() <= Severity::NonblockingError - && self - .diags - .any_syntax_error_with_primary_loc(diag.primary_loc()) - { - // do not report multiple diags for the same location (unless they are blocking) - // to avoid noise that is likely to confuse the developer trying to - // localize the problem - // - // TODO: this check is O(n^2) for n diags - shouldn't be a huge problem but fix - // if it becomes one - return; - } - - if !self.is_filtered(&diag) { - // add help to suppress warning, if applicable - // TODO do we want a centralized place for tips like this? - if diag.info().severity() == Severity::Warning { - if let Some((prefix, name)) = self.known_filter_names.get(&diag.info().id()) { - let help = format!( - "This warning can be suppressed with '#[{}({})]' \ - applied to the 'module' or module member ('const', 'fun', or 'struct')", - known_attributes::DiagnosticAttribute::ALLOW, - format_allow_attr(*prefix, *name), - ); - diag.add_note(help) - } - if self.flags.warnings_are_errors() { - diag = diag.set_severity(Severity::NonblockingError) - } - } - self.diags.add(diag) - } else if !self.filter_for_dependency() { - // unwrap above is safe as the filter has been used (thus it must exist) - self.diags.add_source_filtered(diag) - } - } - - pub fn add_diags(&mut self, diags: Diagnostics) { - for diag in diags.into_vec() { - self.add_diag(diag) - } + pub fn diagnostic_reporter_at_top_level(&self) -> DiagnosticReporter { + DiagnosticReporter::new( + &self.flags, + &self.known_filter_names, + &self.diags, + &self.ide_information, + WarningFiltersScope::root(self.top_level_warning_filter_scope), + ) } pub fn has_warnings_or_errors(&self) -> bool { - !self.diags.is_empty() + !self.diags.read().unwrap().is_empty() } pub fn has_errors(&self) -> bool { @@ -464,63 +340,45 @@ impl CompilationEnv { } pub fn count_diags(&self) -> usize { - self.diags.len() + self.diags.read().unwrap().len() } pub fn count_diags_at_or_above_severity(&self, threshold: Severity) -> usize { - self.diags.count_diags_at_or_above_severity(threshold) + self.diags + .read() + .unwrap() + .count_diags_at_or_above_severity(threshold) } pub fn has_diags_at_or_above_severity(&self, threshold: Severity) -> bool { - self.diags.max_severity_at_or_above_severity(threshold) + self.diags + .read() + .unwrap() + .max_severity_at_or_above_severity(threshold) } - pub fn check_diags_at_or_above_severity( - &mut self, - threshold: Severity, - ) -> Result<(), Diagnostics> { + pub fn check_diags_at_or_above_severity(&self, threshold: Severity) -> Result<(), Diagnostics> { if self.has_diags_at_or_above_severity(threshold) { - Err(std::mem::take(&mut self.diags)) + let diagnostics: &mut Diagnostics = &mut self.diags.write().unwrap(); + Err(std::mem::take(diagnostics)) } else { Ok(()) } } /// Should only be called after compilation is finished - pub fn take_final_diags(&mut self) -> Diagnostics { - std::mem::take(&mut self.diags) + pub fn take_final_diags(&self) -> Diagnostics { + let diagnostics: &mut Diagnostics = &mut self.diags.write().unwrap(); + std::mem::take(diagnostics) } /// Should only be called after compilation is finished - pub fn take_final_warning_diags(&mut self) -> Diagnostics { + pub fn take_final_warning_diags(&self) -> Diagnostics { let final_diags = self.take_final_diags(); debug_assert!(final_diags.max_severity_at_or_under_severity(Severity::Warning)); final_diags } - /// Add a new filter for warnings - pub fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.warning_filter.push(filter) - } - - pub fn pop_warning_filter_scope(&mut self) { - self.warning_filter.pop().unwrap(); - } - - fn is_filtered(&self, diag: &Diagnostic) -> bool { - self.warning_filter - .iter() - .rev() - .any(|filter| filter.is_filtered(diag)) - } - - fn filter_for_dependency(&self) -> bool { - self.warning_filter - .iter() - .rev() - .any(|filter| filter.for_dependency()) - } - pub fn known_filter_names(&self) -> impl IntoIterator + '_ { self.known_filters.keys().copied() } @@ -580,24 +438,25 @@ impl CompilationEnv { &self.flags } - pub fn visitors(&self) -> Rc { - self.visitors.clone() + pub fn visitors(&self) -> &Visitors { + &self.visitors } // Logs an error if the feature isn't supported. Returns `false` if the feature // is not supported, and `true` otherwise. pub fn check_feature( - &mut self, + &self, + reporter: &DiagnosticReporter, package: Option, feature: FeatureGate, loc: Loc, ) -> bool { - edition_check_feature(self, self.package_config(package).edition, feature, loc) + check_feature_or_error(reporter, self.package_config(package).edition, feature, loc) } // Returns an error string if if the feature isn't supported, or None otherwise. pub fn feature_edition_error_msg( - &mut self, + &self, feature: FeatureGate, package: Option, ) -> Option { @@ -618,15 +477,20 @@ impl CompilationEnv { .unwrap_or(&self.default_config) } - pub fn set_primitive_type_definers( - &mut self, - m: BTreeMap, - ) { - self.prim_definers = m + pub fn package_configs(&self) -> impl Iterator, &PackageConfig)> { + std::iter::once((None, &self.default_config)).chain( + self.package_configs + .iter() + .map(|(n, config)| (Some(*n), config)), + ) + } + + pub fn set_primitive_type_definers(&self, m: BTreeMap) { + self.prim_definers.set(m).unwrap() } pub fn primitive_definer(&self, t: N::BuiltinTypeName_) -> Option<&E::ModuleIdent> { - self.prim_definers.get(&t) + self.prim_definers.get().and_then(|m| m.get(&t)) } pub fn save_parser_ast(&self, ast: &P::Program) { @@ -677,22 +541,8 @@ impl CompilationEnv { self.flags.ide_mode() } - pub fn extend_ide_info(&mut self, info: IDEInfo) { - if self.flags().ide_test_mode() { - for entry in info.annotations.iter() { - let diag = entry.clone().into(); - self.add_diag(diag); - } - } - self.ide_information.extend(info); - } - - pub fn add_ide_annotation(&mut self, loc: Loc, info: IDEAnnotation) { - if self.flags().ide_test_mode() { - let diag = (loc, info.clone()).into(); - self.add_diag(diag); - } - self.ide_information.add_ide_annotation(loc, info); + pub fn ide_information(&self) -> std::sync::RwLockReadGuard<'_, IDEInfo> { + self.ide_information.read().unwrap() } } @@ -923,7 +773,7 @@ impl Flags { #[derive(PartialEq, Eq, Clone, Debug)] pub struct PackageConfig { pub is_dependency: bool, - pub warning_filter: WarningFilters, + pub warning_filter: WarningFiltersBuilder, pub flavor: Flavor, pub edition: Edition, } @@ -932,7 +782,7 @@ impl Default for PackageConfig { fn default() -> Self { Self { is_dependency: false, - warning_filter: WarningFilters::new_for_source(), + warning_filter: WarningFiltersBuilder::new_for_source(), flavor: Flavor::default(), edition: Edition::default(), } @@ -944,9 +794,9 @@ impl Default for PackageConfig { //************************************************************************************************** pub struct Visitors { - pub typing: Vec>, - pub abs_int: Vec>, - pub cfgir: Vec>, + pub typing: Vec, + pub abs_int: Vec, + pub cfgir: Vec, } impl Visitors { @@ -959,21 +809,33 @@ impl Visitors { }; for pass in passes { match pass { - Visitor::AbsIntVisitor(f) => vs.abs_int.push(RefCell::new(f)), - Visitor::TypingVisitor(f) => vs.typing.push(RefCell::new(f)), - Visitor::CFGIRVisitor(f) => vs.cfgir.push(RefCell::new(f)), + Visitor::AbsIntVisitor(f) => vs.abs_int.push(f), + Visitor::TypingVisitor(f) => vs.typing.push(f), + Visitor::CFGIRVisitor(f) => vs.cfgir.push(f), } } vs } } +// TODO remove it once visitor invocation is parallel +#[allow(unused)] +fn check() {} +#[allow(unused)] +fn check_all() { + check::(); + check::<&Visitors>(); + check::<&WarningFiltersTable>(); + check::<&WarningFiltersScope>(); + check::<&CompilationEnv>(); +} + //************************************************************************************************** // Save Hooks //************************************************************************************************** #[derive(Clone)] -pub struct SaveHook(Rc>); +pub struct SaveHook(Arc>); #[derive(Clone)] pub(crate) struct SavedInfo { @@ -1001,7 +863,7 @@ pub enum SaveFlag { impl SaveHook { pub fn new(flags: impl IntoIterator) -> Self { let flags = flags.into_iter().collect(); - Self(Rc::new(RefCell::new(SavedInfo { + Self(Arc::new(Mutex::new(SavedInfo { flags, parser: None, expansion: None, @@ -1014,56 +876,56 @@ impl SaveHook { } pub(crate) fn save_parser_ast(&self, ast: &P::Program) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.parser.is_none() && r.flags.contains(&SaveFlag::Parser) { r.parser = Some(ast.clone()) } } pub(crate) fn save_expansion_ast(&self, ast: &E::Program) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.expansion.is_none() && r.flags.contains(&SaveFlag::Expansion) { r.expansion = Some(ast.clone()) } } pub(crate) fn save_naming_ast(&self, ast: &N::Program) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.naming.is_none() && r.flags.contains(&SaveFlag::Naming) { r.naming = Some(ast.clone()) } } pub(crate) fn save_typing_ast(&self, ast: &T::Program) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.typing.is_none() && r.flags.contains(&SaveFlag::Typing) { r.typing = Some(ast.clone()) } } pub(crate) fn save_typing_info(&self, info: &Arc) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.typing_info.is_none() && r.flags.contains(&SaveFlag::TypingInfo) { r.typing_info = Some(info.clone()) } } pub(crate) fn save_hlir_ast(&self, ast: &H::Program) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.hlir.is_none() && r.flags.contains(&SaveFlag::HLIR) { r.hlir = Some(ast.clone()) } } pub(crate) fn save_cfgir_ast(&self, ast: &G::Program) { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); if r.cfgir.is_none() && r.flags.contains(&SaveFlag::CFGIR) { r.cfgir = Some(ast.clone()) } } pub fn take_parser_ast(&self) -> P::Program { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::Parser), "Parser AST not saved. Please set the flag when creating the SaveHook" @@ -1072,7 +934,7 @@ impl SaveHook { } pub fn take_expansion_ast(&self) -> E::Program { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::Expansion), "Expansion AST not saved. Please set the flag when creating the SaveHook" @@ -1081,7 +943,7 @@ impl SaveHook { } pub fn take_naming_ast(&self) -> N::Program { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::Naming), "Naming AST not saved. Please set the flag when creating the SaveHook" @@ -1090,7 +952,7 @@ impl SaveHook { } pub fn take_typing_ast(&self) -> T::Program { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::Typing), "Typing AST not saved. Please set the flag when creating the SaveHook" @@ -1099,7 +961,7 @@ impl SaveHook { } pub fn take_typing_info(&self) -> Arc { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::TypingInfo), "Typing info not saved. Please set the flag when creating the SaveHook" @@ -1108,7 +970,7 @@ impl SaveHook { } pub fn take_hlir_ast(&self) -> H::Program { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::HLIR), "HLIR AST not saved. Please set the flag when creating the SaveHook" @@ -1117,7 +979,7 @@ impl SaveHook { } pub fn take_cfgir_ast(&self) -> G::Program { - let mut r = RefCell::borrow_mut(&self.0); + let mut r = self.0.lock().unwrap(); assert!( r.flags.contains(&SaveFlag::CFGIR), "CFGIR AST not saved. Please set the flag when creating the SaveHook" diff --git a/external-crates/move/crates/move-compiler/src/shared/program_info.rs b/external-crates/move/crates/move-compiler/src/shared/program_info.rs index 3e8b90efd36..80595cbfb25 100644 --- a/external-crates/move/crates/move-compiler/src/shared/program_info.rs +++ b/external-crates/move/crates/move-compiler/src/shared/program_info.rs @@ -9,7 +9,9 @@ use move_symbol_pool::Symbol; use self::known_attributes::AttributePosition; use crate::{ + FullyCompiledProgram, expansion::ast::{AbilitySet, Attributes, ModuleIdent, TargetKind, Visibility}, + iota_mode::info::IotaInfo, naming::ast::{ self as N, DatatypeTypeParameter, EnumDefinition, FunctionSignature, ResolvedUseFuns, StructDefinition, SyntaxMethods, Type, @@ -17,7 +19,6 @@ use crate::{ parser::ast::{ConstantName, DatatypeName, Field, FunctionName, VariantName}, shared::{unique_map::UniqueMap, *}, typing::ast::{self as T}, - FullyCompiledProgram, }; #[derive(Debug, Clone)] @@ -51,6 +52,14 @@ pub struct ModuleInfo { pub constants: UniqueMap, } +#[derive(Debug, Clone)] +pub struct ProgramInfo { + pub modules: UniqueMap, + pub iota_flavor_info: Option, +} +pub type NamingProgramInfo = ProgramInfo; +pub type TypingProgramInfo = ProgramInfo; + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeKind { Struct, @@ -65,13 +74,6 @@ pub enum NamedMemberKind { Constant, } -#[derive(Debug, Clone)] -pub struct ProgramInfo { - pub modules: UniqueMap, -} -pub type NamingProgramInfo = ProgramInfo; -pub type TypingProgramInfo = ProgramInfo; - macro_rules! program_info { ($pre_compiled_lib:ident, $prog:ident, $pass:ident, $module_use_funs:ident) => {{ let all_modules = $prog.modules.key_cloned_iter(); @@ -117,12 +119,16 @@ macro_rules! program_info { } } } - ProgramInfo { modules } + ProgramInfo { + modules, + iota_flavor_info: None, + } }}; } impl TypingProgramInfo { pub fn new( + env: &CompilationEnv, pre_compiled_lib: Option>, modules: &UniqueMap, mut module_use_funs: BTreeMap, @@ -132,7 +138,18 @@ impl TypingProgramInfo { } let mut module_use_funs = Some(&mut module_use_funs); let prog = Prog { modules }; - program_info!(pre_compiled_lib, prog, typing, module_use_funs) + let pcl = pre_compiled_lib.clone(); + let mut info = program_info!(pcl, prog, typing, module_use_funs); + // TODO we should really have an idea of root package flavor here + // but this feels roughly equivalent + if env + .package_configs() + .any(|(_, config)| config.flavor == Flavor::Iota) + { + let iota_flavor_info = IotaInfo::new(pre_compiled_lib, modules, &info); + info.iota_flavor_info = Some(iota_flavor_info); + }; + info } } diff --git a/external-crates/move/crates/move-compiler/src/shared/string_utils.rs b/external-crates/move/crates/move-compiler/src/shared/string_utils.rs index 2fd7079ed72..21060bd1f2e 100644 --- a/external-crates/move/crates/move-compiler/src/shared/string_utils.rs +++ b/external-crates/move/crates/move-compiler/src/shared/string_utils.rs @@ -97,11 +97,14 @@ pub(crate) use format_oxford_list; /// - `fmt`: calls `println!("{}", val)` /// - `dbg`: calls `println!("{:?}", val)` /// - `sdbg`: calls `println!("{:#?}", val)` +#[allow(unused_macros)] macro_rules! debug_print_format { ($val:expr) => {{ + use crate::shared::ast_debug::AstDebug; $val.print(); }}; ($val:expr ; verbose) => {{ + use crate::shared::ast_debug::AstDebug; $val.print_verbose(); }}; ($val:expr ; fmt) => {{ @@ -115,6 +118,7 @@ macro_rules! debug_print_format { }}; } +#[allow(unused_imports)] pub(crate) use debug_print_format; /// Print formatter for debugging. Allows a few different forms: @@ -125,6 +129,7 @@ pub(crate) use debug_print_format; /// `(lines name => val [; fmt]) ` as "name: " + for n in val { debug_print_format!(n; fmt) } /// /// See `debug_print_format` for different `fmt` options. +#[allow(unused_macros)] macro_rules! debug_print_internal { () => {}; ((msg $msg:expr)) => { @@ -166,6 +171,7 @@ macro_rules! debug_print_internal { }; } +#[allow(unused_imports)] pub(crate) use debug_print_internal; /// Macro for a small DSL for compactling printing debug information based on the provided flag. @@ -182,6 +188,7 @@ pub(crate) use debug_print_internal; /// See `debug_print_internal` for the available syntax. /// /// Feature gates the print and check against the `debug_assertions` feature. +#[allow(unused_macros)] macro_rules! debug_print { ($flag:expr, $($arg:tt),+) => { #[cfg(debug_assertions)] diff --git a/external-crates/move/crates/move-compiler/src/shared/unique_map.rs b/external-crates/move/crates/move-compiler/src/shared/unique_map.rs index 8105d4acec6..bff4465da8c 100644 --- a/external-crates/move/crates/move-compiler/src/shared/unique_map.rs +++ b/external-crates/move/crates/move-compiler/src/shared/unique_map.rs @@ -5,6 +5,8 @@ use std::{collections::BTreeMap, fmt::Debug, iter::IntoIterator}; +use rayon::prelude::*; + use super::*; //************************************************************************************************** @@ -226,6 +228,78 @@ impl UniqueMap { } } +impl UniqueMap +where + K: Sync + Send, + K::Key: Sync, + K::Loc: Send + Sync, + V: Sync, +{ + pub fn key_cloned_par_iter(&self) -> impl ParallelIterator { + self.par_iter() + .map(|(loc, k_, v)| (K::add_loc(loc, k_.clone()), v)) + } +} + +impl UniqueMap +where + K: Sync + Send, + K::Key: Sync, + K::Loc: Send + Sync, + V: Sync + Send, +{ + pub fn key_cloned_par_iter_mut(&mut self) -> impl ParallelIterator { + IntoParallelRefMutIterator::par_iter_mut(self) + .map(|(loc, k_, v)| (K::add_loc(loc, k_.clone()), v)) + } +} + +impl UniqueMap +where + K: Send, + K::Key: Send, + K::Loc: Send, + V: Send, +{ + pub fn par_map(self, f: F) -> UniqueMap + where + V2: Send, + F: Fn(K, V) -> V2 + Sync + Send, + { + UniqueMap( + self.0 + .into_par_iter() + .map(|(k_, (loc, v))| { + let v2 = f(K::add_loc(loc, k_.clone()), v); + (k_, (loc, v2)) + }) + .collect(), + ) + } + + pub fn maybe_from_par_iter( + iter: impl ParallelIterator, + ) -> Result, (K::Key, K::Loc, K::Loc)> { + iter.try_fold(Self::new, |mut m, (k, v)| { + if let Err((k, old_loc)) = m.add(k, v) { + let (loc, key_) = k.drop_loc(); + Err((key_, loc, old_loc)) + } else { + Ok(m) + } + }) + .try_reduce(Self::new, |mut m1, m2| { + for (k, v) in m2 { + if let Err((k, old_loc)) = m1.add(k, v) { + let (loc, key_) = k.drop_loc(); + return Err((key_, loc, old_loc)); + } + } + Ok(m1) + }) + } +} + impl PartialEq for UniqueMap { fn eq(&self, other: &UniqueMap) -> bool { self.iter() @@ -327,6 +401,29 @@ impl IntoIterator for UniqueMap { } } +impl IntoParallelIterator for UniqueMap +where + K: Send, + K::Key: Send, + K::Loc: Send, + V: Send, +{ + type Iter = rayon::iter::Map< + rayon::collections::btree_map::IntoIter, + fn((K::Key, (K::Loc, V))) -> (K, V), + >; + type Item = (K, V); + + fn into_par_iter(self) -> Self::Iter { + self.0.into_par_iter().map(|(k_, loc_v)| { + let loc = loc_v.0; + let v = loc_v.1; + let k = K::add_loc(loc, k_); + (k, v) + }) + } +} + //************************************************************************************************** // Iter //************************************************************************************************** @@ -368,6 +465,29 @@ impl<'a, K: TName, V> IntoIterator for &'a UniqueMap { } } +impl<'a, K: TName, V> IntoParallelRefIterator<'a> for UniqueMap +where + K: Sync, + K::Key: Sync + 'a, + K::Loc: Send + Sync + 'a, + V: Sync + 'a, +{ + type Iter = rayon::iter::Map< + rayon::collections::btree_map::Iter<'a, K::Key, (K::Loc, V)>, + fn((&'a K::Key, &'a (K::Loc, V))) -> (K::Loc, &'a K::Key, &'a V), + >; + type Item = (K::Loc, &'a K::Key, &'a V); + + fn par_iter(&'a self) -> Self::Iter { + let fix = |(k_, loc_v): (&'a K::Key, &'a (K::Loc, V))| -> (K::Loc, &'a K::Key, &'a V) { + let loc = loc_v.0; + let v = &loc_v.1; + (loc, k_, v) + }; + self.0.par_iter().map(fix) + } +} + //************************************************************************************************** // IterMut //************************************************************************************************** @@ -406,3 +526,27 @@ impl<'a, K: TName, V> IntoIterator for &'a mut UniqueMap { IterMut(self.0.iter_mut().map(fix), len) } } + +impl<'a, K: TName, V> IntoParallelRefMutIterator<'a> for UniqueMap +where + K: Sync, + K::Key: Sync + 'a, + K::Loc: Send + Sync + 'a, + V: Sync + Send + 'a, +{ + type Iter = rayon::iter::Map< + rayon::collections::btree_map::IterMut<'a, K::Key, (K::Loc, V)>, + fn((&'a K::Key, &'a mut (K::Loc, V))) -> (K::Loc, &'a K::Key, &'a mut V), + >; + type Item = (K::Loc, &'a K::Key, &'a mut V); + + fn par_iter_mut(&'a mut self) -> Self::Iter { + let fix = + |(k_, loc_v): (&'a K::Key, &'a mut (K::Loc, V))| -> (K::Loc, &'a K::Key, &'a mut V) { + let loc = loc_v.0; + let v = &mut loc_v.1; + (loc, k_, v) + }; + self.0.par_iter_mut().map(fix) + } +} diff --git a/external-crates/move/crates/move-compiler/src/to_bytecode/canonicalize_handles.rs b/external-crates/move/crates/move-compiler/src/to_bytecode/canonicalize_handles.rs index 5a99c3360c4..36e90fa8100 100644 --- a/external-crates/move/crates/move-compiler/src/to_bytecode/canonicalize_handles.rs +++ b/external-crates/move/crates/move-compiler/src/to_bytecode/canonicalize_handles.rs @@ -5,6 +5,7 @@ use std::collections::HashMap; use move_binary_format::{ + CompiledModule, file_format::{ Bytecode, CodeUnit, DatatypeHandleIndex, EnumDefinition, EnumDefinitionIndex, FunctionDefinition, FunctionDefinitionIndex, FunctionHandleIndex, IdentifierIndex, @@ -12,7 +13,6 @@ use move_binary_format::{ StructFieldInformation, TableIndex, }, internals::ModuleIndex, - CompiledModule, }; use move_core_types::account_address::AccountAddress; use move_symbol_pool::Symbol; diff --git a/external-crates/move/crates/move-compiler/src/to_bytecode/context.rs b/external-crates/move/crates/move-compiler/src/to_bytecode/context.rs index 83492f69493..edc47e14ea2 100644 --- a/external-crates/move/crates/move-compiler/src/to_bytecode/context.rs +++ b/external-crates/move/crates/move-compiler/src/to_bytecode/context.rs @@ -28,7 +28,7 @@ pub type DatatypeDeclarations = /// Compilation context for a single compilation unit (module). /// Contains all of the dependencies actually used in the module pub struct Context<'a> { - pub env: &'a mut CompilationEnv, + pub env: &'a CompilationEnv, current_package: Option, current_module: Option<&'a ModuleIdent>, seen_datatypes: BTreeSet<(ModuleIdent, DatatypeName)>, @@ -37,7 +37,7 @@ pub struct Context<'a> { impl<'a> Context<'a> { pub fn new( - env: &'a mut CompilationEnv, + env: &'a CompilationEnv, current_package: Option, current_module: Option<&'a ModuleIdent>, ) -> Self { diff --git a/external-crates/move/crates/move-compiler/src/to_bytecode/translate.rs b/external-crates/move/crates/move-compiler/src/to_bytecode/translate.rs index 8f914a6cd30..b49b9d4d8d2 100644 --- a/external-crates/move/crates/move-compiler/src/to_bytecode/translate.rs +++ b/external-crates/move/crates/move-compiler/src/to_bytecode/translate.rs @@ -21,6 +21,7 @@ use crate::{ cfgir::{ast as G, translate::move_value_from_value_}, compiled_unit::*, diag, + diagnostics::DiagnosticReporter, expansion::ast::{ AbilitySet, Address, Attributes, ModuleIdent, ModuleIdent_, Mutability, TargetKind, }, @@ -41,7 +42,7 @@ type CollectedInfos = UniqueMap; type CollectedInfo = (Vec<(Mutability, Var, H::SingleType)>, Attributes); fn extract_decls( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: &G::Program, ) -> ( @@ -130,15 +131,16 @@ fn extract_decls( //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: G::Program, ) -> Vec { let mut units = vec![]; - + let reporter = compilation_env.diagnostic_reporter_at_top_level(); let (orderings, ddecls, fdecls) = extract_decls(compilation_env, pre_compiled_lib, &prog); let G::Program { modules: gmodules, + warning_filters_table, info: _, } = prog; @@ -148,15 +150,27 @@ pub fn program( .collect::>(); source_modules.sort_by_key(|(_, mdef)| mdef.dependency_order); for (m, mdef) in source_modules { - if let Some(unit) = module(compilation_env, m, mdef, &orderings, &ddecls, &fdecls) { + if let Some(unit) = module( + compilation_env, + &reporter, + m, + mdef, + &orderings, + &ddecls, + &fdecls, + ) { units.push(unit) } } + // there are unsafe pointers into this table in the WarningFilters in the AST. Now that they + // are gone, the table can safely be dropped. + drop(warning_filters_table); units } fn module( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, + reporter: &DiagnosticReporter, ident: ModuleIdent, mdef: G::ModuleDefinition, dependency_orderings: &HashMap, @@ -230,7 +244,7 @@ fn module( match move_ir_to_bytecode::compiler::compile_module(ir_module, deps) { Ok(res) => res, Err(e) => { - compilation_env.add_diag(diag!( + reporter.add_diag(diag!( Bug::BytecodeGeneration, (ident_loc, format!("IR ERROR: {}", e)) )); @@ -555,6 +569,7 @@ fn function( warning_filter: _warning_filter, index: _index, attributes, + loc, compiled_visibility: v, // original, declared visibility is ignored. This is primarily for marking entry functions // as public in tests @@ -586,15 +601,16 @@ fn function( IR::FunctionBody::Bytecode { locals, code } } }; - let loc = f.loc(); + let name_loc = f.loc(); let name = context.function_definition_name(m, f); let ir_function = IR::Function_ { + loc, visibility: v, is_entry: entry.is_some(), signature, body, }; - ((name, sp(loc, ir_function)), (parameters, attributes)) + ((name, sp(name_loc, ir_function)), (parameters, attributes)) } fn visibility(_context: &mut Context, v: Visibility) -> IR::FunctionVisibility { @@ -815,11 +831,11 @@ fn base_types(context: &mut Context, bs: Vec) -> Vec { bs.into_iter().map(|b| base_type(context, b)).collect() } -fn base_type(context: &mut Context, sp!(_, bt_): H::BaseType) -> IR::Type { +fn base_type(context: &mut Context, sp!(bt_loc, bt_): H::BaseType) -> IR::Type { use BuiltinTypeName_ as BT; use H::{BaseType_ as B, TypeName_ as TN}; - use IR::Type as IRT; - match bt_ { + use IR::Type_ as IRT; + let type_ = match bt_ { B::Unreachable | B::UnresolvedError => { panic!("ICE should not have reached compilation if there are errors") } @@ -849,15 +865,19 @@ fn base_type(context: &mut Context, sp!(_, bt_): H::BaseType) -> IR::Type { user_specified_name, .. }) => IRT::TypeParameter(type_var(user_specified_name).value), - } + }; + sp(bt_loc, type_) } -fn single_type(context: &mut Context, sp!(_, st_): H::SingleType) -> IR::Type { +fn single_type(context: &mut Context, sp!(st_loc, st_): H::SingleType) -> IR::Type { use H::SingleType_ as S; - use IR::Type as IRT; + use IR::Type_ as IRT; match st_ { S::Base(bt) => base_type(context, bt), - S::Ref(mut_, bt) => IRT::Reference(mut_, Box::new(base_type(context, bt))), + S::Ref(mut_, bt) => sp( + st_loc, + IRT::Reference(mut_, Box::new(base_type(context, bt))), + ), } } @@ -891,7 +911,7 @@ fn command(context: &mut Context, code: &mut IR::BytecodeBlock, sp!(loc, cmd_): exp(context, code, *eref); code.push(sp(loc, B::WriteRef)); } - C::Abort(ecode) => { + C::Abort(_, ecode) => { exp(context, code, ecode); code.push(sp(loc, B::Abort)); } diff --git a/external-crates/move/crates/move-compiler/src/typing/ast.rs b/external-crates/move/crates/move-compiler/src/typing/ast.rs index 15adfa4e2e8..762c5b54a02 100644 --- a/external-crates/move/crates/move-compiler/src/typing/ast.rs +++ b/external-crates/move/crates/move-compiler/src/typing/ast.rs @@ -9,27 +9,29 @@ use std::{ sync::Arc, }; +use move_core_types::parsing::address::NumericalAddress; use move_ir_types::location::*; +use move_proc_macros::growing_stack; use move_symbol_pool::Symbol; use crate::{ - debug_display, - diagnostics::WarningFilters, + diagnostics::{ + DiagnosticReporter, + warning_filters::{WarningFilters, WarningFiltersTable}, + }, expansion::ast::{ Address, Attributes, Fields, Friend, ModuleIdent, Mutability, TargetKind, Value, Visibility, }, ice, naming::ast::{ BlockLabel, EnumDefinition, FunctionSignature, Neighbor, StructDefinition, SyntaxMethods, - Type, TypeName_, Type_, UseFuns, Var, + Type, Type_, UseFuns, Var, }, parser::ast::{ - BinOp, ConstantName, DatatypeName, Field, FunctionName, UnaryOp, VariantName, - ENTRY_MODIFIER, MACRO_MODIFIER, NATIVE_MODIFIER, - }, - shared::{ - ast_debug::*, program_info::TypingProgramInfo, unique_map::UniqueMap, CompilationEnv, Name, + BinOp, ConstantName, DatatypeName, ENTRY_MODIFIER, Field, FunctionName, MACRO_MODIFIER, + NATIVE_MODIFIER, UnaryOp, VariantName, }, + shared::{Name, ast_debug::*, program_info::TypingProgramInfo, unique_map::UniqueMap}, }; //************************************************************************************************** @@ -39,6 +41,9 @@ use crate::{ #[derive(Debug, Clone)] pub struct Program { pub info: Arc, + /// Safety: This table should not be dropped as long as any `WarningFilters` + /// are alive + pub warning_filters_table: Arc, pub modules: UniqueMap, } @@ -87,6 +92,7 @@ pub struct Function { // index in the original order as defined in the source file pub index: usize, pub attributes: Attributes, + pub loc: Loc, /// The original, declared visibility as defined in the source file pub visibility: Visibility, /// We sometimes change the visibility of functions, e.g. `entry` is marked @@ -195,7 +201,7 @@ pub enum UnannotatedExp_ { Builtin(Box, Box), Vector(Loc, usize, Box, Box), - IfElse(Box, Box, Box), + IfElse(Box, Box, Option>), Match(Box, Spanned>), VariantMatch( Box, @@ -340,6 +346,37 @@ impl BuiltinFunction_ { } } +impl Exp { + pub fn is_unit(&self, diags: &DiagnosticReporter) -> bool { + self.exp.value.is_unit(diags, self.exp.loc) + } +} + +impl UnannotatedExp_ { + #[growing_stack] + pub fn is_unit(&self, diags: &DiagnosticReporter, loc: Loc) -> bool { + match &self { + Self::Unit { .. } => true, + Self::Annotate(inner, _) => inner.is_unit(diags), + Self::Block((_, seq)) if seq.is_empty() => { + diags.add_diag(ice!((loc, "Unexpected empty block without a value"))); + false + } + Self::Block((_, seq)) if seq.len() == 1 => seq[0].value.is_unit(diags), + _ => false, + } + } +} + +impl SequenceItem_ { + pub fn is_unit(&self, diags: &DiagnosticReporter) -> bool { + match &self { + Self::Seq(e) => e.is_unit(diags), + Self::Declare(_) | Self::Bind(_, _, _) => false, + } + } +} + pub fn explist(loc: Loc, mut es: Vec) -> Exp { match es.len() { 0 => { @@ -366,24 +403,29 @@ pub fn single_item(e: Exp) -> ExpListItem { ExpListItem::Single(e, ty) } -pub fn splat_item(env: &mut CompilationEnv, splat_loc: Loc, e: Exp) -> ExpListItem { - let ss = match &e.ty { - sp!(_, Type_::Unit) => vec![], - sp!(_, Type_::Apply(_, sp!(_, TypeName_::Multiple(_)), ss)) => ss.clone(), - _ => { - let mut diag = ice!((splat_loc, "ICE called `splat_item` on a non-list type")); - diag.add_note(format!("Expression: {}", debug_display!(e))); - env.add_diag(diag); - vec![] - } - }; - ExpListItem::Splat(splat_loc, e, ss) -} - pub fn pat(ty: Type, pat: UnannotatedPat) -> MatchPattern { MatchPattern { ty, pat } } +impl ModuleCall { + pub fn is( + &self, + address: &Addr, + module: impl AsRef, + function: impl AsRef, + ) -> bool + where + NumericalAddress: PartialEq, + { + let Self { + module: sp!(_, mident), + name: f, + .. + } = self; + mident.is(address, module) && f == function.as_ref() + } +} + //************************************************************************************************** // Display //************************************************************************************************** @@ -400,10 +442,14 @@ impl fmt::Display for BuiltinFunction_ { impl AstDebug for Program { fn ast_debug(&self, w: &mut AstWriter) { - let Program { modules, info: _ } = self; + let Program { + modules, + info: _, + warning_filters_table: _, + } = self; for (m, mdef) in modules.key_cloned_iter() { - w.write(&format!("module {}", m)); + w.write(format!("module {}", m)); w.block(|w| mdef.ast_debug(w)); w.new_line(); } @@ -431,7 +477,7 @@ impl AstDebug for ModuleDefinition { } = self; warning_filter.ast_debug(w); if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); w.writeln(match target_kind { @@ -443,20 +489,20 @@ impl AstDebug for ModuleDefinition { } => "dependency module", TargetKind::External => "external module", }); - w.writeln(&format!("dependency order #{}", dependency_order)); + w.writeln(format!("dependency order #{}", dependency_order)); for (mident, neighbor) in immediate_neighbors.key_cloned_iter() { - w.write(&format!("{mident} is")); + w.write(format!("{mident} is")); neighbor.ast_debug(w); w.writeln(";"); } for addr in used_addresses { - w.write(&format!("uses address {};", addr)); + w.write(format!("uses address {};", addr)); w.new_line() } use_funs.ast_debug(w); syntax_methods.ast_debug(w); for (mident, _loc) in friends.key_cloned_iter() { - w.write(&format!("friend {};", mident)); + w.write(format!("friend {};", mident)); w.new_line(); } for sdef in structs.key_cloned_iter() { @@ -486,6 +532,7 @@ impl AstDebug for (FunctionName, &Function) { warning_filter, index, attributes, + loc: _, visibility, compiled_visibility, entry, @@ -502,15 +549,15 @@ impl AstDebug for (FunctionName, &Function) { compiled_visibility.ast_debug(w); w.write(") "); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if macro_.is_some() { - w.write(&format!("{} ", MACRO_MODIFIER)); + w.write(format!("{} ", MACRO_MODIFIER)); } if let FunctionBody_::Native = &body.value { - w.write(&format!("{} ", NATIVE_MODIFIER)); + w.write(format!("{} ", NATIVE_MODIFIER)); } - w.write(&format!("fun#{index} {name}")); + w.write(format!("fun#{index} {name}")); signature.ast_debug(w); body.ast_debug(w); } @@ -541,7 +588,7 @@ impl AstDebug for (ConstantName, &Constant) { ) = self; warning_filter.ast_debug(w); attributes.ast_debug(w); - w.write(&format!("const#{index} {name}:")); + w.write(format!("const#{index} {name}:")); signature.ast_debug(w); w.write(" = "); value.ast_debug(w); @@ -622,7 +669,7 @@ impl AstDebug for UnannotatedExp_ { w.write("use@"); v.ast_debug(w) } - E::Constant(m, c) => w.write(&format!("{}::{}", m, c)), + E::Constant(m, c) => w.write(format!("{}::{}", m, c)), E::ModuleCall(mcall) => { mcall.ast_debug(w); } @@ -642,14 +689,14 @@ impl AstDebug for UnannotatedExp_ { w.write("]"); } E::Pack(m, s, tys, fields) => { - w.write(&format!("{}::{}", m, s)); + w.write(format!("{}::{}", m, s)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_e)| { let (idx, (bt, e)) = idx_bt_e; - w.write(&format!("({}#{}:", idx, f)); + w.write(format!("({}#{}:", idx, f)); bt.ast_debug(w); w.write("): "); e.ast_debug(w); @@ -657,27 +704,29 @@ impl AstDebug for UnannotatedExp_ { w.write("}"); } E::PackVariant(m, e, v, tys, fields) => { - w.write(&format!("{}::{}::{}", m, e, v)); + w.write(format!("{}::{}::{}", m, e, v)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_e)| { let (idx, (bt, e)) = idx_bt_e; - w.write(&format!("({}#{}:", idx, f)); + w.write(format!("({}#{}:", idx, f)); bt.ast_debug(w); w.write("): "); e.ast_debug(w); }); w.write("}"); } - E::IfElse(b, t, f) => { + E::IfElse(b, t, f_opt) => { w.write("if ("); b.ast_debug(w); w.write(") "); t.ast_debug(w); - w.write(" else "); - f.ast_debug(w); + if let Some(f) = f_opt { + w.write(" else "); + f.ast_debug(w); + } } E::Match(esubject, arms) => { w.write("match ("); @@ -796,7 +845,7 @@ impl AstDebug for UnannotatedExp_ { w.write("mut "); } e.ast_debug(w); - w.write(&format!(".{}", f)); + w.write(format!(".{}", f)); } E::TempBorrow(mut_, e) => { w.write("&"); @@ -833,7 +882,7 @@ impl AstDebug for UnannotatedExp_ { } => { w.write("ErrorConstant"); if let Some(c) = error_constant { - w.write(&format!("({})", c)) + w.write(format!("({})", c)) } } } @@ -857,7 +906,7 @@ impl AstDebug for ModuleCall { arguments, method_name: _, } = self; - w.write(&format!("{}::{}", module, name)); + w.write(format!("{}::{}", module, name)); if !parameter_types.is_empty() { w.write("["); if !parameter_types.is_empty() { @@ -932,28 +981,28 @@ impl AstDebug for UnannotatedPat_ { if *mut_ { w.write("mut "); } - w.write(&format!("{}::{}::{}", m, e, v)); + w.write(format!("{}::{}::{}", m, e, v)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); w.write("}"); } UnannotatedPat_::Variant(m, e, v, tys, fields) => { - w.write(&format!("{}::{}::{}", m, e, v)); + w.write(format!("{}::{}::{}", m, e, v)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); @@ -964,35 +1013,35 @@ impl AstDebug for UnannotatedPat_ { if *mut_ { w.write("mut "); } - w.write(&format!("{}::{}", m, s)); + w.write(format!("{}::{}", m, s)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); w.write("}"); } UnannotatedPat_::Struct(m, e, tys, fields) => { - w.write(&format!("{}::{}", m, e)); + w.write(format!("{}::{}", m, e)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); w.write("}"); } UnannotatedPat_::Constant(m, c) => { - w.write(&format!("{}::{}", m, c)); + w.write(format!("{}::{}", m, c)); } UnannotatedPat_::Or(lhs, rhs) => { w.write("("); @@ -1062,14 +1111,14 @@ impl AstDebug for LValue_ { st, ), L::Unpack(m, s, tys, fields) => { - w.write(&format!("{}::{}", m, s)); + w.write(format!("{}::{}", m, s)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); @@ -1080,28 +1129,28 @@ impl AstDebug for LValue_ { if *mut_ { w.write("mut "); } - w.write(&format!("{}::{}", m, s)); + w.write(format!("{}::{}", m, s)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); w.write("}"); } L::UnpackVariant(m, e, v, tys, fields) => { - w.write(&format!("{}::{}::{}", m, e, v)); + w.write(format!("{}::{}::{}", m, e, v)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); @@ -1112,14 +1161,14 @@ impl AstDebug for LValue_ { if *mut_ { w.write("mut "); } - w.write(&format!("{}::{}::{}", m, e, v)); + w.write(format!("{}::{}::{}", m, e, v)); w.write("<"); tys.ast_debug(w); w.write(">"); w.write("{"); w.comma(fields, |w, (_, f, idx_bt_a)| { let (idx, (bt, a)) = idx_bt_a; - w.annotate(|w| w.write(&format!("{}#{}", idx, f)), bt); + w.annotate(|w| w.write(format!("{}#{}", idx, f)), bt); w.write(": "); a.ast_debug(w); }); diff --git a/external-crates/move/crates/move-compiler/src/typing/core.rs b/external-crates/move/crates/move-compiler/src/typing/core.rs index bf4f5560509..f3ea25638ed 100644 --- a/external-crates/move/crates/move-compiler/src/typing/core.rs +++ b/external-crates/move/crates/move-compiler/src/typing/core.rs @@ -17,7 +17,8 @@ use crate::{ debug_display, diag, diagnostics::{ codes::{NameResolution, TypeSafety}, - Diagnostic, + warning_filters::WarningFilters, + Diagnostic, DiagnosticReporter, Diagnostics, }, editions::FeatureGate, expansion::ast::{AbilitySet, ModuleIdent, ModuleIdent_, Mutability, Visibility}, @@ -85,16 +86,26 @@ pub enum MacroExpansion { } pub(super) struct TypingDebugFlags { + #[allow(dead_code)] pub(super) match_counterexample: bool, + #[allow(dead_code)] pub(super) autocomplete_resolution: bool, + #[allow(dead_code)] pub(super) function_translation: bool, + #[allow(dead_code)] pub(super) type_elaboration: bool, } +pub struct TVarCounter { + next: u64, +} + pub struct Context<'env> { pub modules: NamingProgramInfo, macros: UniqueMap>, - pub env: &'env mut CompilationEnv, + pub env: &'env CompilationEnv, + pub reporter: DiagnosticReporter<'env>, + #[allow(dead_code)] pub(super) debug: TypingDebugFlags, deprecations: Deprecations, @@ -111,6 +122,7 @@ pub struct Context<'env> { pub return_type: Option, locals: UniqueMap, + pub tvar_counter: TVarCounter, pub subst: Subst, pub constraints: Constraints, @@ -185,7 +197,7 @@ impl UseFunsScope { impl<'env> Context<'env> { pub fn new( - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, _pre_compiled_lib: Option>, info: NamingProgramInfo, ) -> Self { @@ -197,8 +209,10 @@ impl<'env> Context<'env> { function_translation: false, type_elaboration: false, }; + let reporter = env.diagnostic_reporter_at_top_level(); Context { use_funs: vec![global_use_funs], + tvar_counter: TVarCounter::new(), subst: Subst::empty(), current_package: None, current_module: None, @@ -212,6 +226,7 @@ impl<'env> Context<'env> { macros: UniqueMap::new(), named_block_map: BTreeMap::new(), env, + reporter, debug, next_match_var_id: 0, new_friends: BTreeSet::new(), @@ -223,6 +238,35 @@ impl<'env> Context<'env> { } } + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + pub fn extend_ide_info(&self, info: IDEInfo) { + self.reporter.extend_ide_info(info); + } + + pub fn add_ide_annotation(&self, loc: Loc, info: IDEAnnotation) { + self.reporter.add_ide_annotation(loc, info); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + + pub fn check_feature(&self, package: Option, feature: FeatureGate, loc: Loc) -> bool { + self.env + .check_feature(&self.reporter, package, feature, loc) + } + pub fn set_macros( &mut self, macros: UniqueMap>, @@ -272,7 +316,7 @@ impl<'env> Context<'env> { let (target_m, target_f) = &use_fun.target_function; let msg = format!("{case} method alias '{tn}.{method}' for '{target_m}::{target_f}'"); - self.env.add_diag(diag!( + self.add_diag(diag!( Declarations::DuplicateAlias, (use_fun.loc, msg), (prev_loc, "The same alias was previously declared here") @@ -312,18 +356,18 @@ impl<'env> Context<'env> { UseFunKind::Explicit => { let msg = format!("Unused 'use fun' of '{tn}.{method}'. Consider removing it"); - self.env.add_diag(diag!(UnusedItem::Alias, (*loc, msg))) + self.add_diag(diag!(UnusedItem::Alias, (*loc, msg))) } UseFunKind::UseAlias => { let msg = format!("Unused 'use' of alias '{method}'. Consider removing it"); - self.env.add_diag(diag!(UnusedItem::Alias, (*loc, msg))) + self.add_diag(diag!(UnusedItem::Alias, (*loc, msg))) } UseFunKind::FunctionDeclaration => { let diag = ice!(( *loc, "ICE fun declaration 'use' funs should never be added to 'use' funs" )); - self.env.add_diag(diag); + self.add_diag(diag); } } } @@ -418,7 +462,7 @@ impl<'env> Context<'env> { }; diag.add_secondary_label((*prev_loc, msg)); } - self.env.add_diag(diag); + self.add_diag(diag); false } else { self.macro_expansion @@ -440,7 +484,7 @@ impl<'env> Context<'env> { loc, "ICE macro expansion stack should have a call when leaving a macro expansion" )); - self.env.add_diag(diag); + self.add_diag(diag); return false; } }; @@ -478,7 +522,7 @@ impl<'env> Context<'env> { loc, "ICE macro expansion stack should have a lambda when leaving a lambda", )); - self.env.add_diag(diag); + self.add_diag(diag); } } } @@ -506,6 +550,7 @@ impl<'env> Context<'env> { self.return_type = None; self.locals = UniqueMap::new(); self.subst = Subst::empty(); + self.tvar_counter = TVarCounter::new(); self.constraints = Constraints::new(); self.current_function = None; self.in_macro_function = false; @@ -514,8 +559,7 @@ impl<'env> Context<'env> { self.lambda_expansion = vec![]; if !self.ide_info.is_empty() { - self.env - .add_diag(ice!((loc, "IDE info should be cleared after each item"))); + self.add_diag(ice!((loc, "IDE info should be cleared after each item"))); self.ide_info = IDEInfo::new(); } } @@ -582,15 +626,14 @@ impl<'env> Context<'env> { pub fn declare_local(&mut self, _: Mutability, var: Var, ty: Type) { if let Err((_, prev_loc)) = self.locals.add(var, ty) { let msg = format!("ICE duplicate {var:?}. Should have been made unique in naming"); - self.env - .add_diag(ice!((var.loc, msg), (prev_loc, "Previously declared here"))); + self.add_diag(ice!((var.loc, msg), (prev_loc, "Previously declared here"))); } } pub fn get_local_type(&mut self, var: &Var) -> Type { if !self.locals.contains_key(var) { let msg = format!("ICE unbound {var:?}. Should have failed in naming"); - self.env.add_diag(ice!((var.loc, msg))); + self.add_diag(ice!((var.loc, msg))); return self.error_type(var.loc); } @@ -667,7 +710,8 @@ impl<'env> Context<'env> { if deprecation.location == AttributePosition::Module && in_same_module { return; } - deprecation.emit_deprecation_warning(self.env, name, method_opt); + let diags = deprecation.deprecation_warnings(name, method_opt); + self.add_diags(diags); } } @@ -858,12 +902,12 @@ impl<'env> Context<'env> { } impl MatchContext for Context<'_> { - fn env(&mut self) -> &mut CompilationEnv { + fn env(&self) -> &CompilationEnv { self.env } - fn env_ref(&self) -> &CompilationEnv { - self.env + fn reporter(&self) -> &DiagnosticReporter { + &self.reporter } /// Makes a new `naming/ast.rs` variable. Does _not_ record it as a function @@ -899,6 +943,19 @@ impl MacroExpansion { } } +impl TVarCounter { + pub fn new() -> Self { + TVarCounter { next: 0 } + } + + #[allow(clippy::should_implement_trait)] + pub fn next(&mut self) -> TVar { + let id = self.next; + self.next += 1; + TVar(id) + } +} + //************************************************************************************************** // Subst //************************************************************************************************** @@ -925,8 +982,8 @@ impl Subst { self.tvars.get(&tvar) } - pub fn new_num_var(&mut self, loc: Loc) -> TVar { - let tvar = TVar::next(); + pub fn new_num_var(&mut self, counter: &mut TVarCounter, loc: Loc) -> TVar { + let tvar = counter.next(); assert!(self.num_vars.insert(tvar, loc).is_none()); tvar } @@ -953,7 +1010,7 @@ impl ast_debug::AstDebug for Subst { let mut tvars = tvars.iter().collect::>(); tvars.sort_by_key(|(v, _)| *v); for (tvar, bt) in tvars { - w.write(&format!("{:?} => ", tvar)); + w.write(format!("{:?} => ", tvar)); bt.ast_debug(w); w.new_line(); } @@ -963,7 +1020,7 @@ impl ast_debug::AstDebug for Subst { let mut num_vars = num_vars.keys().collect::>(); num_vars.sort(); for tvar in num_vars { - w.writeln(&format!("{:?}", tvar)) + w.writeln(format!("{:?}", tvar)) } }) } @@ -1110,7 +1167,7 @@ fn debug_abilities_info(context: &mut Context, ty: &Type) -> (Option, Abili loc, "ICE did not call unfold_type before debug_abiliites_info" )); - context.env.add_diag(diag); + context.add_diag(diag); (None, AbilitySet::all(loc), vec![]) } T::UnresolvedError | T::Anything => (None, AbilitySet::all(loc), vec![]), @@ -1144,12 +1201,12 @@ fn debug_abilities_info(context: &mut Context, ty: &Type) -> (Option, Abili } pub fn make_num_tvar(context: &mut Context, loc: Loc) -> Type { - let tvar = context.subst.new_num_var(loc); + let tvar = context.subst.new_num_var(&mut context.tvar_counter, loc); sp(loc, Type_::Var(tvar)) } -pub fn make_tvar(_context: &mut Context, loc: Loc) -> Type { - sp(loc, Type_::Var(TVar::next())) +pub fn make_tvar(context: &mut Context, loc: Loc) -> Type { + sp(loc, Type_::Var(context.tvar_counter.next())) } //************************************************************************************************** @@ -1246,7 +1303,7 @@ pub fn make_struct_field_type( N::StructFields::Native(nloc) => { let nloc = *nloc; let msg = format!("Unbound field '{}' for native struct '{}::{}'", field, m, n); - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundField, (loc, msg), (nloc, "Struct declared 'native' here") @@ -1257,7 +1314,7 @@ pub fn make_struct_field_type( }; match fields_map.get(field).cloned() { None => { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundField, (loc, format!("Unbound field '{}' in '{}::{}'", field, m, n)), )); @@ -1372,7 +1429,7 @@ pub fn make_constant_type( let msg = format!("Invalid access of '{}::{}'", m, c); let internal_msg = "Constants are internal to their module, and cannot can be accessed \ outside of their module"; - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::Visibility, (loc, msg), (defined_loc, internal_msg) @@ -1404,7 +1461,7 @@ pub fn make_method_call_type( loc, format!("ICE method on tuple type {}", debug_display!(tn)) )); - context.env.add_diag(diag); + context.add_diag(diag); return None; } TypeName_::Builtin(sp!(_, bt_)) => context.env.primitive_definer(*bt_), @@ -1441,7 +1498,7 @@ pub fn make_method_call_type( No known method '{method}' on type '{lhs_ty_str}'" ); let fmsg = format!("The function '{m}::{method}' exists, {arg_msg}"); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidMethodCall, (loc, msg), (first_ty_loc, fmsg) @@ -1459,7 +1516,7 @@ pub fn make_method_call_type( }; let fmsg = format!("No local 'use fun' alias was found for '{lhs_ty_str}.{method}'{decl_msg}"); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidMethodCall, (loc, msg), (method.loc, fmsg) @@ -1749,7 +1806,7 @@ fn report_visibility_error_( diag.add_secondary_label((call.invocation, "While expanding this macro")); } _ => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( call_loc, "Error when dealing with macro visibilities" ))); @@ -1762,7 +1819,7 @@ fn report_visibility_error_( "Visibility inside of expanded macros is resolved in the scope of the caller.", ); } - context.env.add_diag(diag); + context.add_diag(diag); } pub fn check_call_arity S>( @@ -1787,7 +1844,7 @@ pub fn check_call_arity S>( arity, given_len ); - context.env.add_diag(diag!( + context.add_diag(diag!( code, (loc, cmsg), (argloc, format!("Found {} argument(s) here", given_len)), @@ -1806,7 +1863,9 @@ pub fn solve_constraints(context: &mut Context) { let tvar = sp(loc, Type_::Var(num_var)); match unfold_type(&subst, tvar.clone()).value { Type_::UnresolvedError | Type_::Anything => { - let next_subst = join(subst, &Type_::u64(loc), &tvar).unwrap().0; + let next_subst = join(&mut context.tvar_counter, subst, &Type_::u64(loc), &tvar) + .unwrap() + .0; subst = next_subst; } _ => (), @@ -1883,7 +1942,7 @@ fn solve_ability_constraint( format!("'{}' constraint declared here", constraint), )); } - context.env.add_diag(diag) + context.add_diag(diag) } } @@ -1983,7 +2042,7 @@ fn solve_builtin_type_constraint( } _ => { let tmsg = mk_tmsg(); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::BuiltinOperation, (loc, format!("Invalid argument to '{}'", op)), (tloc, tmsg) @@ -2001,7 +2060,7 @@ fn solve_base_type_constraint(context: &mut Context, loc: Loc, msg: String, ty: Unit | Ref(_, _) | Apply(_, sp!(_, Multiple(_)), _) => { let tystr = error_format(ty, &context.subst); let tmsg = format!("Expected a single non-reference type, but found: {}", tystr); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::ExpectedBaseType, (loc, msg), (tyloc, tmsg) @@ -2022,7 +2081,7 @@ fn solve_single_type_constraint(context: &mut Context, loc: Loc, msg: String, ty "Expected a single type, but found expression list type: {}", error_format(ty, &context.subst) ); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::ExpectedSingleType, (loc, msg), (tyloc, tmsg) @@ -2347,7 +2406,9 @@ fn instantiate_type_args_impl( .zip(ty_args) .fold(subst, |subst, (tvar, ty_arg)| { // tvar is just a type variable, so shouldn't throw ever... - let (subst, t) = join(subst, &tvar, &ty_arg).ok().unwrap(); + let (subst, t) = join(&mut context.tvar_counter, subst, &tvar, &ty_arg) + .ok() + .unwrap(); res.push(t); subst }); @@ -2375,7 +2436,7 @@ fn check_type_argument_arity String>( arity, args_len ); - context.env.add_diag(diag!(code, (loc, msg))); + context.add_diag(diag!(code, (loc, msg))); } while ty_args.len() > arity { @@ -2466,19 +2527,35 @@ enum TypingCase { Subtype, } -pub fn subtype(subst: Subst, lhs: &Type, rhs: &Type) -> Result<(Subst, Type), TypingError> { - join_impl(subst, TypingCase::Subtype, lhs, rhs) +pub fn subtype( + counter: &mut TVarCounter, + subst: Subst, + lhs: &Type, + rhs: &Type, +) -> Result<(Subst, Type), TypingError> { + join_impl(counter, subst, TypingCase::Subtype, lhs, rhs) } -pub fn join(subst: Subst, lhs: &Type, rhs: &Type) -> Result<(Subst, Type), TypingError> { - join_impl(subst, TypingCase::Join, lhs, rhs) +pub fn join( + counter: &mut TVarCounter, + subst: Subst, + lhs: &Type, + rhs: &Type, +) -> Result<(Subst, Type), TypingError> { + join_impl(counter, subst, TypingCase::Join, lhs, rhs) } -pub fn invariant(subst: Subst, lhs: &Type, rhs: &Type) -> Result<(Subst, Type), TypingError> { - join_impl(subst, TypingCase::Invariant, lhs, rhs) +pub fn invariant( + counter: &mut TVarCounter, + subst: Subst, + lhs: &Type, + rhs: &Type, +) -> Result<(Subst, Type), TypingError> { + join_impl(counter, subst, TypingCase::Invariant, lhs, rhs) } fn join_impl( + counter: &mut TVarCounter, mut subst: Subst, case: TypingCase, lhs: &Type, @@ -2519,7 +2596,7 @@ fn join_impl( )); } }; - let (subst, t) = join_impl(subst, case, t1, t2)?; + let (subst, t) = join_impl(counter, subst, case, t1, t2)?; Ok((subst, sp(loc, Ref(mut_, Box::new(t))))) } (sp!(_, Param(TParam { id: id1, .. })), sp!(_, Param(TParam { id: id2, .. }))) @@ -2546,7 +2623,7 @@ fn join_impl( k1, k2 ); - let (subst, tys) = join_impl_types(subst, case, tys1, tys2)?; + let (subst, tys) = join_impl_types(counter, subst, case, tys1, tys2)?; Ok((subst, sp(*loc, Apply(k2.clone(), n2.clone(), tys)))) } (sp!(_, Fun(a1, _)), sp!(_, Fun(a2, _))) if a1.len() != a2.len() => { @@ -2561,17 +2638,17 @@ fn join_impl( // TODO this is going to likely lead to some strange error locations/messages // since the RHS in subtyping is currently assumed to be an annotation let (subst, args) = match case { - Join | Invariant => join_impl_types(subst, case, a1, a2)?, - Subtype => join_impl_types(subst, case, a2, a1)?, + Join | Invariant => join_impl_types(counter, subst, case, a1, a2)?, + Subtype => join_impl_types(counter, subst, case, a2, a1)?, }; - let (subst, result) = join_impl(subst, case, r1, r2)?; + let (subst, result) = join_impl(counter, subst, case, r1, r2)?; Ok((subst, sp(*loc, Fun(args, Box::new(result))))) } (sp!(loc1, Var(id1)), sp!(loc2, Var(id2))) => { if *id1 == *id2 { Ok((subst, sp(*loc2, Var(*id2)))) } else { - join_tvar(subst, case, *loc1, *id1, *loc2, *id2) + join_tvar(counter, subst, case, *loc1, *id1, *loc2, *id2) } } (sp!(loc, Var(id)), other) if subst.get(*id).is_none() => { @@ -2595,14 +2672,14 @@ fn join_impl( } } (sp!(loc, Var(id)), other) => { - let new_tvar = TVar::next(); + let new_tvar = counter.next(); subst.insert(new_tvar, other.clone()); - join_tvar(subst, case, *loc, *id, other.loc, new_tvar) + join_tvar(counter, subst, case, *loc, *id, other.loc, new_tvar) } (other, sp!(loc, Var(id))) => { - let new_tvar = TVar::next(); + let new_tvar = counter.next(); subst.insert(new_tvar, other.clone()); - join_tvar(subst, case, other.loc, new_tvar, *loc, *id) + join_tvar(counter, subst, case, other.loc, new_tvar, *loc, *id) } (sp!(_, UnresolvedError), other) | (other, sp!(_, UnresolvedError)) => { @@ -2616,6 +2693,7 @@ fn join_impl( } fn join_impl_types( + counter: &mut TVarCounter, mut subst: Subst, case: TypingCase, tys1: &[Type], @@ -2625,7 +2703,7 @@ fn join_impl_types( // elsewhere as all types are instantiated as a sanity check let mut tys = vec![]; for (ty1, ty2) in tys1.iter().zip(tys2) { - let (nsubst, t) = join_impl(subst, case, ty1, ty2)?; + let (nsubst, t) = join_impl(counter, subst, case, ty1, ty2)?; subst = nsubst; tys.push(t) } @@ -2633,6 +2711,7 @@ fn join_impl_types( } fn join_tvar( + counter: &mut TVarCounter, mut subst: Subst, case: TypingCase, loc1: Loc, @@ -2652,7 +2731,7 @@ fn join_tvar( Some(t) => t.clone(), }; - let new_tvar = TVar::next(); + let new_tvar = counter.next(); let num_loc_1 = subst.num_vars.get(&last_id1); let num_loc_2 = subst.num_vars.get(&last_id2); match (num_loc_1, num_loc_2) { @@ -2665,7 +2744,7 @@ fn join_tvar( subst.insert(last_id1, sp(loc1, Var(new_tvar))); subst.insert(last_id2, sp(loc2, Var(new_tvar))); - let (mut subst, new_ty) = join_impl(subst, case, &ty1, &ty2)?; + let (mut subst, new_ty) = join_impl(counter, subst, case, &ty1, &ty2)?; match subst.get(new_tvar) { Some(sp!(tloc, _)) => Err(TypingError::RecursiveType(*tloc)), None => { diff --git a/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs b/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs index 96afdd29bc2..6bb37861523 100644 --- a/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs +++ b/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs @@ -10,7 +10,7 @@ use move_proc_macros::growing_stack; use petgraph::{algo::toposort as petgraph_toposort, graphmap::DiGraphMap}; use crate::{ - diagnostics::{codes::*, Diagnostic}, + diagnostics::{codes::*, Diagnostic, DiagnosticReporter}, expansion::ast::{Address, ModuleIdent, Value_}, ice, naming::ast::{self as N, Neighbor, Neighbor_}, @@ -23,7 +23,7 @@ use crate::{ //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, modules: &mut UniqueMap, ) { let imm_modules = &modules; @@ -41,7 +41,7 @@ pub fn program( Err(cycle_node) => { let cycle_ident = *cycle_node.node_id(); let error = cycle_error(&module_neighbors, cycle_ident); - compilation_env.add_diag(error); + context.reporter.add_diag(error); } Ok(ordered_ids) => { for (order, mident) in ordered_ids.iter().rev().enumerate() { @@ -66,7 +66,9 @@ enum DepType { } struct Context<'a, 'env> { - env: &'env mut CompilationEnv, + #[allow(unused)] + env: &'env CompilationEnv, + reporter: DiagnosticReporter<'env>, modules: &'a UniqueMap, // A union of uses and friends for modules (used for cyclyc dependency checking) // - if A uses B, add edge A -> B @@ -82,11 +84,13 @@ struct Context<'a, 'env> { impl<'a, 'env> Context<'a, 'env> { fn new( - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, modules: &'a UniqueMap, ) -> Self { + let reporter = env.diagnostic_reporter_at_top_level(); Context { env, + reporter, modules, module_neighbors: BTreeMap::new(), neighbors_by_node: BTreeMap::new(), @@ -375,7 +379,7 @@ fn lvalue(context: &mut Context, sp!(loc, lv_): &T::LValue) { } } L::BorrowUnpackVariant(..) | L::UnpackVariant(..) => { - context.env.add_diag(ice!(( + context.reporter.add_diag(ice!(( *loc, "variant unpacking shouldn't occur before match expansion" ))); @@ -405,10 +409,12 @@ fn exp(context: &mut Context, e: &T::Exp) { type_(context, ty); exp(context, e); } - E::IfElse(e1, e2, e3) => { + E::IfElse(e1, e2, e3_opt) => { exp(context, e1); exp(context, e2); - exp(context, e3); + if let Some(e3) = e3_opt { + exp(context, e3); + } } E::Match(esubject, arms) => { exp(context, esubject); @@ -421,7 +427,7 @@ fn exp(context: &mut Context, e: &T::Exp) { } } E::VariantMatch(..) => { - context.env.add_diag(ice!(( + context.reporter.add_diag(ice!(( e.exp.loc, "shouldn't find variant match before HLIR lowering" ))); diff --git a/external-crates/move/crates/move-compiler/src/typing/deprecation_warnings.rs b/external-crates/move/crates/move-compiler/src/typing/deprecation_warnings.rs index 00f5a079751..284458c634d 100644 --- a/external-crates/move/crates/move-compiler/src/typing/deprecation_warnings.rs +++ b/external-crates/move/crates/move-compiler/src/typing/deprecation_warnings.rs @@ -4,6 +4,7 @@ use crate::{ diag, + diagnostics::{DiagnosticReporter, Diagnostics}, expansion::ast::{self as E, ModuleIdent}, ice, shared::{ @@ -44,12 +45,13 @@ pub struct Deprecations { impl Deprecations { /// Index the modules and their members for deprecation attributes and register each /// deprecation attribute for use later on. - pub fn new(env: &mut CompilationEnv, info: &NamingProgramInfo) -> Self { + pub fn new(env: &CompilationEnv, info: &NamingProgramInfo) -> Self { let mut deprecated_members = HashMap::new(); + let reporter = env.diagnostic_reporter_at_top_level(); for (mident, module_info) in info.modules.key_cloned_iter() { if let Some(deprecation) = deprecations( - env, + &reporter, AttributePosition::Module, &module_info.attributes, mident.loc, @@ -60,7 +62,7 @@ impl Deprecations { for (name, constant) in module_info.constants.key_cloned_iter() { if let Some(deprecation) = deprecations( - env, + &reporter, AttributePosition::Constant, &constant.attributes, name.0.loc, @@ -72,7 +74,7 @@ impl Deprecations { for (name, function) in module_info.functions.key_cloned_iter() { if let Some(deprecation) = deprecations( - env, + &reporter, AttributePosition::Function, &function.attributes, name.0.loc, @@ -84,7 +86,7 @@ impl Deprecations { for (name, datatype) in module_info.structs.key_cloned_iter() { if let Some(deprecation) = deprecations( - env, + &reporter, AttributePosition::Struct, &datatype.attributes, name.0.loc, @@ -96,7 +98,7 @@ impl Deprecations { for (name, datatype) in module_info.enums.key_cloned_iter() { if let Some(deprecation) = deprecations( - env, + &reporter, AttributePosition::Enum, &datatype.attributes, name.0.loc, @@ -121,12 +123,7 @@ impl Deprecations { impl Deprecation { /// Emit a warning for the deprecation of a module member. - pub fn emit_deprecation_warning( - &self, - env: &mut CompilationEnv, - member_name: Name, - method_opt: Option, - ) { + pub fn deprecation_warnings(&self, member_name: Name, method_opt: Option) -> Diagnostics { let mident_string = self.module_ident.to_string(); let location_string = match (self.location, method_opt) { (AttributePosition::Module, None) => { @@ -160,7 +157,10 @@ impl Deprecation { let location = method_opt.map_or(member_name.loc, |method| method.loc); - env.add_diag(diag!(TypeSafety::DeprecatedUsage, (location, message))); + Diagnostics::from(vec![diag!( + TypeSafety::DeprecatedUsage, + (location, message) + )]) } } @@ -169,7 +169,7 @@ impl Deprecation { // #[deprecated] attributes (malformed, or multiple on the member), add an error diagnostic to // `env` and return None. fn deprecations( - env: &mut CompilationEnv, + reporter: &DiagnosticReporter, attr_position: AttributePosition, attrs: &E::Attributes, source_location: Loc, @@ -185,7 +185,7 @@ fn deprecations( } if deprecations.len() != 1 { - env.add_diag(ice!(( + reporter.add_diag(ice!(( source_location, "ICE: verified that there is at at least one deprecation attribute above, \ and expansion should have failed if there were multiple deprecation attributes." @@ -197,7 +197,7 @@ fn deprecations( .last() .expect("Verified deprecations is not empty above"); - let mut make_invalid_deprecation_diag = || { + let make_invalid_deprecation_diag = || { let mut diag = diag!( Attributes::InvalidUsage, ( @@ -210,7 +210,7 @@ fn deprecations( DeprecationAttribute.name() ); diag.add_note(note); - env.add_diag(diag); + reporter.add_diag(diag); None }; diff --git a/external-crates/move/crates/move-compiler/src/typing/expand.rs b/external-crates/move/crates/move-compiler/src/typing/expand.rs index d8a4496f1a2..5de3f1ef647 100644 --- a/external-crates/move/crates/move-compiler/src/typing/expand.rs +++ b/external-crates/move/crates/move-compiler/src/typing/expand.rs @@ -10,7 +10,7 @@ use crate::{ ice, naming::ast::{BuiltinTypeName_, FunctionSignature, Type, TypeName_, Type_}, parser::ast::Ability_, - shared::{ide::IDEAnnotation, string_utils::debug_print, AstDebug}, + shared::{ide::IDEAnnotation, string_utils::debug_print}, typing::{ ast::{self as T}, core::{self, Context}, @@ -70,14 +70,12 @@ pub fn type_(context: &mut Context, ty: &mut Type) { ty.loc, "ICE unfold_type_base failed to expand type inf. var" )); - context.env.add_diag(diag); + context.add_diag(diag); sp(loc, UnresolvedError) } sp!(loc, Anything) => { let msg = "Could not infer this type. Try adding an annotation"; - context - .env - .add_diag(diag!(TypeSafety::UninferredType, (ty.loc, msg))); + context.add_diag(diag!(TypeSafety::UninferredType, (ty.loc, msg))); sp(loc, UnresolvedError) } sp!(loc, Fun(_, _)) if !context.in_macro_function => { @@ -97,7 +95,7 @@ pub fn type_(context: &mut Context, ty: &mut Type) { ty.loc, format!("ICE expanding pre-expanded type {}", debug_display!(aty)) )); - context.env.add_diag(diag); + context.add_diag(diag); *ty = sp(ty.loc, UnresolvedError) } Apply(None, _, _) => { @@ -109,7 +107,7 @@ pub fn type_(context: &mut Context, ty: &mut Type) { } _ => { let diag = ice!((ty.loc, "ICE type-apply switched to non-apply")); - context.env.add_diag(diag); + context.add_diag(diag); *ty = sp(ty.loc, UnresolvedError) } } @@ -127,15 +125,10 @@ pub fn type_(context: &mut Context, ty: &mut Type) { } fn unexpected_lambda_type(context: &mut Context, loc: Loc) { - if context - .env - .check_feature(context.current_package, FeatureGate::MacroFuns, loc) - { + if context.check_feature(context.current_package, FeatureGate::MacroFuns, loc) { let msg = "Unexpected lambda type. \ Lambdas can only be used with 'macro' functions, as parameters or direct arguments"; - context - .env - .add_diag(diag!(TypeSafety::UnexpectedFunctionType, (loc, msg))); + context.add_diag(diag!(TypeSafety::UnexpectedFunctionType, (loc, msg))); } } @@ -235,10 +228,12 @@ pub fn exp(context: &mut Context, e: &mut T::Exp) { exp(context, args); } - E::IfElse(eb, et, ef) => { + E::IfElse(eb, et, ef_opt) => { exp(context, eb); exp(context, et); - exp(context, ef); + if let Some(ef) = ef_opt { + exp(context, ef) + } } E::Match(esubject, arms) => { exp(context, esubject); @@ -247,7 +242,7 @@ pub fn exp(context: &mut Context, e: &mut T::Exp) { } } E::VariantMatch(subject, _, arms) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( e.exp.loc, "shouldn't find variant match before match compilation" ))); @@ -356,7 +351,7 @@ fn inferred_numerical_value( "Annotating the literal might help inference: '{value}{type}'", type=fix_bt, ); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidNum, (eloc, "Invalid numerical literal"), (ty.loc, msg), diff --git a/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs b/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs index 579da5f3311..a0b568fe109 100644 --- a/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs +++ b/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs @@ -143,7 +143,7 @@ impl<'a> Context<'a> { //************************************************************************************************** pub fn modules( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, modules: &UniqueMap, ) { let tparams = modules @@ -174,11 +174,12 @@ macro_rules! scc_edges { } fn module<'a>( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, tparams: &'a BTreeMap>>, mname: ModuleIdent, module: &T::ModuleDefinition, ) { + let reporter = compilation_env.diagnostic_reporter_at_top_level(); let context = &mut Context::new(tparams, mname); module .functions @@ -191,7 +192,7 @@ fn module<'a>( petgraph_scc(&graph) .into_iter() .filter(|scc| scc_edges!(&graph, scc).any(|(_, e, _)| e == Edge::Nested)) - .for_each(|scc| compilation_env.add_diag(cycle_error(context, &graph, scc))) + .for_each(|scc| reporter.add_diag(cycle_error(context, &graph, scc))) } //************************************************************************************************** @@ -242,10 +243,12 @@ fn exp(context: &mut Context, e: &T::Exp) { exp(context, &call.arguments) } - E::IfElse(eb, et, ef) => { + E::IfElse(eb, et, ef_opt) => { exp(context, eb); exp(context, et); - exp(context, ef); + if let Some(ef) = ef_opt { + exp(context, ef) + } } E::Match(esubject, arms) => { exp(context, esubject); diff --git a/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs b/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs index e9074431716..5c5537bee73 100644 --- a/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs +++ b/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs @@ -67,7 +67,7 @@ pub(crate) fn call( let reloc_clever_errors = match &context.macro_expansion[0] { core::MacroExpansion::Call(call) => call.invocation, core::MacroExpansion::Argument { .. } => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( call_loc, "ICE top level macro scope should never be an argument" ))); @@ -96,7 +96,7 @@ pub(crate) fn call( return None; } Err(Some(diag)) => { - context.env.add_diag(*diag); + context.add_diag(*diag); return None; } }; @@ -292,9 +292,7 @@ fn bind_lambda( "Unable to bind lambda to parameter '{}'. The lambda must be passed directly", param.name ); - context - .env - .add_diag(diag!(TypeSafety::CannotExpandMacro, (arg.loc, msg))); + context.add_diag(diag!(TypeSafety::CannotExpandMacro, (arg.loc, msg))); None } } @@ -557,10 +555,12 @@ fn recolor_exp(ctx: &mut Recolor, sp!(_, e_): &mut N::Exp) { recolor_lvalues(ctx, lvalues); recolor_exp(ctx, e) } - N::Exp_::IfElse(econd, et, ef) => { + N::Exp_::IfElse(econd, et, ef_opt) => { recolor_exp(ctx, econd); recolor_exp(ctx, et); - recolor_exp(ctx, ef); + if let Some(ef) = ef_opt { + recolor_exp(ctx, ef); + } } N::Exp_::Match(subject, arms) => { recolor_exp(ctx, subject); @@ -648,7 +648,7 @@ fn recolor_exp(ctx: &mut Recolor, sp!(_, e_): &mut N::Exp) { recolor_exp(ctx, e) } } - N::Exp_::MethodCall(ed, _, _, _, sp!(_, es)) => { + N::Exp_::MethodCall(ed, _, _, _, _, sp!(_, es)) => { recolor_exp_dotted(ctx, ed); for e in es { recolor_exp(ctx, e) @@ -686,7 +686,7 @@ fn recolor_exp(ctx: &mut Recolor, sp!(_, e_): &mut N::Exp) { fn recolor_exp_dotted(ctx: &mut Recolor, sp!(_, ed_): &mut N::ExpDotted) { match ed_ { N::ExpDotted_::Exp(e) => recolor_exp(ctx, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { + N::ExpDotted_::Dot(ed, _, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { recolor_exp_dotted(ctx, ed) } N::ExpDotted_::Index(ed, sp!(_, es)) => { @@ -751,9 +751,7 @@ fn report_unused_argument(context: &mut core::Context, loc: EvalStrategy { + N::Exp_::IfElse(econd, et, ef_opt) => { exp(context, econd); exp(context, et); - exp(context, ef); + if let Some(ef) = ef_opt { + exp(context, ef) + } } N::Exp_::Match(subject, arms) => { macro_rules! take_and_mut_replace { @@ -947,7 +947,7 @@ fn exp(context: &mut Context, sp!(eloc, e_): &mut N::Exp) { } exps(context, es) } - N::Exp_::MethodCall(ed, _, _, tys_opt, sp!(_, es)) => { + N::Exp_::MethodCall(ed, _, _, _, tys_opt, sp!(_, es)) => { if let Some(tys) = tys_opt { types(context, tys) } @@ -1069,7 +1069,6 @@ fn exp(context: &mut Context, sp!(eloc, e_): &mut N::Exp) { if context.core.env.ide_mode() { context .core - .env .add_ide_annotation(*eloc, IDEAnnotation::ExpandedLambda); } *e_ = block; @@ -1109,7 +1108,7 @@ fn exp(context: &mut Context, sp!(eloc, e_): &mut N::Exp) { N::Exp_::VarCall(sp!(_, v_), _) if context.by_name_args.contains_key(v_) => { context.mark_used(v_); let (arg, _expected_ty) = context.by_name_args.get(v_).unwrap(); - context.core.env.add_diag(diag!( + context.core.add_diag(diag!( TypeSafety::CannotExpandMacro, (*eloc, "Cannot call non-lambda argument"), (arg.loc, "Expected a lambda argument") @@ -1168,7 +1167,7 @@ fn builtin_function(context: &mut Context, sp!(_, bf_): &mut N::BuiltinFunction) fn exp_dotted(context: &mut Context, sp!(_, ed_): &mut N::ExpDotted) { match ed_ { N::ExpDotted_::Exp(e) => exp(context, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { + N::ExpDotted_::Dot(ed, _, _) | N::ExpDotted_::DotAutocomplete(_, ed) => { exp_dotted(context, ed) } N::ExpDotted_::Index(ed, sp!(_, es)) => { diff --git a/external-crates/move/crates/move-compiler/src/typing/match_analysis.rs b/external-crates/move/crates/move-compiler/src/typing/match_analysis.rs index 422fd7ebb0b..c7dc7229208 100644 --- a/external-crates/move/crates/move-compiler/src/typing/match_analysis.rs +++ b/external-crates/move/crates/move-compiler/src/typing/match_analysis.rs @@ -4,12 +4,12 @@ use crate::{ diag, + diagnostics::warning_filters::WarningFilters, expansion::ast::{ModuleIdent, Value_}, ice, naming::ast::BuiltinTypeName_, parser::ast::{DatatypeName, VariantName}, shared::{ - ast_debug::AstDebug, ide::{IDEAnnotation, MissingMatchArmsInfo, PatternSuggestion}, matching::{MatchContext, PatternMatrix}, string_utils::{debug_print, format_oxford_list}, @@ -18,7 +18,7 @@ use crate::{ typing::{ ast as T, core::{error_format, Context, Subst}, - visitor::TypingVisitorContext, + visitor::TypingMutVisitorContext, }, }; use move_ir_types::location::*; @@ -43,7 +43,7 @@ struct MatchCompiler<'ctx, 'env> { context: &'ctx mut Context<'env>, } -impl TypingVisitorContext for MatchCompiler<'_, '_> { +impl TypingMutVisitorContext for MatchCompiler<'_, '_> { fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { use T::UnannotatedExp_ as E; let eloc = exp.exp.loc; @@ -71,12 +71,12 @@ impl TypingVisitorContext for MatchCompiler<'_, '_> { } } - fn add_warning_filter_scope(&mut self, filter: crate::diagnostics::WarningFilters) { - self.context.env.add_warning_filter_scope(filter); + fn push_warning_filter_scope(&mut self, filter: WarningFilters) { + self.context.push_warning_filter_scope(filter); } fn pop_warning_filter_scope(&mut self) { - self.context.env.pop_warning_filter_scope(); + self.context.pop_warning_filter_scope(); } } @@ -565,7 +565,7 @@ fn find_counterexample_impl( } else { // An error case: no entry on the fringe but no if !context.env.has_errors() { - context.env.add_diag(ice!(( + context.add_diag(ice!(( matrix.loc, "Non-empty matrix with non errors but no type" ))); @@ -594,7 +594,7 @@ fn find_counterexample_impl( if has_guards { diag.add_note("Match arms with guards are not considered for coverage."); } - context.env.add_diag(diag); + context.add_diag(diag); true } else { false @@ -623,9 +623,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr if !unused.is_empty() { let arms = unused.into_iter().map(PS::Value).collect::>(); let info = MissingMatchArmsInfo { arms }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); + context.add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); } } @@ -636,9 +634,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr let info = MissingMatchArmsInfo { arms: vec![PS::Wildcard], }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); + context.add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); } } @@ -658,7 +654,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr // If the matrix _is_ empty, we suggest adding an unpack. let is_positional = context.modules.struct_is_positional(&mident, &name); let Some(fields) = context.modules.struct_fields(&mident, &name) else { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Tried to look up fields for this struct and found none" ))); @@ -685,9 +681,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr let info = MissingMatchArmsInfo { arms: vec![suggestion], }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); + context.add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); } else { // If there's a default arm, no suggestion is necessary. if matrix.has_default_arm() { @@ -723,7 +717,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr .modules .enum_variant_fields(&mident, &name, &variant) else { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Tried to look up fields for this enum and found none" ))); @@ -753,14 +747,12 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr arms.push(suggestion); } let info = MissingMatchArmsInfo { arms }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); + context.add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); } } let Some(ty) = matrix.tys.first() else { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Pattern matrix with no types handed to IDE function" ))); @@ -779,7 +771,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr } else { if !context.env.has_errors() { // It's unclear how we got here, so report an ICE and suggest a wildcard. - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, format!( "Found non-matchable type {} as match subject", @@ -791,9 +783,7 @@ fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatr let info = MissingMatchArmsInfo { arms: vec![PS::Wildcard], }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); + context.add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); } } } diff --git a/external-crates/move/crates/move-compiler/src/typing/match_compilation.rs b/external-crates/move/crates/move-compiler/src/typing/match_compilation.rs deleted file mode 100644 index 9dc0e2f53a3..00000000000 --- a/external-crates/move/crates/move-compiler/src/typing/match_compilation.rs +++ /dev/null @@ -1,2917 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - diag, - expansion::ast::{Fields, ModuleIdent, Mutability, Value, Value_}, - ice, ice_assert, - naming::ast::{self as N, BuiltinTypeName_, Type, UseFuns, Var}, - parser::ast::{BinOp_, ConstantName, DatatypeName, Field, VariantName}, - shared::{ - ast_debug::{AstDebug, AstWriter}, - ide::{IDEAnnotation, MissingMatchArmsInfo, PatternSuggestion}, - string_utils::{debug_print, format_oxford_list}, - unique_map::UniqueMap, - Identifier, - }, - typing::ast::{self as T, MatchArm_, MatchPattern, UnannotatedPat_ as TP}, - typing::core::{error_format, Context, Subst}, -}; -use move_ir_types::location::*; -use move_proc_macros::growing_stack; -use std::{ - collections::{BTreeMap, BTreeSet, VecDeque}, - fmt::Display, -}; - -use super::visitor::TypingVisitorContext; - -//************************************************************************************************** -// Description -//************************************************************************************************** -// This mostly follows the classical Maranget (2008) implementation toward optimal decision trees. - -//************************************************************************************************** -// Entry and Visitor -//************************************************************************************************** - -struct MatchCompiler<'ctx, 'env> { - context: &'ctx mut Context<'env>, -} - -impl TypingVisitorContext for MatchCompiler<'_, '_> { - fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { - use T::UnannotatedExp_ as E; - if let E::Match(_, _) = &exp.exp.value { - let E::Match(mut subject, arms) = - std::mem::replace(&mut exp.exp.value, E::UnresolvedError) - else { - unreachable!() - }; - self.visit_exp(&mut subject); - debug_print!(self.context.debug.match_translation, - ("subject" => subject), - (lines "arms" => &arms.value) - ); - let _ = std::mem::replace(exp, compile_match(self.context, &exp.ty, *subject, arms)); - debug_print!(self.context.debug.match_translation, ("compiled" => exp)); - true - } else { - false - } - } - - fn add_warning_filter_scope(&mut self, filter: crate::diagnostics::WarningFilters) { - self.context.env.add_warning_filter_scope(filter); - } - - fn pop_warning_filter_scope(&mut self) { - self.context.env.pop_warning_filter_scope(); - } -} - -pub fn function_body_(context: &mut Context, b_: &mut T::FunctionBody_) { - match b_ { - T::FunctionBody_::Native | T::FunctionBody_::Macro => (), - T::FunctionBody_::Defined(es) => { - let mut compiler = MatchCompiler { context }; - compiler.visit_seq(es); - } - } -} - -//************************************************************************************************** -// Match Trees -//************************************************************************************************** - -#[derive(Clone, Debug)] -struct FringeEntry { - var: Var, - ty: Type, -} - -type Binders = Vec<(Mutability, Var)>; -type PatBindings = BTreeMap; -type Guard = Option>; - -#[derive(Clone, Debug)] -struct Arm { - orig_pattern: MatchPattern, - rhs_binders: BTreeSet, - index: usize, -} - -#[derive(Clone, Debug)] -struct PatternArm { - pats: VecDeque, - guard: Guard, - arm: Arm, -} - -#[derive(Clone, Debug)] -struct PatternMatrix { - tys: Vec, - patterns: Vec, -} - -#[derive(Clone, Debug)] -struct ArmResult { - loc: Loc, - bindings: PatBindings, - guard: Option>, - arm: Arm, -} - -impl FringeEntry { - fn into_move_exp(self) -> T::Exp { - let FringeEntry { var, ty } = self; - let move_exp = T::UnannotatedExp_::Move { - from_user: false, - var, - }; - T::exp(ty, sp(var.loc, move_exp)) - } -} - -impl PatternArm { - fn pattern_empty(&self) -> bool { - self.pats.is_empty() - } - - /// Returns true if every entry is a wildcard or binder. - fn is_wild_arm(&self) -> bool { - self.pats - .iter() - .all(|pat| matches!(pat.pat.value, TP::Wildcard | TP::Binder(_, _))) - } - - fn all_wild_arm(&mut self, fringe: &VecDeque) -> Option { - if self.is_wild_arm() { - let bindings = self.make_arm_bindings(fringe); - let PatternArm { - pats: _, - guard, - arm, - } = self; - let arm = ArmResult { - loc: arm.orig_pattern.pat.loc, - bindings, - guard: guard.clone(), - arm: arm.clone(), - }; - Some(arm) - } else { - None - } - } - - fn make_arm_bindings(&mut self, fringe: &VecDeque) -> PatBindings { - let mut bindings = BTreeMap::new(); - assert!(self.pats.len() == fringe.len()); - for (pmut, subject) in self.pats.iter_mut().zip(fringe.iter()) { - if let TP::Binder(mut_, x) = pmut.pat.value { - if bindings.insert(x, (mut_, subject.clone())).is_some() { - panic!("ICE should have failed in naming"); - }; - pmut.pat.value = TP::Wildcard; - } - } - bindings - } - - fn first_variant(&self) -> Option<(VariantName, (Loc, Fields))> { - if self.pats.is_empty() { - return None; - } - - fn first_variant_recur(pat: MatchPattern) -> Option<(VariantName, (Loc, Fields))> { - match pat.pat.value { - TP::Variant(_, _, name, _, fields) => { - let ty_fields: Fields = fields.clone().map(|_, (ndx, (ty, _))| (ndx, ty)); - Some((name, (pat.pat.loc, ty_fields))) - } - TP::BorrowVariant(_, _, _, name, _, fields) => { - let ty_fields: Fields = fields.clone().map(|_, (ndx, (ty, _))| (ndx, ty)); - Some((name, (pat.pat.loc, ty_fields))) - } - TP::At(_, inner) => first_variant_recur(*inner), - TP::Struct(..) | TP::BorrowStruct(..) => None, - TP::Constant(_, _) - | TP::Binder(_, _) - | TP::Literal(_) - | TP::Wildcard - | TP::ErrorPat => None, - TP::Or(_, _) => unreachable!(), - } - } - - first_variant_recur(self.pats.front().unwrap().clone()) - } - - fn first_struct(&self) -> Option<(Loc, Fields)> { - if self.pats.is_empty() { - return None; - } - - fn first_struct_recur(pat: MatchPattern) -> Option<(Loc, Fields)> { - match pat.pat.value { - TP::Struct(_, _, _, fields) => { - let ty_fields: Fields = fields.clone().map(|_, (ndx, (ty, _))| (ndx, ty)); - Some((pat.pat.loc, ty_fields)) - } - TP::BorrowStruct(_, _, _, _, fields) => { - let ty_fields: Fields = fields.clone().map(|_, (ndx, (ty, _))| (ndx, ty)); - Some((pat.pat.loc, ty_fields)) - } - TP::At(_, inner) => first_struct_recur(*inner), - TP::Variant(..) | TP::BorrowVariant(..) => None, - TP::Constant(_, _) - | TP::Binder(_, _) - | TP::Literal(_) - | TP::Wildcard - | TP::ErrorPat => None, - TP::Or(_, _) => unreachable!(), - } - } - - first_struct_recur(self.pats.front().unwrap().clone()) - } - - fn first_lit(&self) -> Option { - if self.pats.is_empty() { - return None; - } - - fn first_lit_recur(pat: MatchPattern) -> Option { - match pat.pat.value { - TP::Literal(v) => Some(v), - TP::At(_, inner) => first_lit_recur(*inner), - TP::Variant(_, _, _, _, _) - | TP::BorrowVariant(_, _, _, _, _, _) - | TP::Struct(..) - | TP::BorrowStruct(..) - | TP::Binder(_, _) - | TP::Wildcard - | TP::ErrorPat => None, - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - } - } - - first_lit_recur(self.pats.front().unwrap().clone()) - } - - fn specialize_variant( - &self, - context: &Context, - ctor_name: &VariantName, - arg_types: &Vec<&Type>, - ) -> Option<(Binders, PatternArm)> { - let mut output = self.clone(); - let first_pattern = output.pats.pop_front().unwrap(); - let loc = first_pattern.pat.loc; - match first_pattern.pat.value { - TP::Variant(mident, enum_, name, _, fields) - | TP::BorrowVariant(_, mident, enum_, name, _, fields) - if &name == ctor_name => - { - let field_pats = fields.clone().map(|_key, (ndx, (_, pat))| (ndx, pat)); - let decl_fields = context.enum_variant_fields(&mident, &enum_, &name); - let ordered_pats = order_fields_by_decl(decl_fields, field_pats); - for (_, _, pat) in ordered_pats.into_iter().rev() { - output.pats.push_front(pat); - } - Some((vec![], output)) - } - TP::Variant(_, _, _, _, _) | TP::BorrowVariant(_, _, _, _, _, _) => None, - TP::Struct(_, _, _, _) | TP::BorrowStruct(_, _, _, _, _) => None, - TP::Literal(_) => None, - TP::Binder(mut_, x) => { - for arg_type in arg_types - .clone() - .into_iter() - .map(|ty| ty_to_wildcard_pattern(ty.clone(), loc)) - .rev() - { - output.pats.push_front(arg_type); - } - Some((vec![(mut_, x)], output)) - } - TP::Wildcard => { - for arg_type in arg_types - .clone() - .into_iter() - .map(|ty| ty_to_wildcard_pattern(ty.clone(), loc)) - .rev() - { - output.pats.push_front(arg_type); - } - Some((vec![], output)) - } - TP::At(x, inner) => { - output.pats.push_front(*inner); - output - .specialize_variant(context, ctor_name, arg_types) - .map(|(mut binders, inner)| { - binders.push((Mutability::Imm, x)); - (binders, inner) - }) - } - TP::ErrorPat => None, - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - } - } - - fn specialize_struct( - &self, - context: &Context, - arg_types: &Vec<&Type>, - ) -> Option<(Binders, PatternArm)> { - let mut output = self.clone(); - let first_pattern = output.pats.pop_front().unwrap(); - let loc = first_pattern.pat.loc; - match first_pattern.pat.value { - TP::Struct(mident, struct_, _, fields) - | TP::BorrowStruct(_, mident, struct_, _, fields) => { - let field_pats = fields.clone().map(|_key, (ndx, (_, pat))| (ndx, pat)); - let decl_fields = context.struct_fields(&mident, &struct_); - let ordered_pats = order_fields_by_decl(decl_fields, field_pats); - for (_, _, pat) in ordered_pats.into_iter().rev() { - output.pats.push_front(pat); - } - Some((vec![], output)) - } - TP::Literal(_) => None, - TP::Variant(_, _, _, _, _) | TP::BorrowVariant(_, _, _, _, _, _) => None, - TP::Binder(mut_, x) => { - for arg_type in arg_types - .clone() - .into_iter() - .map(|ty| ty_to_wildcard_pattern(ty.clone(), loc)) - .rev() - { - output.pats.push_front(arg_type); - } - Some((vec![(mut_, x)], output)) - } - TP::Wildcard => { - for arg_type in arg_types - .clone() - .into_iter() - .map(|ty| ty_to_wildcard_pattern(ty.clone(), loc)) - .rev() - { - output.pats.push_front(arg_type); - } - Some((vec![], output)) - } - TP::At(x, inner) => { - output.pats.push_front(*inner); - output - .specialize_struct(context, arg_types) - .map(|(mut binders, inner)| { - binders.push((Mutability::Imm, x)); - (binders, inner) - }) - } - TP::ErrorPat => None, - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - } - } - - fn specialize_literal(&self, literal: &Value) -> Option<(Binders, PatternArm)> { - let mut output = self.clone(); - let first_pattern = output.pats.pop_front().unwrap(); - match first_pattern.pat.value { - TP::Literal(v) if &v == literal => Some((vec![], output)), - TP::Literal(_) => None, - TP::Variant(_, _, _, _, _) | TP::BorrowVariant(_, _, _, _, _, _) => None, - TP::Struct(_, _, _, _) | TP::BorrowStruct(_, _, _, _, _) => None, - TP::Binder(mut_, x) => Some((vec![(mut_, x)], output)), - TP::Wildcard => Some((vec![], output)), - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - TP::At(x, inner) => { - output.pats.push_front(*inner); - output - .specialize_literal(literal) - .map(|(mut binders, inner)| { - binders.push((Mutability::Imm, x)); - (binders, inner) - }) - } - TP::ErrorPat => None, - } - } - - fn specialize_default(&self) -> Option<(Binders, PatternArm)> { - let mut output = self.clone(); - let first_pattern = output.pats.pop_front().unwrap(); - match first_pattern.pat.value { - TP::Literal(_) => None, - TP::Variant(_, _, _, _, _) | TP::BorrowVariant(_, _, _, _, _, _) => None, - TP::Struct(_, _, _, _) | TP::BorrowStruct(_, _, _, _, _) => None, - TP::Binder(mut_, x) => Some((vec![(mut_, x)], output)), - TP::Wildcard => Some((vec![], output)), - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - TP::At(x, inner) => { - output.pats.push_front(*inner); - output.specialize_default().map(|(mut binders, inner)| { - binders.push((Mutability::Imm, x)); - (binders, inner) - }) - } - TP::ErrorPat => None, - } - } -} - -impl PatternMatrix { - fn from( - context: &mut Context, - subject_ty: Type, - arms: Vec, - ) -> (PatternMatrix, Vec) { - let tys = vec![subject_ty]; - let mut patterns = vec![]; - let mut rhss = vec![]; - for sp!(_, arm) in arms { - let MatchArm_ { - pattern, - binders: _, - guard, - guard_binders, - rhs_binders, - rhs, - } = arm; - rhss.push(*rhs); - let index = rhss.len() - 1; - let new_patterns = flatten_or(pattern); - for mut pat in new_patterns { - debug_print!(context.debug.match_constant_conversion, ("with consts" => pat)); - let (guard, const_binders) = const_pats_to_guards(context, &mut pat, guard.clone()); - debug_print!(context.debug.match_constant_conversion, ("no consts" => pat)); - let arm = Arm { - orig_pattern: pat.clone(), - rhs_binders: rhs_binders.clone(), - index, - }; - // Make a match pattern that only holds guard binders - let guard_binders = guard_binders.union_with(&const_binders, |k, _, x| { - let msg = "Match compilation made a binder for this during const compilation"; - context.env.add_diag(ice!((k.loc, msg))); - *x - }); - let pat = apply_pattern_subst(pat, &guard_binders); - debug_print!(context.debug.match_constant_conversion, ("after subst" => pat)); - patterns.push(PatternArm { - pats: VecDeque::from([pat]), - guard, - arm, - }); - } - } - (PatternMatrix { tys, patterns }, rhss) - } - - fn is_empty(&self) -> bool { - self.patterns.is_empty() - } - - fn patterns_empty(&self) -> bool { - !self.patterns.is_empty() && self.patterns.iter().all(|pat| pat.pattern_empty()) - } - - fn all_errors(&self) -> bool { - self.patterns.iter().all(|arm| { - arm.pats - .iter() - .all(|pat| matches!(pat.pat.value, TP::ErrorPat)) - }) - } - - /// Returns true if there is an arm made up entirely of wildcards / binders with no guard. - fn has_default_arm(&self) -> bool { - self.patterns - .iter() - .any(|pat| pat.is_wild_arm() && pat.guard.is_none()) - } - - fn wild_arm_opt(&mut self, fringe: &VecDeque) -> Option> { - // NB: If the first row is all wild, we need to collect _all_ wild rows that have guards - // until we find one that does not. - if let Some(arm) = self.patterns[0].all_wild_arm(fringe) { - if arm.guard.is_none() { - return Some(vec![arm]); - } - let mut result = vec![arm]; - for pat in self.patterns[1..].iter_mut() { - if let Some(arm) = pat.all_wild_arm(fringe) { - let has_guard = arm.guard.is_some(); - result.push(arm); - if !has_guard { - return Some(result); - } - } - } - Some(result) - } else { - None - } - } - - fn specialize_variant( - &self, - context: &Context, - ctor_name: &VariantName, - arg_types: Vec<&Type>, - ) -> (Binders, PatternMatrix) { - let mut patterns = vec![]; - let mut bindings = vec![]; - for entry in &self.patterns { - if let Some((mut new_bindings, arm)) = - entry.specialize_variant(context, ctor_name, &arg_types) - { - bindings.append(&mut new_bindings); - patterns.push(arm) - } - } - let tys = arg_types - .into_iter() - .cloned() - .chain(self.tys.clone().into_iter().skip(1)) - .collect::>(); - let matrix = PatternMatrix { tys, patterns }; - (bindings, matrix) - } - - fn specialize_struct( - &self, - context: &Context, - arg_types: Vec<&Type>, - ) -> (Binders, PatternMatrix) { - let mut patterns = vec![]; - let mut bindings = vec![]; - for entry in &self.patterns { - if let Some((mut new_bindings, arm)) = entry.specialize_struct(context, &arg_types) { - bindings.append(&mut new_bindings); - patterns.push(arm) - } - } - let tys = arg_types - .into_iter() - .cloned() - .chain(self.tys.clone().into_iter().skip(1)) - .collect::>(); - let matrix = PatternMatrix { tys, patterns }; - (bindings, matrix) - } - - fn specialize_literal(&self, lit: &Value) -> (Binders, PatternMatrix) { - let mut patterns = vec![]; - let mut bindings = vec![]; - for entry in &self.patterns { - if let Some((mut new_bindings, arm)) = entry.specialize_literal(lit) { - bindings.append(&mut new_bindings); - patterns.push(arm) - } - } - let tys = self.tys[1..].to_vec(); - let matrix = PatternMatrix { tys, patterns }; - (bindings, matrix) - } - - fn specialize_default(&self) -> (Binders, PatternMatrix) { - let mut patterns = vec![]; - let mut bindings = vec![]; - for entry in &self.patterns { - if let Some((mut new_bindings, arm)) = entry.specialize_default() { - bindings.append(&mut new_bindings); - patterns.push(arm) - } - } - let tys = self.tys[1..].to_vec(); - let matrix = PatternMatrix { tys, patterns }; - (bindings, matrix) - } - - fn first_variant_ctors(&self) -> BTreeMap)> { - self.patterns - .iter() - .flat_map(|pat| pat.first_variant()) - .collect() - } - - fn first_struct_ctors(&self) -> Option<(Loc, Fields)> { - self.patterns.iter().find_map(|pat| pat.first_struct()) - } - - fn first_list(&self) -> BTreeSet { - self.patterns - .iter() - .flat_map(|pat| pat.first_lit()) - .collect() - } - - fn has_guards(&self) -> bool { - self.patterns.iter().any(|pat| pat.guard.is_some()) - } - - fn remove_guarded_arms(&mut self) { - let pats = std::mem::take(&mut self.patterns); - self.patterns = pats.into_iter().filter(|pat| pat.guard.is_none()).collect(); - } -} - -// ----------------------------------------------- -// Pattern Helpers -// ----------------------------------------------- - -fn ty_to_wildcard_pattern(ty: Type, loc: Loc) -> T::MatchPattern { - T::MatchPattern { - ty, - pat: sp(loc, T::UnannotatedPat_::Wildcard), - } -} - -// NB: this converts any binders not in `env` to wildcards, and strips any `at` pattern binders -// that is not in the `env` -fn apply_pattern_subst(pat: MatchPattern, env: &UniqueMap) -> MatchPattern { - let MatchPattern { - ty, - pat: sp!(ploc, pat), - } = pat; - let new_pat = match pat { - TP::Variant(m, e, v, ta, spats) => { - let out_fields = - spats.map(|_, (ndx, (t, pat))| (ndx, (t, apply_pattern_subst(pat, env)))); - TP::Variant(m, e, v, ta, out_fields) - } - TP::BorrowVariant(mut_, m, e, v, ta, spats) => { - let out_fields = - spats.map(|_, (ndx, (t, pat))| (ndx, (t, apply_pattern_subst(pat, env)))); - TP::BorrowVariant(mut_, m, e, v, ta, out_fields) - } - TP::Struct(m, s, ta, spats) => { - let out_fields = - spats.map(|_, (ndx, (t, pat))| (ndx, (t, apply_pattern_subst(pat, env)))); - TP::Struct(m, s, ta, out_fields) - } - TP::BorrowStruct(mut_, m, s, ta, spats) => { - let out_fields = - spats.map(|_, (ndx, (t, pat))| (ndx, (t, apply_pattern_subst(pat, env)))); - TP::BorrowStruct(mut_, m, s, ta, out_fields) - } - TP::At(x, inner) => { - let xloc = x.loc; - // Since we are only applying the guard environment, this may be unused here. - // If it is, we simply elide the `@` form. - if let Some(y) = env.get(&x) { - TP::At( - sp(xloc, y.value), - Box::new(apply_pattern_subst(*inner, env)), - ) - } else { - apply_pattern_subst(*inner, env).pat.value - } - } - TP::Binder(mut_, x) => { - let xloc = x.loc; - if let Some(y) = env.get(&x) { - TP::Binder(mut_, sp(xloc, y.value)) - } else { - TP::Wildcard - } - } - pat @ (TP::Literal(_) | TP::ErrorPat | TP::Wildcard) => pat, - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - }; - MatchPattern { - ty, - pat: sp(ploc, new_pat), - } -} - -fn flatten_or(pat: MatchPattern) -> Vec { - let ploc = pat.pat.loc; - match pat.pat.value { - TP::Constant(_, _) | TP::Literal(_) | TP::Binder(_, _) | TP::Wildcard | TP::ErrorPat => { - vec![pat] - } - TP::Variant(_, _, _, _, ref pats) - | TP::BorrowVariant(_, _, _, _, _, ref pats) - | TP::Struct(_, _, _, ref pats) - | TP::BorrowStruct(_, _, _, _, ref pats) - if pats.is_empty() => - { - vec![pat] - } - TP::Variant(m, e, v, ta, spats) => { - let all_spats = spats.map(|_, (ndx, (t, pat))| (ndx, (t, flatten_or(pat)))); - let fields_lists: Vec> = combine_pattern_fields(all_spats); - fields_lists - .into_iter() - .map(|field_list| MatchPattern { - ty: pat.ty.clone(), - pat: sp(ploc, TP::Variant(m, e, v, ta.clone(), field_list)), - }) - .collect::>() - } - TP::BorrowVariant(mut_, m, e, v, ta, spats) => { - let all_spats = spats.map(|_, (ndx, (t, pat))| (ndx, (t, flatten_or(pat)))); - let fields_lists: Vec> = combine_pattern_fields(all_spats); - fields_lists - .into_iter() - .map(|field_list| MatchPattern { - ty: pat.ty.clone(), - pat: sp( - ploc, - TP::BorrowVariant(mut_, m, e, v, ta.clone(), field_list), - ), - }) - .collect::>() - } - TP::Struct(m, s, ta, spats) => { - let all_spats = spats.map(|_, (ndx, (t, pat))| (ndx, (t, flatten_or(pat)))); - let fields_lists: Vec> = combine_pattern_fields(all_spats); - fields_lists - .into_iter() - .map(|field_list| MatchPattern { - ty: pat.ty.clone(), - pat: sp(ploc, TP::Struct(m, s, ta.clone(), field_list)), - }) - .collect::>() - } - TP::BorrowStruct(mut_, m, s, ta, spats) => { - let all_spats = spats.map(|_, (ndx, (t, pat))| (ndx, (t, flatten_or(pat)))); - let fields_lists: Vec> = combine_pattern_fields(all_spats); - fields_lists - .into_iter() - .map(|field_list| MatchPattern { - ty: pat.ty.clone(), - pat: sp(ploc, TP::BorrowStruct(mut_, m, s, ta.clone(), field_list)), - }) - .collect::>() - } - TP::Or(lhs, rhs) => { - let mut lhs_rec = flatten_or(*lhs); - let mut rhs_rec = flatten_or(*rhs); - lhs_rec.append(&mut rhs_rec); - lhs_rec - } - TP::At(x, inner) => flatten_or(*inner) - .into_iter() - .map(|pat| MatchPattern { - ty: pat.ty.clone(), - pat: sp(ploc, TP::At(x, Box::new(pat))), - }) - .collect::>(), - } -} - -// A BRIEF OVERVIEW OF CONSTANT MATCH HANDLING -// -// To handle constants, we need to do two things: first, we need to replace all of the constants in -// the patterns with _something_, and then we need to push the constant checks into guards in the -// right-hand side. We take advantage of existing assumptions for match compilation to accomplish -// this, allowing us to reuse the existing match compilation machinery: -// -// 1. We traverse the pattern mutably, replacing all constants with new, fresh variables. -// 2. We generate a new 'guard' variable that acts as the "guard variable map" entry for that -// binder, indicating that this guard variable should be bound during match decision tree -// compilation for guard checking. This guard variable, as all, is typed as an immutable -// reference of the value in question. -// 3. We generate a guard check `guard_var == &const`. -// -// Finally, we hand back: -// -// 1. a new guard expression made up of the new guards plus the old guard (if any), in that order; -// 2. and a guard binder map that maps the new pattern variable to their new guard versions. -// -// As an example: -// -// match (Option::Some(5)) { -// Option::Some(y @ CONST) if (y#guard == 0) => rhs0, -// Option::Some(x) if (x#guard == 1) => rhs1, -// _ => rhs2 -// } -// -// will be translated as: -// -// match (Option::Some(5)) { -// Option::Some(y @ _match_var) if (_match_var#guard == &CONST && y#guard == 0) => rhs0, -// Option::Some(x) if (x#guard == 1) => rhs1, -// _ => rhs2 -// } -// -// At this point, match compilation can proceed normally. -// -// NB: Since `_match_var` is not in the `rhs_binders` list, it will be erased in the final arm. - -/// Assumes `flatten_or` has already been performed. -fn const_pats_to_guards( - context: &mut Context, - pat: &mut MatchPattern, - guard: Option>, -) -> (Option>, UniqueMap) { - #[growing_stack] - fn convert_recur( - context: &mut Context, - input: &mut MatchPattern, - guard_exps: &mut Vec, - guard_map: &mut UniqueMap, - ) { - match &mut input.pat.value { - TP::Constant(m, const_) => { - let loc = input.pat.loc; - let pat_var = context.new_match_var("const".to_string(), loc); - let guard_var = context.new_match_var("const_guard".to_string(), loc); - guard_map.add(pat_var, guard_var).expect("This cannot fail"); - let guard_exp = make_const_test(input.ty.clone(), guard_var, loc, *m, *const_); - let MatchPattern { ty, pat: _ } = input; - guard_exps.push(guard_exp); - *input = T::pat(ty.clone(), sp(loc, TP::Binder(Mutability::Imm, pat_var))); - } - TP::Variant(_, _, _, _, fields) - | TP::BorrowVariant(_, _, _, _, _, fields) - | TP::Struct(_, _, _, fields) - | TP::BorrowStruct(_, _, _, _, fields) => { - for (_, _, (_, (_, rhs))) in fields.iter_mut() { - convert_recur(context, rhs, guard_exps, guard_map); - } - } - TP::At(_, inner) => convert_recur(context, inner, guard_exps, guard_map), - TP::Literal(_) | TP::Binder(_, _) | TP::Wildcard | TP::ErrorPat => (), - TP::Or(_, _) => unreachable!(), - } - } - - fn combine_guards(mut guards: Vec, guard: Option>) -> Option> { - if let Some(guard) = guard { - guards.push(*guard); - } - let Some(mut guard) = guards.pop() else { - return None; - }; - while let Some(new_guard) = guards.pop() { - // FIXME: No good `Loc` to use here... - guard = make_and_test(new_guard.exp.loc, new_guard, guard); - } - Some(Box::new(guard)) - } - - let mut const_guards = vec![]; - let mut const_guard_map = UniqueMap::new(); - - convert_recur(context, pat, &mut const_guards, &mut const_guard_map); - (combine_guards(const_guards, guard), const_guard_map) -} - -fn combine_pattern_fields( - fields: Fields<(Type, Vec)>, -) -> Vec> { - type VFields = Vec<(Field, (usize, (Spanned, MatchPattern)))>; - type VVFields = Vec<(Field, (usize, (Spanned, Vec)))>; - - fn combine_recur(vec: &mut VVFields) -> Vec { - if let Some((f, (ndx, (ty, pats)))) = vec.pop() { - let rec_fields = combine_recur(vec); - let mut output = vec![]; - for entry in rec_fields { - for pat in pats.clone() { - let mut entry = entry.clone(); - entry.push((f, (ndx, (ty.clone(), pat)))); - output.push(entry); - } - } - output - } else { - // Base case: a single match of no fields. We must have at least one, or else we would - // not have called `combine_match_patterns`. - vec![vec![]] - } - } - - let mut vvfields: VVFields = fields.into_iter().collect::>(); - let output_vec = combine_recur(&mut vvfields); - output_vec - .into_iter() - .map(|vfields| UniqueMap::maybe_from_iter(vfields.into_iter()).unwrap()) - .collect::>() -} - -//************************************************************************************************** -// Match Compilation -//************************************************************************************************** - -type Fringe = VecDeque; - -#[derive(Clone)] -enum StructUnpack { - Default(T), - Unpack(Vec<(Field, Var, Type)>, T), -} - -enum MatchStep { - Leaf(Vec), - Failure, - LiteralSwitch { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - fringe: Fringe, - arms: BTreeMap, - default: PatternMatrix, - }, - StructUnpack { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - tyargs: Vec, - unpack: StructUnpack<(Fringe, PatternMatrix)>, - }, - VariantSwitch { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - tyargs: Vec, - arms: BTreeMap, Fringe, PatternMatrix)>, - default: (Fringe, PatternMatrix), - }, -} - -#[derive(Clone)] -enum WorkResult { - Leaf(Vec), - Failure, - LiteralSwitch { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - arms: BTreeMap, - default: usize, // default - }, - StructUnpack { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - tyargs: Vec, - unpack: StructUnpack, - }, - VariantSwitch { - subject: FringeEntry, - subject_binders: Vec<(Mutability, Var)>, - tyargs: Vec, - arms: BTreeMap, usize)>, - default: usize, - }, -} - -pub fn compile_match( - context: &mut Context, - result_type: &Type, - subject: T::Exp, - arms: Spanned>, -) -> T::Exp { - let arms_loc = arms.loc; - let (pattern_matrix, arms) = PatternMatrix::from(context, subject.ty.clone(), arms.value); - - let mut counterexample_matrix = pattern_matrix.clone(); - let has_guards = counterexample_matrix.has_guards(); - counterexample_matrix.remove_guarded_arms(); - if context.env.ide_mode() { - // Do this first, as it's a borrow and a shallow walk. - ide_report_missing_arms(context, arms_loc, &counterexample_matrix); - } - if find_counterexample(context, subject.exp.loc, counterexample_matrix, has_guards) { - return T::exp( - result_type.clone(), - sp(subject.exp.loc, T::UnannotatedExp_::UnresolvedError), - ); - } - - let mut compilation_results: BTreeMap = BTreeMap::new(); - - let (mut initial_binders, init_subject, match_subject) = { - let subject_var = context.new_match_var("unpack_subject".to_string(), arms_loc); - let subject_loc = subject.exp.loc; - let match_var = context.new_match_var("match_subject".to_string(), arms_loc); - - let subject_entry = FringeEntry { - var: subject_var, - ty: subject.ty.clone(), - }; - let subject_borrow_rhs = make_var_ref(subject_entry.clone()); - - let match_entry = FringeEntry { - var: match_var, - ty: subject_borrow_rhs.ty.clone(), - }; - - let subject_binder = { - let lhs_loc = subject_loc; - let lhs_lvalue = make_lvalue(subject_var, Mutability::Imm, subject.ty.clone()); - let binder = T::SequenceItem_::Bind( - sp(lhs_loc, vec![lhs_lvalue]), - vec![Some(subject.ty.clone())], - Box::new(subject), - ); - sp(lhs_loc, binder) - }; - - let subject_borrow = { - let lhs_loc = arms_loc; - let lhs_lvalue = make_lvalue(match_var, Mutability::Imm, subject_borrow_rhs.ty.clone()); - let binder = T::SequenceItem_::Bind( - sp(lhs_loc, vec![lhs_lvalue]), - vec![Some(subject_borrow_rhs.ty.clone())], - subject_borrow_rhs, - ); - sp(lhs_loc, binder) - }; - - ( - VecDeque::from([subject_binder, subject_borrow]), - subject_entry, - match_entry, - ) - }; - - let mut work_queue: Vec<(usize, Fringe, PatternMatrix)> = - vec![(0, VecDeque::from([match_subject]), pattern_matrix)]; - - let mut work_id = 0; - - let mut next_id = || { - work_id += 1; - work_id - }; - - while let Some((cur_id, init_fringe, matrix)) = work_queue.pop() { - debug_print!( - context.debug.match_work_queue, - ("work queue entry" => cur_id; fmt), - (lines "fringe" => &init_fringe; sdbg), - ("matrix" => matrix; verbose) - ); - let redefined: Option = - match compile_match_head(context, init_fringe.clone(), matrix) { - MatchStep::Leaf(leaf) => compilation_results.insert(cur_id, WorkResult::Leaf(leaf)), - MatchStep::Failure => compilation_results.insert(cur_id, WorkResult::Failure), - MatchStep::LiteralSwitch { - subject, - subject_binders, - fringe, - arms, - default, - } => { - let mut answer_map = BTreeMap::new(); - for (value, matrix) in arms { - let work_id = next_id(); - answer_map.insert(value, work_id); - work_queue.push((work_id, fringe.clone(), matrix)); - } - let default_work_id = next_id(); - work_queue.push((default_work_id, fringe, default)); - let result = WorkResult::LiteralSwitch { - subject, - subject_binders, - arms: answer_map, - default: default_work_id, - }; - compilation_results.insert(cur_id, result) - } - MatchStep::StructUnpack { - subject, - subject_binders, - tyargs, - unpack, - } => { - let unpack_work_id = next_id(); - let unpack = match unpack { - StructUnpack::Default((fringe, matrix)) => { - work_queue.push((unpack_work_id, fringe, matrix)); - StructUnpack::Default(unpack_work_id) - } - StructUnpack::Unpack(dtor_fields, (fringe, matrix)) => { - work_queue.push((unpack_work_id, fringe, matrix)); - StructUnpack::Unpack(dtor_fields, unpack_work_id) - } - }; - compilation_results.insert( - cur_id, - WorkResult::StructUnpack { - subject, - subject_binders, - tyargs, - unpack, - }, - ) - } - - MatchStep::VariantSwitch { - subject, - subject_binders, - tyargs, - arms, - default: (dfringe, dmatrix), - } => { - let mut answer_map = BTreeMap::new(); - for (name, (dtor_fields, fringe, matrix)) in arms { - let work_id = next_id(); - answer_map.insert(name, (dtor_fields, work_id)); - work_queue.push((work_id, fringe, matrix)); - } - let default_work_id = next_id(); - work_queue.push((default_work_id, dfringe, dmatrix)); - compilation_results.insert( - cur_id, - WorkResult::VariantSwitch { - subject, - subject_binders, - tyargs, - arms: answer_map, - default: default_work_id, - }, - ) - } - }; - ice_assert!( - context.env, - redefined.is_none(), - arms_loc, - "Match work queue went awry" - ); - } - - let match_start = compilation_results.remove(&0).unwrap(); - let mut resolution_context = ResolutionContext { - hlir_context: context, - output_type: result_type, - arms: &arms, - arms_loc, - results: &mut compilation_results, - }; - let match_exp = resolve_result(&mut resolution_context, &init_subject, match_start); - - let eloc = match_exp.exp.loc; - let mut seq = VecDeque::new(); - seq.append(&mut initial_binders); - seq.push_back(sp(eloc, T::SequenceItem_::Seq(Box::new(match_exp)))); - let exp_value = sp(eloc, T::UnannotatedExp_::Block((UseFuns::new(0), seq))); - T::exp(result_type.clone(), exp_value) -} - -fn compile_match_head( - context: &mut Context, - mut fringe: VecDeque, - mut matrix: PatternMatrix, -) -> MatchStep { - debug_print!( - context.debug.match_specialization, - ("-----\ncompiling with fringe queue entry" => fringe; dbg) - ); - if matrix.is_empty() { - MatchStep::Failure - } else if let Some(leaf) = matrix.wild_arm_opt(&fringe) { - MatchStep::Leaf(leaf) - } else if fringe[0].ty.value.unfold_to_builtin_type_name().is_some() { - let subject = fringe - .pop_front() - .expect("ICE empty fringe in match compilation"); - let mut subject_binders = vec![]; - // treat column as a literal - let list = matrix.first_list(); - let mut arms = BTreeMap::new(); - for lit in list { - let lit_loc = lit.loc; - debug_print!(context.debug.match_specialization, ("lit specializing" => lit ; fmt)); - let (mut new_binders, inner_matrix) = matrix.specialize_literal(&lit); - debug_print!( - context.debug.match_specialization, - ("binders" => &new_binders; dbg), ("specialized" => inner_matrix) - ); - subject_binders.append(&mut new_binders); - ice_assert!( - context.env, - arms.insert(lit, inner_matrix).is_none(), - lit_loc, - "Specialization failed" - ); - } - let (mut new_binders, default) = matrix.specialize_default(); - debug_print!(context.debug.match_specialization, ("default binders" => &new_binders; dbg)); - subject_binders.append(&mut new_binders); - MatchStep::LiteralSwitch { - subject, - subject_binders, - fringe, - arms, - default, - } - } else { - let subject = fringe - .pop_front() - .expect("ICE empty fringe in match compilation"); - let tyargs = subject.ty.value.type_arguments().unwrap().clone(); - let mut subject_binders = vec![]; - debug_print!( - context.debug.match_specialization, - ("subject" => subject), - ("matrix" => matrix) - ); - let (mident, datatype_name) = subject - .ty - .value - .unfold_to_type_name() - .and_then(|sp!(_, name)| name.datatype_name()) - .expect("ICE non-datatype type in head constructor fringe position"); - - if context.is_struct(&mident, &datatype_name) { - // If we have an actual destructuring anywhere, we do that and take the specialized - // matrix (which holds the default matrix and bindings, for our purpose). If we don't, - // we just take the default matrix. - let unpack = if let Some((ploc, arg_types)) = matrix.first_struct_ctors() { - let fringe_binders = context.make_imm_ref_match_binders(ploc, arg_types); - let fringe_exps = make_fringe_entries(&fringe_binders); - let mut inner_fringe = fringe.clone(); - for fringe_exp in fringe_exps.into_iter().rev() { - inner_fringe.push_front(fringe_exp); - } - let bind_tys = fringe_binders - .iter() - .map(|(_, _, ty)| ty) - .collect::>(); - debug_print!( - context.debug.match_specialization, ("struct specialized" => datatype_name; dbg) - ); - let (mut new_binders, inner_matrix) = matrix.specialize_struct(context, bind_tys); - debug_print!(context.debug.match_specialization, - ("binders" => new_binders; dbg), - ("specialized" => inner_matrix)); - subject_binders.append(&mut new_binders); - StructUnpack::Unpack(fringe_binders, (inner_fringe, inner_matrix)) - } else { - let (mut new_binders, default_matrix) = matrix.specialize_default(); - subject_binders.append(&mut new_binders); - StructUnpack::Default((fringe, default_matrix)) - }; - MatchStep::StructUnpack { - subject, - subject_binders, - tyargs, - unpack, - } - } else { - let mut unmatched_variants = context - .enum_variants(&mident, &datatype_name) - .into_iter() - .collect::>(); - - let ctors = matrix.first_variant_ctors(); - - let mut arms = BTreeMap::new(); - for (ctor, (ploc, arg_types)) in ctors { - unmatched_variants.remove(&ctor); - let fringe_binders = context.make_imm_ref_match_binders(ploc, arg_types); - let fringe_exps = make_fringe_entries(&fringe_binders); - let mut inner_fringe = fringe.clone(); - for fringe_exp in fringe_exps.into_iter().rev() { - inner_fringe.push_front(fringe_exp); - } - let bind_tys = fringe_binders - .iter() - .map(|(_, _, ty)| ty) - .collect::>(); - debug_print!( - context.debug.match_specialization, ("enum specialized" => datatype_name; dbg) - ); - let (mut new_binders, inner_matrix) = - matrix.specialize_variant(context, &ctor, bind_tys); - debug_print!(context.debug.match_specialization, - ("binders" => new_binders; dbg), - ("specialized" => inner_matrix)); - subject_binders.append(&mut new_binders); - ice_assert!( - context.env, - arms.insert(ctor, (fringe_binders, inner_fringe, inner_matrix)) - .is_none(), - ploc, - "Inserted duplicate ctor" - ); - } - - let (mut new_binders, default_matrix) = matrix.specialize_default(); - subject_binders.append(&mut new_binders); - - MatchStep::VariantSwitch { - subject, - subject_binders, - tyargs, - arms, - default: (fringe, default_matrix), - } - } - } -} - -pub fn order_fields_by_decl( - decl_fields: Option>, - fields: Fields, -) -> Vec<(usize, Field, T)> { - let mut texp_fields: Vec<(usize, Field, T)> = if let Some(field_map) = decl_fields { - fields - .into_iter() - .map(|(f, (_exp_idx, t))| (*field_map.get(&f).unwrap(), f, t)) - .collect() - } else { - // If no field map, compiler error in typing. - fields - .into_iter() - .enumerate() - .map(|(ndx, (f, (_exp_idx, t)))| (ndx, f, t)) - .collect() - }; - texp_fields.sort_by(|(decl_idx1, _, _), (decl_idx2, _, _)| decl_idx1.cmp(decl_idx2)); - texp_fields -} - -fn make_fringe_entries(binders: &[(Field, Var, Type)]) -> VecDeque { - binders - .iter() - .map(|(_, var, ty)| FringeEntry { - var: *var, - ty: ty.clone(), - }) - .collect::>() -} - -//------------------------------------------------ -// Result Construction -//------------------------------------------------ - -struct ResolutionContext<'ctxt, 'call> { - hlir_context: &'call mut Context<'ctxt>, - output_type: &'call Type, - arms: &'call Vec, - arms_loc: Loc, - results: &'call mut BTreeMap, -} - -impl<'ctxt, 'call> ResolutionContext<'ctxt, 'call> { - fn arm(&self, index: usize) -> T::Exp { - self.arms[index].clone() - } - - fn arms_loc(&self) -> Loc { - self.arms_loc - } - - fn work_result(&mut self, work_id: usize) -> WorkResult { - self.results.remove(&work_id).unwrap() - } - - fn copy_work_result(&mut self, work_id: usize) -> WorkResult { - self.results.get(&work_id).unwrap().clone() - } - - fn output_type(&self) -> Type { - self.output_type.clone() - } -} - -#[growing_stack] -fn resolve_result( - context: &mut ResolutionContext, - init_subject: &FringeEntry, - result: WorkResult, -) -> T::Exp { - match result { - WorkResult::Leaf(leaf) => make_leaf(context, init_subject, leaf), - WorkResult::Failure => T::exp( - context.output_type(), - sp(context.arms_loc, T::UnannotatedExp_::UnresolvedError), - ), - WorkResult::VariantSwitch { - subject, - subject_binders, - tyargs, - mut arms, - default: default_ndx, - } => { - let (m, e) = subject - .ty - .value - .unfold_to_type_name() - .and_then(|sp!(_, name)| name.datatype_name()) - .unwrap(); - let bindings = subject_binders - .into_iter() - .map(|(mut_, binder)| (binder, (mut_, subject.clone()))) - .collect(); - - let sorted_variants: Vec = context.hlir_context.enum_variants(&m, &e); - let mut blocks = vec![]; - for v in sorted_variants { - if let Some((unpack_fields, result_ndx)) = arms.remove(&v) { - let work_result = context.work_result(result_ndx); - let rest_result = resolve_result(context, init_subject, work_result); - let unpack_block = make_match_variant_unpack( - m, - e, - v, - tyargs.clone(), - unpack_fields, - subject.clone(), - rest_result, - ); - blocks.push((v, unpack_block)); - } else { - let work_result = context.copy_work_result(default_ndx); - let rest_result = resolve_result(context, init_subject, work_result); - blocks.push((v, rest_result)); - } - } - let out_exp = T::UnannotatedExp_::VariantMatch(make_var_ref(subject), (m, e), blocks); - let body_exp = T::exp(context.output_type(), sp(context.arms_loc(), out_exp)); - make_copy_bindings(bindings, body_exp) - } - WorkResult::StructUnpack { - subject, - subject_binders, - tyargs, - unpack, - } => { - let (m, s) = subject - .ty - .value - .unfold_to_type_name() - .and_then(|sp!(_, name)| name.datatype_name()) - .unwrap(); - let bindings = subject_binders - .into_iter() - .map(|(mut_, binder)| (binder, (mut_, subject.clone()))) - .collect(); - let unpack_exp = match unpack { - StructUnpack::Default(result_ndx) => { - let work_result = context.work_result(result_ndx); - resolve_result(context, init_subject, work_result) - } - StructUnpack::Unpack(unpack_fields, result_ndx) => { - let work_result = context.work_result(result_ndx); - let rest_result = resolve_result(context, init_subject, work_result); - make_match_struct_unpack( - m, - s, - tyargs.clone(), - unpack_fields, - subject.clone(), - rest_result, - ) - } - }; - make_copy_bindings(bindings, unpack_exp) - } - WorkResult::LiteralSwitch { - subject, - subject_binders, - mut arms, - default: _, - } if matches!( - subject.ty.value.unfold_to_builtin_type_name(), - Some(sp!(_, BuiltinTypeName_::Bool)) - ) && arms.len() == 2 => - { - let bindings = subject_binders - .into_iter() - .map(|(mut_, binder)| (binder, (mut_, subject.clone()))) - .collect(); - // If the literal switch for a boolean is saturated, no default case. - let lit_subject = make_match_lit(subject.clone()); - let true_arm_ndx = arms - .remove(&sp(Loc::invalid(), Value_::Bool(true))) - .unwrap(); - let false_arm_ndx = arms - .remove(&sp(Loc::invalid(), Value_::Bool(false))) - .unwrap(); - - let true_arm_result = context.work_result(true_arm_ndx); - let false_arm_result = context.work_result(false_arm_ndx); - - let true_arm = resolve_result(context, init_subject, true_arm_result); - let false_arm = resolve_result(context, init_subject, false_arm_result); - let result_type = true_arm.ty.clone(); - - make_copy_bindings( - bindings, - make_if_else(lit_subject, true_arm, false_arm, result_type), - ) - } - WorkResult::LiteralSwitch { - subject, - subject_binders, - arms: map, - default, - } => { - let bindings = subject_binders - .into_iter() - .map(|(mut_, binder)| (binder, (mut_, subject.clone()))) - .collect(); - let lit_subject = make_match_lit(subject.clone()); - - let mut entries = map.into_iter().collect::>(); - entries.sort_by(|(key1, _), (key2, _)| key1.cmp(key2)); - - let else_work_result = context.work_result(default); - let mut out_exp = resolve_result(context, init_subject, else_work_result); - - for (key, result_ndx) in entries.into_iter().rev() { - let work_result = context.work_result(result_ndx); - let match_arm = resolve_result(context, init_subject, work_result); - let test_exp = make_lit_test(lit_subject.clone(), key); - let result_ty = out_exp.ty.clone(); - out_exp = make_if_else(test_exp, match_arm, out_exp, result_ty); - } - make_copy_bindings(bindings, out_exp) - } - } -} - -fn make_leaf( - context: &mut ResolutionContext, - subject: &FringeEntry, - mut leaf: Vec, -) -> T::Exp { - assert!(!leaf.is_empty(), "ICE empty leaf in matching"); - - if leaf.len() == 1 { - let last = leaf.pop().unwrap(); - ice_assert!( - context.hlir_context.env, - last.guard.is_none(), - last.guard.unwrap().exp.loc, - "Must have a non-guarded leaf" - ); - return make_copy_bindings(last.bindings, make_arm(context, subject.clone(), last.arm)); - } - - let last = leaf.pop().unwrap(); - ice_assert!( - context.hlir_context.env, - last.guard.is_none(), - last.guard.unwrap().exp.loc, - "Must have a non-guarded leaf" - ); - let mut out_exp = - make_copy_bindings(last.bindings, make_arm(context, subject.clone(), last.arm)); - let out_ty = out_exp.ty.clone(); - while let Some(arm) = leaf.pop() { - ice_assert!( - context.hlir_context.env, - arm.guard.is_some(), - arm.loc, - "Expected a guard" - ); - out_exp = make_guard_exp(context, subject, arm, out_exp, out_ty.clone()); - } - out_exp -} - -fn make_guard_exp( - context: &mut ResolutionContext, - subject: &FringeEntry, - arm: ArmResult, - cur_exp: T::Exp, - result_ty: Type, -) -> T::Exp { - let ArmResult { - loc: _, - bindings, - guard, - arm, - } = arm; - let guard_arm = make_arm(context, subject.clone(), arm); - let body = make_if_else(*guard.unwrap(), guard_arm, cur_exp, result_ty); - make_copy_bindings(bindings, body) -} - -fn make_arm(context: &mut ResolutionContext, subject: FringeEntry, arm: Arm) -> T::Exp { - let arm_exp = context.arm(arm.index); - make_arm_unpack( - context, - subject, - arm.orig_pattern, - &arm.rhs_binders, - arm_exp, - ) -} - -fn make_arm_unpack( - context: &mut ResolutionContext, - subject: FringeEntry, - pattern: MatchPattern, - rhs_binders: &BTreeSet, - next: T::Exp, -) -> T::Exp { - let ploc = pattern.pat.loc; - let mut seq = VecDeque::new(); - - let mut queue: VecDeque<(FringeEntry, MatchPattern)> = VecDeque::from([(subject, pattern)]); - - // TODO(cgswords): we can coalesce patterns a bit here, but don't for now. - while let Some((entry, pat)) = queue.pop_front() { - let ploc = pat.pat.loc; - match pat.pat.value { - TP::Variant(m, e, v, tys, fs) => { - let Some((queue_entries, unpack)) = - arm_variant_unpack(context, None, ploc, m, e, tys, v, fs, entry) - else { - context.hlir_context.env.add_diag(ice!(( - ploc, - "Did not build an arm unpack for a value variant" - ))); - continue; - }; - for entry in queue_entries.into_iter().rev() { - queue.push_front(entry); - } - seq.push_back(unpack); - } - TP::BorrowVariant(mut_, m, e, v, tys, fs) => { - let Some((queue_entries, unpack)) = - arm_variant_unpack(context, Some(mut_), ploc, m, e, tys, v, fs, entry) - else { - continue; - }; - for entry in queue_entries.into_iter().rev() { - queue.push_front(entry); - } - seq.push_back(unpack); - } - TP::Struct(m, s, tys, fs) => { - let Some((queue_entries, unpack)) = - arm_struct_unpack(context, None, ploc, m, s, tys, fs, entry) - else { - context.hlir_context.env.add_diag(ice!(( - ploc, - "Did not build an arm unpack for a value struct" - ))); - continue; - }; - for entry in queue_entries.into_iter().rev() { - queue.push_front(entry); - } - seq.push_back(unpack); - } - TP::BorrowStruct(mut_, m, s, tys, fs) => { - let Some((queue_entries, unpack)) = - arm_struct_unpack(context, Some(mut_), ploc, m, s, tys, fs, entry) - else { - continue; - }; - for entry in queue_entries.into_iter().rev() { - queue.push_front(entry); - } - seq.push_back(unpack); - } - TP::Literal(_) => (), - TP::Binder(mut_, x) if rhs_binders.contains(&x) => { - seq.push_back(make_move_binding(x, mut_, entry.ty.clone(), entry)) - } - TP::Binder(_, _) => (), - TP::Wildcard => (), - TP::At(x, inner) => { - // See comment in typing/translate.rs at pattern typing for more information. - let x_in_rhs_binders = rhs_binders.contains(&x); - let inner_has_rhs_binders = match_pattern_has_binders(&inner, rhs_binders); - match (x_in_rhs_binders, inner_has_rhs_binders) { - // make a copy of the value (or ref) and do both sides - (true, true) => { - let bind_entry = entry.clone(); - seq.push_back(make_copy_binding( - x, - Mutability::Imm, - bind_entry.ty.clone(), - bind_entry, - )); - queue.push_front((entry, *inner)); - } - // no unpack needed, just move the value to the x - (true, false) => seq.push_back(make_move_binding( - x, - Mutability::Imm, - entry.ty.clone(), - entry, - )), - // we need to unpack either way, handling wildcards and the like - (false, _) => queue.push_front((entry, *inner)), - } - } - TP::ErrorPat => (), - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - } - } - - let nloc = next.exp.loc; - let out_type = next.ty.clone(); - seq.push_back(sp(nloc, T::SequenceItem_::Seq(Box::new(next)))); - - let body = T::UnannotatedExp_::Block((UseFuns::new(0), seq)); - T::exp(out_type, sp(ploc, body)) -} - -fn match_pattern_has_binders(pat: &T::MatchPattern, rhs_binders: &BTreeSet) -> bool { - match &pat.pat.value { - TP::Binder(_, x) => rhs_binders.contains(x), - TP::At(x, inner) => { - rhs_binders.contains(x) || match_pattern_has_binders(inner, rhs_binders) - } - TP::Variant(_, _, _, _, fields) | TP::BorrowVariant(_, _, _, _, _, fields) => fields - .iter() - .any(|(_, _, (_, (_, pat)))| match_pattern_has_binders(pat, rhs_binders)), - TP::Struct(_, _, _, fields) | TP::BorrowStruct(_, _, _, _, fields) => fields - .iter() - .any(|(_, _, (_, (_, pat)))| match_pattern_has_binders(pat, rhs_binders)), - TP::Literal(_) => false, - TP::Wildcard => false, - TP::ErrorPat => false, - TP::Constant(_, _) | TP::Or(_, _) => unreachable!(), - } -} - -fn arm_variant_unpack( - context: &mut ResolutionContext, - mut_ref: Option, - pat_loc: Loc, - mident: ModuleIdent, - enum_: DatatypeName, - tyargs: Vec, - variant: VariantName, - fields: Fields<(Type, MatchPattern)>, - rhs: FringeEntry, -) -> Option<(Vec<(FringeEntry, MatchPattern)>, T::SequenceItem)> { - let all_wild = fields - .iter() - .all(|(_, _, (_, (_, pat)))| matches!(pat.pat.value, TP::Wildcard)) - || fields.is_empty(); - // If we are matching a ref with no fields under it, we aren't going to drop so - // we just continue on. - if all_wild && mut_ref.is_some() { - return None; - } - - let (queue_entries, fields) = - make_arm_variant_unpack_fields(context, mut_ref, pat_loc, mident, enum_, variant, fields); - let unpack = make_arm_variant_unpack_stmt(mut_ref, mident, enum_, variant, tyargs, fields, rhs); - Some((queue_entries, unpack)) -} - -fn arm_struct_unpack( - context: &mut ResolutionContext, - mut_ref: Option, - pat_loc: Loc, - mident: ModuleIdent, - struct_: DatatypeName, - tyargs: Vec, - fields: Fields<(Type, MatchPattern)>, - rhs: FringeEntry, -) -> Option<(Vec<(FringeEntry, MatchPattern)>, T::SequenceItem)> { - let all_wild = fields - .iter() - .all(|(_, _, (_, (_, pat)))| matches!(pat.pat.value, TP::Wildcard)) - || fields.is_empty(); - // If we are matching a ref with no fields under it, we aren't going to drop so - // we just continue on. - if all_wild && mut_ref.is_some() { - return None; - } - - let (queue_entries, fields) = - make_arm_struct_unpack_fields(context, mut_ref, pat_loc, mident, struct_, fields); - let unpack = make_arm_struct_unpack_stmt(mut_ref, mident, struct_, tyargs, fields, rhs); - Some((queue_entries, unpack)) -} - -//------------------------------------------------ -// Unpack Field Builders -//------------------------------------------------ - -fn make_arm_variant_unpack_fields( - context: &mut ResolutionContext, - mut_ref: Option, - pat_loc: Loc, - mident: ModuleIdent, - enum_: DatatypeName, - variant: VariantName, - fields: Fields<(Type, MatchPattern)>, -) -> (Vec<(FringeEntry, MatchPattern)>, Vec<(Field, Var, Type)>) { - let field_pats = fields.clone().map(|_key, (ndx, (_, pat))| (ndx, pat)); - - let field_tys = { - let field_tys = fields.map(|_key, (ndx, (ty, _))| (ndx, ty)); - if let Some(mut_) = mut_ref { - field_tys.map(|_field, (ndx, sp!(loc, ty))| { - ( - ndx, - sp(loc, N::Type_::Ref(mut_, Box::new(sp(loc, ty.base_type_())))), - ) - }) - } else { - field_tys - } - }; - let fringe_binders = context.hlir_context.make_unpack_binders(pat_loc, field_tys); - let fringe_exps = make_fringe_entries(&fringe_binders); - - let decl_fields = context - .hlir_context - .enum_variant_fields(&mident, &enum_, &variant); - let ordered_pats = order_fields_by_decl(decl_fields, field_pats); - - let mut unpack_fields: Vec<(Field, Var, Type)> = vec![]; - assert!(fringe_exps.len() == ordered_pats.len()); - for (fringe_exp, (_, field, _)) in fringe_exps.iter().zip(ordered_pats.iter()) { - unpack_fields.push((*field, fringe_exp.var, fringe_exp.ty.clone())); - } - let queue_entries = fringe_exps - .into_iter() - .zip( - ordered_pats - .into_iter() - .map(|(_, _, ordered_pat)| ordered_pat), - ) - .collect::>(); - - (queue_entries, unpack_fields) -} - -fn make_arm_struct_unpack_fields( - context: &mut ResolutionContext, - mut_ref: Option, - pat_loc: Loc, - mident: ModuleIdent, - struct_: DatatypeName, - fields: Fields<(Type, MatchPattern)>, -) -> (Vec<(FringeEntry, MatchPattern)>, Vec<(Field, Var, Type)>) { - let field_pats = fields.clone().map(|_key, (ndx, (_, pat))| (ndx, pat)); - - let field_tys = { - let field_tys = fields.map(|_key, (ndx, (ty, _))| (ndx, ty)); - if let Some(mut_) = mut_ref { - field_tys.map(|_field, (ndx, sp!(loc, ty))| { - ( - ndx, - sp(loc, N::Type_::Ref(mut_, Box::new(sp(loc, ty.base_type_())))), - ) - }) - } else { - field_tys - } - }; - let fringe_binders = context.hlir_context.make_unpack_binders(pat_loc, field_tys); - let fringe_exps = make_fringe_entries(&fringe_binders); - - let decl_fields = context.hlir_context.struct_fields(&mident, &struct_); - let ordered_pats = order_fields_by_decl(decl_fields, field_pats); - - let mut unpack_fields: Vec<(Field, Var, Type)> = vec![]; - assert!(fringe_exps.len() == ordered_pats.len()); - for (fringe_exp, (_, field, _)) in fringe_exps.iter().zip(ordered_pats.iter()) { - unpack_fields.push((*field, fringe_exp.var, fringe_exp.ty.clone())); - } - let queue_entries = fringe_exps - .into_iter() - .zip( - ordered_pats - .into_iter() - .map(|(_, _, ordered_pat)| ordered_pat), - ) - .collect::>(); - - (queue_entries, unpack_fields) -} - -//------------------------------------------------ -// Expression Creation Helpers -//------------------------------------------------ - -fn make_var_ref(subject: FringeEntry) -> Box { - let FringeEntry { var, ty } = subject; - match ty { - sp!(_, N::Type_::Ref(false, _)) => { - let loc = var.loc; - Box::new(make_copy_exp(ty, loc, var)) - } - sp!(_, N::Type_::Ref(true, inner)) => { - // NB(cswords): we freeze the mut ref at the non-mut ref type. - let loc = var.loc; - let ref_ty = sp(loc, N::Type_::Ref(true, inner.clone())); - let freeze_arg = make_copy_exp(ref_ty, loc, var); - let freeze_ty = sp(loc, N::Type_::Ref(false, inner)); - Box::new(make_freeze_exp(freeze_ty, loc, freeze_arg)) - } - ty => { - // NB(cswords): we borrow the local - let loc = var.loc; - let ref_ty = sp(loc, N::Type_::Ref(false, Box::new(ty))); - let borrow_exp = T::UnannotatedExp_::BorrowLocal(false, var); - Box::new(T::exp(ref_ty, sp(loc, borrow_exp))) - } - } -} - -// Performs an unpack for the purpose of matching, where we are matching against an imm. ref. -fn make_match_variant_unpack( - mident: ModuleIdent, - enum_: DatatypeName, - variant: VariantName, - tyargs: Vec, - fields: Vec<(Field, Var, Type)>, - rhs: FringeEntry, - next: T::Exp, -) -> T::Exp { - assert!(matches!(rhs.ty.value, N::Type_::Ref(false, _))); - let mut seq = VecDeque::new(); - - let rhs_loc = rhs.var.loc; - let mut lvalue_fields: Fields<(Type, T::LValue)> = UniqueMap::new(); - - for (ndx, (field_name, var, ty)) in fields.into_iter().enumerate() { - assert!(ty.value.is_ref().is_some()); - let var_lvalue = make_lvalue(var, Mutability::Imm, ty.clone()); - let lhs_ty = sp(ty.loc, ty.value.base_type_()); - lvalue_fields - .add(field_name, (ndx, (lhs_ty, var_lvalue))) - .unwrap(); - } - - let unpack_lvalue = sp( - rhs_loc, - T::LValue_::BorrowUnpackVariant(false, mident, enum_, variant, tyargs, lvalue_fields), - ); - - let FringeEntry { var, ty } = rhs; - let rhs = Box::new(make_copy_exp(ty.clone(), var.loc, var)); - let binder = T::SequenceItem_::Bind(sp(rhs_loc, vec![unpack_lvalue]), vec![Some(ty)], rhs); - seq.push_back(sp(rhs_loc, binder)); - - let result_type = next.ty.clone(); - let eloc = next.exp.loc; - seq.push_back(sp(eloc, T::SequenceItem_::Seq(Box::new(next)))); - - let exp_value = sp(eloc, T::UnannotatedExp_::Block((UseFuns::new(0), seq))); - T::exp(result_type, exp_value) -} - -// Performs a struct unpack for the purpose of matching, where we are matching against an imm. ref. -// Note that unpacking refs is a lie; this is -fn make_match_struct_unpack( - mident: ModuleIdent, - struct_: DatatypeName, - tyargs: Vec, - fields: Vec<(Field, Var, Type)>, - rhs: FringeEntry, - next: T::Exp, -) -> T::Exp { - assert!(matches!(rhs.ty.value, N::Type_::Ref(false, _))); - let mut seq = VecDeque::new(); - - let rhs_loc = rhs.var.loc; - let mut lvalue_fields: Fields<(Type, T::LValue)> = UniqueMap::new(); - - for (ndx, (field_name, var, ty)) in fields.into_iter().enumerate() { - assert!(ty.value.is_ref().is_some()); - let var_lvalue = make_lvalue(var, Mutability::Imm, ty.clone()); - let lhs_ty = sp(ty.loc, ty.value.base_type_()); - lvalue_fields - .add(field_name, (ndx, (lhs_ty, var_lvalue))) - .unwrap(); - } - - let unpack_lvalue = sp( - rhs_loc, - T::LValue_::BorrowUnpack(false, mident, struct_, tyargs, lvalue_fields), - ); - - let FringeEntry { var, ty } = rhs; - let rhs = Box::new(make_copy_exp(ty.clone(), var.loc, var)); - let binder = T::SequenceItem_::Bind(sp(rhs_loc, vec![unpack_lvalue]), vec![Some(ty)], rhs); - seq.push_back(sp(rhs_loc, binder)); - - let result_type = next.ty.clone(); - let eloc = next.exp.loc; - seq.push_back(sp(eloc, T::SequenceItem_::Seq(Box::new(next)))); - - let exp_value = sp(eloc, T::UnannotatedExp_::Block((UseFuns::new(0), seq))); - T::exp(result_type, exp_value) -} - -fn make_arm_variant_unpack_stmt( - mut_ref: Option, - mident: ModuleIdent, - enum_: DatatypeName, - variant: VariantName, - tyargs: Vec, - fields: Vec<(Field, Var, Type)>, - rhs: FringeEntry, -) -> T::SequenceItem { - let rhs_loc = rhs.var.loc; - let mut lvalue_fields: Fields<(Type, T::LValue)> = UniqueMap::new(); - - for (ndx, (field_name, var, ty)) in fields.into_iter().enumerate() { - let var_lvalue = make_lvalue(var, Mutability::Imm, ty.clone()); - let lhs_ty = sp(ty.loc, ty.value.base_type_()); - lvalue_fields - .add(field_name, (ndx, (lhs_ty, var_lvalue))) - .unwrap(); - } - - let unpack_lvalue_ = if let Some(mut_) = mut_ref { - T::LValue_::BorrowUnpackVariant(mut_, mident, enum_, variant, tyargs, lvalue_fields) - } else { - T::LValue_::UnpackVariant(mident, enum_, variant, tyargs, lvalue_fields) - }; - let rhs_ty = rhs.ty.clone(); - let rhs: Box = Box::new(rhs.into_move_exp()); - let binder = T::SequenceItem_::Bind( - sp(rhs_loc, vec![sp(rhs_loc, unpack_lvalue_)]), - vec![Some(rhs_ty)], - rhs, - ); - sp(rhs_loc, binder) -} - -fn make_arm_struct_unpack_stmt( - mut_ref: Option, - mident: ModuleIdent, - struct_: DatatypeName, - tyargs: Vec, - fields: Vec<(Field, Var, Type)>, - rhs: FringeEntry, -) -> T::SequenceItem { - let rhs_loc = rhs.var.loc; - let mut lvalue_fields: Fields<(Type, T::LValue)> = UniqueMap::new(); - - for (ndx, (field_name, var, ty)) in fields.into_iter().enumerate() { - let var_lvalue = make_lvalue(var, Mutability::Imm, ty.clone()); - let lhs_ty = sp(ty.loc, ty.value.base_type_()); - lvalue_fields - .add(field_name, (ndx, (lhs_ty, var_lvalue))) - .unwrap(); - } - - let unpack_lvalue_ = if let Some(mut_) = mut_ref { - T::LValue_::BorrowUnpack(mut_, mident, struct_, tyargs, lvalue_fields) - } else { - T::LValue_::Unpack(mident, struct_, tyargs, lvalue_fields) - }; - let rhs_ty = rhs.ty.clone(); - let rhs: Box = Box::new(rhs.into_move_exp()); - let binder = T::SequenceItem_::Bind( - sp(rhs_loc, vec![sp(rhs_loc, unpack_lvalue_)]), - vec![Some(rhs_ty)], - rhs, - ); - sp(rhs_loc, binder) -} - -fn make_match_lit(subject: FringeEntry) -> T::Exp { - let FringeEntry { var, ty } = subject; - match ty { - sp!(ty_loc, N::Type_::Ref(false, inner)) => { - let loc = var.loc; - let copy_exp = make_copy_exp(sp(ty_loc, N::Type_::Ref(false, inner.clone())), loc, var); - make_deref_exp(*inner, loc, copy_exp) - } - sp!(_, N::Type_::Ref(true, inner)) => { - let loc = var.loc; - - // NB(cswords): we now freeze the mut ref at the non-mut ref type. - let ref_ty = sp(loc, N::Type_::Ref(true, inner.clone())); - let freeze_arg = make_copy_exp(ref_ty, loc, var); - let freeze_ty = sp(loc, N::Type_::Ref(false, inner.clone())); - let frozen_exp = make_freeze_exp(freeze_ty, loc, freeze_arg); - make_deref_exp(*inner, loc, frozen_exp) - } - _ty => unreachable!(), - } -} - -fn make_copy_bindings(bindings: PatBindings, next: T::Exp) -> T::Exp { - make_bindings(bindings, next, true) -} - -fn make_bindings(bindings: PatBindings, next: T::Exp, as_copy: bool) -> T::Exp { - let eloc = next.exp.loc; - let mut seq = VecDeque::new(); - for (lhs, (mut_, rhs)) in bindings { - let binding = if as_copy { - make_copy_binding(lhs, mut_, rhs.ty.clone(), rhs) - } else { - make_move_binding(lhs, mut_, rhs.ty.clone(), rhs) - }; - seq.push_back(binding); - } - let result_type = next.ty.clone(); - seq.push_back(sp(eloc, T::SequenceItem_::Seq(Box::new(next)))); - let exp_value = sp(eloc, T::UnannotatedExp_::Block((UseFuns::new(0), seq))); - T::exp(result_type, exp_value) -} - -fn make_lvalue(lhs: Var, mut_: Mutability, ty: Type) -> T::LValue { - let lhs_loc = lhs.loc; - let lhs_var = T::LValue_::Var { - var: lhs, - ty: Box::new(ty.clone()), - mut_: Some(mut_), - unused_binding: false, - }; - sp(lhs_loc, lhs_var) -} - -fn make_move_binding(lhs: Var, mut_: Mutability, ty: Type, rhs: FringeEntry) -> T::SequenceItem { - let lhs_loc = lhs.loc; - let lhs_lvalue = make_lvalue(lhs, mut_, ty.clone()); - let binder = T::SequenceItem_::Bind( - sp(lhs_loc, vec![lhs_lvalue]), - vec![Some(ty)], - Box::new(rhs.into_move_exp()), - ); - sp(lhs_loc, binder) -} - -fn make_copy_binding(lhs: Var, mut_: Mutability, ty: Type, rhs: FringeEntry) -> T::SequenceItem { - let lhs_loc = lhs.loc; - let lhs_lvalue = make_lvalue(lhs, mut_, ty.clone()); - let binder = T::SequenceItem_::Bind( - sp(lhs_loc, vec![lhs_lvalue]), - vec![Some(ty.clone())], - Box::new(make_copy_exp(ty, rhs.var.loc, rhs.var)), - ); - sp(lhs_loc, binder) -} - -fn make_lit_test(lit_exp: T::Exp, value: Value) -> T::Exp { - let loc = value.loc; - let value_exp = T::exp( - lit_exp.ty.clone(), - sp(loc, T::UnannotatedExp_::Value(value)), - ); - make_eq_test(loc, lit_exp, value_exp) -} - -// Since these are guards, we need to borrow the constant -fn make_const_test(ty: N::Type, var: N::Var, loc: Loc, m: ModuleIdent, c: ConstantName) -> T::Exp { - use T::UnannotatedExp_ as E; - let base_ty = sp(loc, ty.value.base_type_()); - let ref_ty = sp(loc, N::Type_::Ref(false, Box::new(base_ty.clone()))); - let var_exp = T::exp( - ref_ty.clone(), - sp( - loc, - E::Move { - from_user: false, - var, - }, - ), - ); - let const_exp = { - // We're in a guard, so we need to borrow the constant immutable. - let const_exp = T::exp(base_ty, sp(loc, E::Constant(m, c))); - let borrow_exp = E::TempBorrow(false, Box::new(const_exp)); - Box::new(T::exp(ref_ty, sp(loc, borrow_exp))) - }; - make_eq_test(loc, var_exp, *const_exp) -} - -fn make_eq_test(loc: Loc, lhs: T::Exp, rhs: T::Exp) -> T::Exp { - let bool = N::Type_::bool(loc); - let equality_exp_ = T::UnannotatedExp_::BinopExp( - Box::new(lhs), - sp(loc, BinOp_::Eq), - Box::new(bool.clone()), - Box::new(rhs), - ); - T::exp(bool, sp(loc, equality_exp_)) -} - -fn make_and_test(loc: Loc, lhs: T::Exp, rhs: T::Exp) -> T::Exp { - let bool = N::Type_::bool(loc); - let equality_exp_ = T::UnannotatedExp_::BinopExp( - Box::new(lhs), - sp(loc, BinOp_::And), - Box::new(bool.clone()), - Box::new(rhs), - ); - T::exp(bool, sp(loc, equality_exp_)) -} - -fn make_if_else(test: T::Exp, conseq: T::Exp, alt: T::Exp, result_ty: Type) -> T::Exp { - // FIXME: this span is woefully wrong - let loc = test.exp.loc; - T::exp( - result_ty, - sp( - loc, - T::UnannotatedExp_::IfElse(Box::new(test), Box::new(conseq), Box::new(alt)), - ), - ) -} - -fn make_copy_exp(ty: Type, loc: Loc, var: Var) -> T::Exp { - let exp_ = T::UnannotatedExp_::Copy { - var, - from_user: false, - }; - T::exp(ty, sp(loc, exp_)) -} - -fn make_freeze_exp(ty: Type, loc: Loc, arg: T::Exp) -> T::Exp { - let freeze_fn = Box::new(sp(loc, T::BuiltinFunction_::Freeze(ty.clone()))); - let freeze_exp = T::UnannotatedExp_::Builtin(freeze_fn, Box::new(arg)); - T::exp(ty, sp(loc, freeze_exp)) -} - -fn make_deref_exp(ty: Type, loc: Loc, arg: T::Exp) -> T::Exp { - let deref_exp = T::UnannotatedExp_::Dereference(Box::new(arg)); - T::exp(ty, sp(loc, deref_exp)) -} - -//------------------------------------------------ -// Counterexample Generation -//------------------------------------------------ - -#[derive(Clone, Debug)] -enum CounterExample { - Wildcard, - Literal(String), - Struct( - DatatypeName, - /* is_positional */ bool, - Vec<(String, CounterExample)>, - ), - Variant( - DatatypeName, - VariantName, - /* is_positional */ bool, - Vec<(String, CounterExample)>, - ), - Note(String, Box), -} - -impl CounterExample { - fn into_notes(self) -> VecDeque { - match self { - CounterExample::Wildcard => VecDeque::new(), - CounterExample::Literal(_) => VecDeque::new(), - CounterExample::Note(s, next) => { - let mut notes = next.into_notes(); - notes.push_front(s.clone()); - notes - } - CounterExample::Variant(_, _, _, inner) => inner - .into_iter() - .flat_map(|(_, ce)| ce.into_notes()) - .collect::>(), - CounterExample::Struct(_, _, inner) => inner - .into_iter() - .flat_map(|(_, ce)| ce.into_notes()) - .collect::>(), - } - } -} - -impl Display for CounterExample { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - CounterExample::Wildcard => write!(f, "_"), - CounterExample::Literal(s) => write!(f, "{}", s), - CounterExample::Note(_, inner) => inner.fmt(f), - CounterExample::Struct(s, is_positional, args) => { - write!(f, "{}", s)?; - if *is_positional { - write!(f, "(")?; - write!( - f, - "{}", - args.iter() - .map(|(_name, arg)| { format!("{}", arg) }) - .collect::>() - .join(", ") - )?; - write!(f, ")") - } else { - write!(f, " {{ ")?; - write!( - f, - "{}", - args.iter() - .map(|(name, arg)| { format!("{}: {}", name, arg) }) - .collect::>() - .join(", ") - )?; - write!(f, " }}") - } - } - CounterExample::Variant(e, v, is_positional, args) => { - write!(f, "{}::{}", e, v)?; - if !args.is_empty() { - if *is_positional { - write!(f, "(")?; - write!( - f, - "{}", - args.iter() - .map(|(_name, arg)| { format!("{}", arg) }) - .collect::>() - .join(", ") - )?; - write!(f, ")") - } else { - write!(f, " {{ ")?; - write!( - f, - "{}", - args.iter() - .map(|(name, arg)| { format!("{}: {}", name, arg) }) - .collect::>() - .join(", ") - )?; - write!(f, " }}") - } - } else { - Ok(()) - } - } - } - } -} - -/// Returns true if it found a counter-example. Assumes all arms with guards have been removed from -/// the provided matrix. -fn find_counterexample( - context: &mut Context, - loc: Loc, - matrix: PatternMatrix, - has_guards: bool, -) -> bool { - // If the matrix is only errors (or empty), it was all error or something else (like typing) - // went wrong; no counterexample is required. - if !matrix.is_empty() && !matrix.patterns_empty() && matrix.all_errors() { - debug_print!(context.debug.match_counterexample, (msg "errors"), ("matrix" => matrix; dbg)); - assert!(context.env.has_errors()); - return true; - } - find_counterexample_impl(context, loc, matrix, has_guards) -} - -/// Returns true if it found a counter-example. -fn find_counterexample_impl( - context: &mut Context, - loc: Loc, - matrix: PatternMatrix, - has_guards: bool, -) -> bool { - fn make_wildcards(n: usize) -> Vec { - std::iter::repeat(CounterExample::Wildcard) - .take(n) - .collect() - } - - #[growing_stack] - fn counterexample_bool( - context: &mut Context, - matrix: PatternMatrix, - arity: u32, - ndx: &mut u32, - ) -> Option> { - let literals = matrix.first_list(); - assert!(literals.len() <= 2, "ICE match exhaustiveness failure"); - if literals.len() == 2 { - // Saturated - for lit in literals { - if let Some(counterexample) = - counterexample_rec(context, matrix.specialize_literal(&lit).1, arity - 1, ndx) - { - let lit_str = format!("{}", lit); - let result = [CounterExample::Literal(lit_str)] - .into_iter() - .chain(counterexample) - .collect(); - return Some(result); - } - } - None - } else { - let (_, default) = matrix.specialize_default(); - if let Some(counterexample) = counterexample_rec(context, default, arity - 1, ndx) { - if literals.is_empty() { - let result = [CounterExample::Wildcard] - .into_iter() - .chain(counterexample) - .collect(); - Some(result) - } else { - let mut unused = BTreeSet::from([Value_::Bool(true), Value_::Bool(false)]); - for lit in literals { - unused.remove(&lit.value); - } - let result = [CounterExample::Literal(format!( - "{}", - unused.first().unwrap() - ))] - .into_iter() - .chain(counterexample) - .collect(); - Some(result) - } - } else { - None - } - } - } - - #[growing_stack] - fn counterexample_builtin( - context: &mut Context, - matrix: PatternMatrix, - arity: u32, - ndx: &mut u32, - ) -> Option> { - // For all other non-literals, we don't consider a case where the constructors are - // saturated. - let literals = matrix.first_list(); - let (_, default) = matrix.specialize_default(); - if let Some(counterexample) = counterexample_rec(context, default, arity - 1, ndx) { - if literals.is_empty() { - let result = [CounterExample::Wildcard] - .into_iter() - .chain(counterexample) - .collect(); - Some(result) - } else { - let n_id = format!("_{}", ndx); - *ndx += 1; - let lit_str = { - let lit_len = literals.len() as u64; - let fmt_list = if lit_len > 4 { - let mut result = literals - .into_iter() - .take(3) - .map(|lit| lit.to_string()) - .collect::>(); - result.push(format!("{} other values", lit_len - 3)); - result - } else { - literals - .into_iter() - .map(|lit| lit.to_string()) - .collect::>() - }; - format_oxford_list!("or", "{}", fmt_list) - }; - let lit_msg = format!("When '{}' is not {}", n_id, lit_str); - let lit_ce = CounterExample::Note(lit_msg, Box::new(CounterExample::Literal(n_id))); - let result = [lit_ce].into_iter().chain(counterexample).collect(); - Some(result) - } - } else { - None - } - } - - #[growing_stack] - fn counterexample_datatype( - context: &mut Context, - matrix: PatternMatrix, - arity: u32, - ndx: &mut u32, - mident: ModuleIdent, - datatype_name: DatatypeName, - ) -> Option> { - debug_print!( - context.debug.match_counterexample, - (lines "matrix types" => &matrix.tys; verbose) - ); - if context.is_struct(&mident, &datatype_name) { - // For a struct, we only care if we destructure it. If we do, we want to specialize and - // recur. If we don't, we check it as a default specialization. - if let Some((ploc, arg_types)) = matrix.first_struct_ctors() { - let ctor_arity = arg_types.len() as u32; - let fringe_binders = context.make_imm_ref_match_binders(ploc, arg_types); - let is_positional = context.struct_is_positional(&mident, &datatype_name); - let names = fringe_binders - .iter() - .map(|(name, _, _)| name.to_string()) - .collect::>(); - let bind_tys = fringe_binders - .iter() - .map(|(_, _, ty)| ty) - .collect::>(); - let (_, inner_matrix) = matrix.specialize_struct(context, bind_tys); - if let Some(mut counterexample) = - counterexample_rec(context, inner_matrix, ctor_arity + arity - 1, ndx) - { - let ctor_args = counterexample - .drain(0..(ctor_arity as usize)) - .collect::>(); - assert!(ctor_args.len() == names.len()); - let output = [CounterExample::Struct( - datatype_name, - is_positional, - names.into_iter().zip(ctor_args).collect::>(), - )] - .into_iter() - .chain(counterexample) - .collect(); - Some(output) - } else { - // If we didn't find a counterexample in the destructuring cases, we're done. - None - } - } else { - let (_, default) = matrix.specialize_default(); - // `_` is a reasonable counterexample since we never unpacked this struct - if let Some(counterexample) = counterexample_rec(context, default, arity - 1, ndx) { - // If we didn't match any head constructor, `_` is a reasonable - // counter-example entry. - let mut result = vec![CounterExample::Wildcard]; - result.extend(&mut counterexample.into_iter()); - Some(result) - } else { - None - } - } - } else { - let mut unmatched_variants = context - .enum_variants(&mident, &datatype_name) - .into_iter() - .collect::>(); - - let ctors = matrix.first_variant_ctors(); - for ctor in ctors.keys() { - unmatched_variants.remove(ctor); - } - if unmatched_variants.is_empty() { - for (ctor, (ploc, arg_types)) in ctors { - let ctor_arity = arg_types.len() as u32; - let fringe_binders = context.make_imm_ref_match_binders(ploc, arg_types); - let is_positional = - context.enum_variant_is_positional(&mident, &datatype_name, &ctor); - let names = fringe_binders - .iter() - .map(|(name, _, _)| name.to_string()) - .collect::>(); - let bind_tys = fringe_binders - .iter() - .map(|(_, _, ty)| ty) - .collect::>(); - let (_, inner_matrix) = matrix.specialize_variant(context, &ctor, bind_tys); - if let Some(mut counterexample) = - counterexample_rec(context, inner_matrix, ctor_arity + arity - 1, ndx) - { - let ctor_args = counterexample - .drain(0..(ctor_arity as usize)) - .collect::>(); - assert!(ctor_args.len() == names.len()); - let output = [CounterExample::Variant( - datatype_name, - ctor, - is_positional, - names - .into_iter() - .zip(ctor_args.into_iter()) - .collect::>(), - )] - .into_iter() - .chain(counterexample) - .collect(); - return Some(output); - } - } - None - } else { - let (_, default) = matrix.specialize_default(); - if let Some(counterexample) = counterexample_rec(context, default, arity - 1, ndx) { - if ctors.is_empty() { - // If we didn't match any head constructor, `_` is a reasonable - // counter-example entry. - let mut result = vec![CounterExample::Wildcard]; - result.extend(&mut counterexample.into_iter()); - Some(result) - } else { - let variant_name = unmatched_variants.first().unwrap(); - let is_positional = context.enum_variant_is_positional( - &mident, - &datatype_name, - variant_name, - ); - let ctor_args = context - .enum_variant_fields(&mident, &datatype_name, variant_name) - .unwrap(); - let names = ctor_args - .iter() - .map(|(_, field, _)| field.to_string()) - .collect::>(); - let ctor_arity = names.len(); - let result = [CounterExample::Variant( - datatype_name, - *variant_name, - is_positional, - names.into_iter().zip(make_wildcards(ctor_arity)).collect(), - )] - .into_iter() - .chain(counterexample) - .collect(); - Some(result) - } - } else { - // If we are missing a variant but everything else is fine, we're done. - None - } - } - } - } - - // \mathcal{I} from Maranget. Warning for pattern matching. 1992. - #[growing_stack] - fn counterexample_rec( - context: &mut Context, - matrix: PatternMatrix, - arity: u32, - ndx: &mut u32, - ) -> Option> { - debug_print!(context.debug.match_counterexample, ("checking matrix" => matrix; verbose)); - let result = if matrix.patterns_empty() { - None - } else if let Some(ty) = matrix.tys.first() { - if let Some(sp!(_, BuiltinTypeName_::Bool)) = ty.value.unfold_to_builtin_type_name() { - counterexample_bool(context, matrix, arity, ndx) - } else if let Some(_builtin) = ty.value.unfold_to_builtin_type_name() { - counterexample_builtin(context, matrix, arity, ndx) - } else if let Some((mident, datatype_name)) = ty - .value - .unfold_to_type_name() - .and_then(|sp!(_, name)| name.datatype_name()) - { - counterexample_datatype(context, matrix, arity, ndx, mident, datatype_name) - } else { - // This can only be a binding or wildcard, so we act accordingly. - let (_, default) = matrix.specialize_default(); - if let Some(counterexample) = counterexample_rec(context, default, arity - 1, ndx) { - let result = [CounterExample::Wildcard] - .into_iter() - .chain(counterexample) - .collect(); - Some(result) - } else { - None - } - } - } else { - assert!(matrix.is_empty()); - Some(make_wildcards(arity as usize)) - }; - debug_print!(context.debug.match_counterexample, (opt "result" => &result; sdbg)); - result - } - - let mut ndx = 0; - - if let Some(mut counterexample) = counterexample_rec(context, matrix, 1, &mut ndx) { - debug_print!( - context.debug.match_counterexample, - ("counterexamples #" => counterexample.len(); fmt), - (lines "counterexamples" => &counterexample; fmt) - ); - assert!(counterexample.len() == 1); - let counterexample = counterexample.remove(0); - let msg = format!("Pattern '{}' not covered", counterexample); - let mut diag = diag!(TypeSafety::IncompletePattern, (loc, msg)); - for note in counterexample.into_notes() { - diag.add_note(note); - } - if has_guards { - diag.add_note("Match arms with guards are not considered for coverage."); - } - context.env.add_diag(diag); - true - } else { - false - } -} - -//------------------------------------------------ -// IDE Arm Suggestion Generation -//------------------------------------------------ - -/// Produces IDE information if the top-level match is incomplete. Assumes all arms with guards -/// have been removed from the provided matrix. -fn ide_report_missing_arms(context: &mut Context, loc: Loc, matrix: &PatternMatrix) { - use PatternSuggestion as PS; - // This function looks at the very top-level of the match. For any arm missing, it suggests the - // IDE add an arm to address that missing one. - - fn report_bool(context: &mut Context, loc: Loc, matrix: &PatternMatrix) { - let literals = matrix.first_list(); - assert!(literals.len() <= 2, "ICE match exhaustiveness failure"); - // Figure out which are missing - let mut unused = BTreeSet::from([Value_::Bool(true), Value_::Bool(false)]); - for lit in literals { - unused.remove(&lit.value); - } - if !unused.is_empty() { - let arms = unused.into_iter().map(PS::Value).collect::>(); - let info = MissingMatchArmsInfo { arms }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); - } - } - - fn report_builtin(context: &mut Context, loc: Loc, matrix: &PatternMatrix) { - // For all other non-literals, we don't consider a case where the constructors are - // saturated. If it doesn't have a wildcard, we suggest adding a wildcard. - if !matrix.has_default_arm() { - let info = MissingMatchArmsInfo { - arms: vec![PS::Wildcard], - }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); - } - } - - fn report_datatype( - context: &mut Context, - loc: Loc, - matrix: &PatternMatrix, - mident: ModuleIdent, - name: DatatypeName, - ) { - if context.is_struct(&mident, &name) { - if !matrix.is_empty() { - // If the matrix isn't empty, we _must_ have matched the struct with at least one - // non-guard arm (either wildcards or the struct itself), so we're fine. - return; - } - // If the matrix _is_ empty, we suggest adding an unpack. - let is_positional = context.struct_is_positional(&mident, &name); - let Some(fields) = context.struct_fields(&mident, &name) else { - context.env.add_diag(ice!(( - loc, - "Tried to look up fields for this struct and found none" - ))); - return; - }; - // NB: We might not have a concrete type for the type parameters to the datatype (due - // to type errors or otherwise), so we use stand-in types. Since this is IDE - // information that should be inserted and then re-compiled, this should work for our - // purposes. - - let suggestion = if is_positional { - PS::UnpackPositionalStruct { - module: mident, - name, - field_count: fields.len(), - } - } else { - PS::UnpackNamedStruct { - module: mident, - name, - fields: fields.into_iter().map(|(field, _)| field.value()).collect(), - } - }; - let info = MissingMatchArmsInfo { - arms: vec![suggestion], - }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); - } else { - // If there's a default arm, no suggestion is necessary. - if matrix.has_default_arm() { - return; - } - - let mut unmatched_variants = context - .enum_variants(&mident, &name) - .into_iter() - .collect::>(); - let ctors = matrix.first_variant_ctors(); - for ctor in ctors.keys() { - unmatched_variants.remove(ctor); - } - // If all of the variants were matched, no suggestion is necessary. - if unmatched_variants.is_empty() { - return; - } - let mut arms = vec![]; - // re-iterate the original so we generate these in definition order - for variant in context.enum_variants(&mident, &name).into_iter() { - if !unmatched_variants.contains(&variant) { - continue; - } - let is_empty = context.enum_variant_is_empty(&mident, &name, &variant); - let is_positional = context.enum_variant_is_positional(&mident, &name, &variant); - let Some(fields) = context.enum_variant_fields(&mident, &name, &variant) else { - context.env.add_diag(ice!(( - loc, - "Tried to look up fields for this enum and found none" - ))); - continue; - }; - let suggestion = if is_empty { - PS::UnpackEmptyVariant { - module: mident, - enum_name: name, - variant_name: variant, - } - } else if is_positional { - PS::UnpackPositionalVariant { - module: mident, - enum_name: name, - variant_name: variant, - field_count: fields.len(), - } - } else { - PS::UnpackNamedVariant { - module: mident, - enum_name: name, - variant_name: variant, - fields: fields.into_iter().map(|(field, _)| field.value()).collect(), - } - }; - arms.push(suggestion); - } - let info = MissingMatchArmsInfo { arms }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); - } - } - - let Some(ty) = matrix.tys.first() else { - context.env.add_diag(ice!(( - loc, - "Pattern matrix with no types handed to IDE function" - ))); - return; - }; - if let Some(sp!(_, BuiltinTypeName_::Bool)) = &ty.value.unfold_to_builtin_type_name() { - report_bool(context, loc, matrix) - } else if let Some(_builtin) = ty.value.unfold_to_builtin_type_name() { - report_builtin(context, loc, matrix) - } else if let Some((mident, datatype_name)) = ty - .value - .unfold_to_type_name() - .and_then(|sp!(_, name)| name.datatype_name()) - { - report_datatype(context, loc, matrix, mident, datatype_name) - } else { - if !context.env.has_errors() { - // It's unclear how we got here, so report an ICE and suggest a wildcard. - context.env.add_diag(ice!(( - loc, - format!( - "Found non-matchable type {} as match subject", - error_format(ty, &Subst::empty()) - ) - ))); - } - if !matrix.has_default_arm() { - let info = MissingMatchArmsInfo { - arms: vec![PS::Wildcard], - }; - context - .env - .add_ide_annotation(loc, IDEAnnotation::MissingMatchArms(Box::new(info))); - } - } -} - -//************************************************************************************************** -// Debug Print -//************************************************************************************************** - -impl AstDebug for PatternMatrix { - fn ast_debug(&self, w: &mut AstWriter) { - for arm in &self.patterns { - let PatternArm { - pats: pat, - guard, - arm, - } = arm; - w.write(" { "); - w.comma(pat, |w, p| p.ast_debug(w)); - w.write(" } =>"); - if let Some(guard) = guard { - w.write(" if "); - guard.ast_debug(w); - } - w.write(" ["); - w.write(format!("] arm {}\n", arm.index)); - } - } -} - -impl AstDebug for FringeEntry { - fn ast_debug(&self, w: &mut AstWriter) { - w.write(format!("{:?} : ", self.var)); - self.ty.ast_debug(w); - } -} diff --git a/external-crates/move/crates/move-compiler/src/typing/recursive_datatypes.rs b/external-crates/move/crates/move-compiler/src/typing/recursive_datatypes.rs index 76c258f05eb..629fa484709 100644 --- a/external-crates/move/crates/move-compiler/src/typing/recursive_datatypes.rs +++ b/external-crates/move/crates/move-compiler/src/typing/recursive_datatypes.rs @@ -57,7 +57,7 @@ impl Context { //************************************************************************************************** pub fn modules( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, modules: &UniqueMap, ) { modules @@ -65,7 +65,8 @@ pub fn modules( .for_each(|(mname, m)| module(compilation_env, mname, m)) } -fn module(compilation_env: &mut CompilationEnv, mname: ModuleIdent, module: &T::ModuleDefinition) { +fn module(compilation_env: &CompilationEnv, mname: ModuleIdent, module: &T::ModuleDefinition) { + let reporter = compilation_env.diagnostic_reporter_at_top_level(); let context = &mut Context::new(mname); module .structs @@ -82,7 +83,7 @@ fn module(compilation_env: &mut CompilationEnv, mname: ModuleIdent, module: &T:: petgraph_scc(&graph) .into_iter() .filter(|scc| scc.len() > 1 || graph.contains_edge(scc[0], scc[0])) - .for_each(|scc| compilation_env.add_diag(cycle_error(context, &graph, scc[0]))) + .for_each(|scc| reporter.add_diag(cycle_error(context, &graph, scc[0]))) } fn struct_def(context: &mut Context, sname: DatatypeName, sdef: &N::StructDefinition) { diff --git a/external-crates/move/crates/move-compiler/src/typing/syntax_methods.rs b/external-crates/move/crates/move-compiler/src/typing/syntax_methods.rs index 24f3b4264af..cd03f7b7eac 100644 --- a/external-crates/move/crates/move-compiler/src/typing/syntax_methods.rs +++ b/external-crates/move/crates/move-compiler/src/typing/syntax_methods.rs @@ -77,7 +77,7 @@ fn validate_index_syntax_methods( diag.add_note( "Index operations on the same type must take the name number of type arguments", ); - context.env.add_diag(diag); + context.add_diag(diag); return false; } @@ -96,7 +96,7 @@ fn validate_index_syntax_methods( (index_mut.loc, index_mut_msg), ); diag.add_note("Index operations on the same type must take the name number of parameters"); - context.env.add_diag(diag); + context.add_diag(diag); return false; } @@ -125,7 +125,7 @@ fn validate_index_syntax_methods( diag.add_note( "Index operations on use the same abilities for their type parameters", ); - context.env.add_diag(diag); + context.add_diag(diag); valid = false; } } @@ -146,7 +146,7 @@ fn validate_index_syntax_methods( diag.add_note( "Index operations on use the same abilities for their type parameters", ); - context.env.add_diag(diag); + context.add_diag(diag); valid = false; } } @@ -191,9 +191,12 @@ fn validate_index_syntax_methods( // subtype of the `&` param. We already ensured they were both references of // the appropriate shape in naming, so this is a bit redundant. if let Some((ndx, (subject_ref_type, subject_mut_ref_type))) = param_tys.next() { - if let Ok((subst_, _)) = - core::subtype(subst.clone(), subject_mut_ref_type, subject_ref_type) - { + if let Ok((subst_, _)) = core::subtype( + &mut context.tvar_counter, + subst.clone(), + subject_mut_ref_type, + subject_ref_type, + ) { subst = subst_; } else { let (_, _, index_type) = &index_finfo.signature.parameters[ndx]; @@ -207,7 +210,7 @@ fn validate_index_syntax_methods( let N::Type_::Ref(false, inner) = core::ready_tvars(&subst, subject_ref_type.clone()).value else { - context.env.add_diag(ice!(( + context.add_diag(ice!(( index_finfo.signature.return_type.loc, "This index function got to type verification with an invalid type" ))); @@ -235,7 +238,7 @@ fn validate_index_syntax_methods( diag.add_note( "These functions must take the same subject type, differing only by mutability", ); - context.env.add_diag(diag); + context.add_diag(diag); valid = false; } } else { @@ -244,7 +247,9 @@ fn validate_index_syntax_methods( // We ensure the rest of the parameters match exactly. for (ndx, (ptype, mut_ptype)) in param_tys { - if let Ok((subst_, _)) = core::invariant(subst.clone(), ptype, mut_ptype) { + if let Ok((subst_, _)) = + core::invariant(&mut context.tvar_counter, subst.clone(), ptype, mut_ptype) + { subst = subst_; } else { let (_, _, index_type) = &index_finfo.signature.parameters[ndx]; @@ -269,7 +274,7 @@ fn validate_index_syntax_methods( &mut_finfo.signature.type_parameters, ); diag.add_note("Index operation non-subject parameter types must match exactly"); - context.env.add_diag(diag); + context.add_diag(diag); valid = false; } } @@ -278,6 +283,7 @@ fn validate_index_syntax_methods( // already checked that they are appropriately-shaped references, and now we // ensure they refer to the same type under the reference. if core::subtype( + &mut context.tvar_counter, subst.clone(), &mut_finfo.signature.return_type, &index_ty.return_, @@ -289,7 +295,7 @@ fn validate_index_syntax_methods( let index_msg = format!("This index function returns type {}", ty_str(index_type)); let N::Type_::Ref(false, inner) = core::ready_tvars(&subst, index_ty.return_.clone()).value else { - context.env.add_diag(ice!(( + context.add_diag(ice!(( index_finfo.signature.return_type.loc, "This index function got to type verification with an invalid type" ))); @@ -315,7 +321,7 @@ fn validate_index_syntax_methods( &mut_finfo.signature.type_parameters, ); diag.add_note("These functions must return the same type, differing only by mutability"); - context.env.add_diag(diag); + context.add_diag(diag); valid = false; } diff --git a/external-crates/move/crates/move-compiler/src/typing/translate.rs b/external-crates/move/crates/move-compiler/src/typing/translate.rs index 386d187e2a7..384cc1679bc 100644 --- a/external-crates/move/crates/move-compiler/src/typing/translate.rs +++ b/external-crates/move/crates/move-compiler/src/typing/translate.rs @@ -10,19 +10,20 @@ use std::{ use move_ir_types::location::*; use move_proc_macros::growing_stack; +use rayon::prelude::*; use crate::{ - diag, - diagnostics::{codes::*, Diagnostic}, + FullyCompiledProgram, diag, + diagnostics::{Diagnostic, codes::*}, editions::{FeatureGate, Flavor}, expansion::ast::{ - AbilitySet, Attribute, AttributeValue_, Attribute_, DottedUsage, Fields, Friend, + AbilitySet, Attribute, Attribute_, AttributeValue_, DottedUsage, Fields, Friend, ModuleAccess_, ModuleIdent, ModuleIdent_, Mutability, TargetKind, Value_, Visibility, }, - ice, iota_mode, + ice, ice_assert, iota_mode, naming::ast::{ self as N, BlockLabel, DatatypeTypeParameter, IndexSyntaxMethods, TParam, TParamID, Type, - TypeName, TypeName_, Type_, + Type_, TypeName, TypeName_, }, parser::ast::{ Ability_, BinOp, BinOp_, ConstantName, DatatypeName, Field, FunctionName, UnaryOp_, @@ -40,14 +41,13 @@ use crate::{ typing::{ ast::{self as T}, core::{ - self, public_testing_visibility, report_visibility_error, Context, PublicForTesting, - ResolvedFunctionType, Subst, + self, Context, PublicForTesting, ResolvedFunctionType, Subst, + public_testing_visibility, report_visibility_error, }, dependency_ordering, expand, infinite_instantiations, macro_expand, match_analysis, recursive_datatypes, syntax_methods::validate_syntax_methods, }, - FullyCompiledProgram, }; //************************************************************************************************** @@ -55,12 +55,13 @@ use crate::{ //************************************************************************************************** pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: N::Program, ) -> T::Program { let N::Program { info, + warning_filters_table, inner: N::Program_ { modules: nmodules }, } = prog; let mut context = Box::new(Context::new( @@ -83,15 +84,18 @@ pub fn program( .into_iter() .map(|(mident, minfo)| (mident, minfo.use_funs)) .collect(); - let module_info = TypingProgramInfo::new(pre_compiled_lib, &modules, module_use_funs); - let mut prog = T::Program { + let module_info = + TypingProgramInfo::new(compilation_env, pre_compiled_lib, &modules, module_use_funs); + let prog = T::Program { modules, + warning_filters_table, info: Arc::new(module_info), }; - for v in &compilation_env.visitors().typing { - let mut v = v.borrow_mut(); - v.visit(compilation_env, &mut prog); - } + compilation_env + .visitors() + .typing + .par_iter() + .for_each(|v| v.visit(compilation_env, &prog)); prog } @@ -230,7 +234,7 @@ fn module( } = mdef; context.current_module = Some(ident); context.current_package = package_name; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); context.add_use_funs_scope(use_funs); structs .iter_mut() @@ -242,7 +246,7 @@ fn module( assert!(context.constraints.is_empty()); context.current_package = None; let use_funs = context.pop_use_funs_scope(); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); let typed_module = T::ModuleDefinition { loc, warning_filter, @@ -274,7 +278,7 @@ fn finalize_ide_info(context: &mut Context) { for (_loc, ann) in info.iter_mut() { expand::ide_annotation(context, ann); } - context.env.extend_ide_info(info); + context.extend_ide_info(info); } //************************************************************************************************** @@ -286,13 +290,14 @@ fn function(context: &mut Context, name: FunctionName, f: N::Function) -> T::Fun warning_filter, index, attributes, + loc, visibility, entry, macro_, mut signature, body: n_body, } = f; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); assert!(context.constraints.is_empty()); context.reset_for_module_item(name.loc()); context.current_function = Some(name); @@ -313,11 +318,12 @@ fn function(context: &mut Context, name: FunctionName, f: N::Function) -> T::Fun finalize_ide_info(context); context.current_function = None; context.in_macro_function = false; - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); T::Function { warning_filter, index, attributes, + loc, compiled_visibility, visibility, entry, @@ -396,7 +402,7 @@ fn constant(context: &mut Context, name: ConstantName, nconstant: N::Constant) - signature, value: nvalue, } = nconstant; - context.env.add_warning_filter_scope(warning_filter.clone()); + context.push_warning_filter_scope(warning_filter); process_attributes(context, &attributes); @@ -429,7 +435,7 @@ fn constant(context: &mut Context, name: ConstantName, nconstant: N::Constant) - if context.env.ide_mode() { finalize_ide_info(context); } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); T::Constant { warning_filter, @@ -507,9 +513,7 @@ mod check_valid_constant { core::error_format(ty, &Subst::empty()), format_comma(tys), ); - context - .env - .add_diag(diag!(code, (sloc, fmsg()), (loc, tmsg))) + context.add_diag(diag!(code, (sloc, fmsg()), (loc, tmsg))) } pub fn exp(context: &mut Context, e: &T::Exp) { @@ -576,10 +580,12 @@ mod check_valid_constant { s = format!("'{}' is", b); &s } - E::IfElse(eb, et, ef) => { + E::IfElse(eb, et, ef_opt) => { exp(context, eb); exp(context, et); - exp(context, ef); + if let Some(ef) = ef_opt { + exp(context, ef) + } "'if' expressions are" } E::Match(esubject, sp!(_, arms)) => { @@ -593,7 +599,7 @@ mod check_valid_constant { "'match' expressions are" } E::VariantMatch(_subject, _, _arms) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( *loc, "shouldn't find variant match before match compilation" ))); @@ -646,7 +652,7 @@ mod check_valid_constant { "Enum variants are" } }; - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::UnsupportedConstant, (*loc, format!("{} not supported in constants", error_case)) )); @@ -693,9 +699,7 @@ mod check_valid_constant { } }; let msg = format!("{} are not supported in constants", error_case); - context - .env - .add_diag(diag!(TypeSafety::UnsupportedConstant, (*loc, msg),)) + context.add_diag(diag!(TypeSafety::UnsupportedConstant, (*loc, msg),)) } } @@ -706,9 +710,7 @@ mod check_valid_constant { fn struct_def(context: &mut Context, sloc: Loc, s: &mut N::StructDefinition) { assert!(context.constraints.is_empty()); context.reset_for_module_item(sloc); - context - .env - .add_warning_filter_scope(s.warning_filter.clone()); + context.push_warning_filter_scope(s.warning_filter); let field_map = match &mut s.fields { N::StructFields::Native(_) => return, @@ -751,15 +753,13 @@ fn struct_def(context: &mut Context, sloc: Loc, s: &mut N::StructDefinition) { expand::type_(context, &mut idx_ty.1); } check_type_params_usage(context, &s.type_parameters, field_map); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } fn enum_def(context: &mut Context, enum_: &mut N::EnumDefinition) { assert!(context.constraints.is_empty()); - context - .env - .add_warning_filter_scope(enum_.warning_filter.clone()); + context.push_warning_filter_scope(enum_.warning_filter); let enum_abilities = &enum_.abilities; let enum_type_params = &enum_.type_parameters; @@ -772,7 +772,7 @@ fn enum_def(context: &mut Context, enum_: &mut N::EnumDefinition) { } check_variant_type_params_usage(context, enum_type_params, field_types); - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } fn variant_def( @@ -1033,7 +1033,7 @@ fn invalid_phantom_use_error( } }; let decl_msg = format!("'{}' declared here as phantom", ¶m.user_specified_name); - context.env.add_diag(diag!( + context.add_diag(diag!( Declarations::InvalidPhantomUse, (ty_loc, msg), (param.user_specified_name.loc, decl_msg), @@ -1052,9 +1052,7 @@ fn check_non_phantom_param_usage( "Unused type parameter '{}'. Consider declaring it as phantom", name ); - context - .env - .add_diag(diag!(UnusedItem::StructTypeParam, (name.loc, msg))) + context.add_diag(diag!(UnusedItem::StructTypeParam, (name.loc, msg))) } Some(false) => { let msg = format!( @@ -1062,9 +1060,7 @@ fn check_non_phantom_param_usage( adding a phantom declaration here", name ); - context - .env - .add_diag(diag!(Declarations::InvalidNonPhantomUse, (name.loc, msg))) + context.add_diag(diag!(Declarations::InvalidNonPhantomUse, (name.loc, msg))) } Some(true) => {} } @@ -1224,7 +1220,7 @@ fn subtype_no_report( let subst = std::mem::replace(&mut context.subst, Subst::empty()); let lhs = core::ready_tvars(&subst, pre_lhs); let rhs = core::ready_tvars(&subst, pre_rhs); - match core::subtype(subst.clone(), &lhs, &rhs) { + match core::subtype(&mut context.tvar_counter, subst.clone(), &lhs, &rhs) { Ok((next_subst, ty)) => { context.subst = next_subst; Ok(ty) @@ -1246,11 +1242,11 @@ fn subtype_impl T>( let subst = std::mem::replace(&mut context.subst, Subst::empty()); let lhs = core::ready_tvars(&subst, pre_lhs); let rhs = core::ready_tvars(&subst, pre_rhs); - match core::subtype(subst.clone(), &lhs, &rhs) { + match core::subtype(&mut context.tvar_counter, subst.clone(), &lhs, &rhs) { Err(e) => { context.subst = subst; let diag = typing_error(context, /* from_subtype */ true, loc, msg, e); - context.env.add_diag(diag); + context.add_diag(diag); Err(rhs) } Ok((next_subst, ty)) => { @@ -1296,11 +1292,11 @@ fn join_opt T>( let subst = std::mem::replace(&mut context.subst, Subst::empty()); let t1 = core::ready_tvars(&subst, pre_t1); let t2 = core::ready_tvars(&subst, pre_t2); - match core::join(subst.clone(), &t1, &t2) { + match core::join(&mut context.tvar_counter, subst.clone(), &t1, &t2) { Err(e) => { context.subst = subst; let diag = typing_error(context, /* from_subtype */ false, loc, msg, e); - context.env.add_diag(diag); + context.add_diag(diag); None } Ok((next_subst, ty)) => { @@ -1331,7 +1327,7 @@ fn invariant_no_report( let subst = std::mem::replace(&mut context.subst, Subst::empty()); let lhs = core::ready_tvars(&subst, pre_lhs); let rhs = core::ready_tvars(&subst, pre_rhs); - core::invariant(subst.clone(), &lhs, &rhs).map(|(next_subst, ty)| { + core::invariant(&mut context.tvar_counter, subst.clone(), &lhs, &rhs).map(|(next_subst, ty)| { context.subst = next_subst; ty }) @@ -1348,11 +1344,11 @@ fn invariant_impl T>( let subst = std::mem::replace(&mut context.subst, Subst::empty()); let lhs = core::ready_tvars(&subst, pre_lhs); let rhs = core::ready_tvars(&subst, pre_rhs); - match core::invariant(subst.clone(), &lhs, &rhs) { + match core::invariant(&mut context.tvar_counter, subst.clone(), &lhs, &rhs) { Err(e) => { context.subst = subst; let diag = typing_error(context, /* from_subtype */ false, loc, msg, e); - context.env.add_diag(diag); + context.add_diag(diag); Err(rhs) } Ok((next_subst, ty)) => { @@ -1486,13 +1482,10 @@ fn exp(context: &mut Context, ne: Box) -> Box { let sp!(eloc, ne_) = *ne; let (ty, e_) = match ne_ { - NE::ErrorConstant { line_number_loc } => ( - Type_::u64(eloc), - TE::ErrorConstant { - line_number_loc, - error_constant: None, - }, - ), + NE::ErrorConstant { line_number_loc } => (Type_::u64(eloc), TE::ErrorConstant { + line_number_loc, + error_constant: None, + }), NE::Unit { trailing } => (sp(eloc, Type_::Unit), TE::Unit { trailing }), NE::Value(sp!(vloc, Value_::InferredNum(v))) => ( core::make_num_tvar(context, eloc), @@ -1514,10 +1507,27 @@ fn exp(context: &mut Context, ne: Box) -> Box { let ty = context.get_local_type(&var); (ty, TE::Use(var)) } - NE::MethodCall(ndotted, f, /* is_macro */ None, ty_args_opt, sp!(argloc, nargs_)) => { + NE::MethodCall( + ndotted, + dot_loc, + f, + // is_macro + None, + ty_args_opt, + sp!(argloc, nargs_), + ) => { let edotted = process_exp_dotted(context, None, ndotted); let args = exp_vec(context, nargs_); - let ty_call_opt = method_call(context, eloc, edotted, f, ty_args_opt, argloc, args); + let ty_call_opt = method_call( + context, + eloc, + edotted, + f, + ty_args_opt, + argloc, + args, + dot_loc, + ); match ty_call_opt { None => { assert!(context.env.has_errors()); @@ -1530,7 +1540,14 @@ fn exp(context: &mut Context, ne: Box) -> Box { let args = exp_vec(context, nargs_); module_call(context, eloc, m, f, ty_args_opt, argloc, args) } - NE::MethodCall(ndotted, f, Some(macro_call_loc), ty_args_opt, sp!(argloc, nargs_)) => { + NE::MethodCall( + ndotted, + dot_loc, + f, + Some(macro_call_loc), + ty_args_opt, + sp!(argloc, nargs_), + ) => { let edotted = process_exp_dotted(context, None, ndotted); let ty_call_opt = macro_method_call( context, @@ -1541,6 +1558,7 @@ fn exp(context: &mut Context, ne: Box) -> Box { ty_args_opt, argloc, nargs_, + dot_loc, ); match ty_call_opt { None => { @@ -1579,7 +1597,7 @@ fn exp(context: &mut Context, ne: Box) -> Box { vector_pack(context, eloc, vec_loc, ty_opt, argloc, args_) } - NE::IfElse(nb, nt, nf) => { + NE::IfElse(nb, nt, nf_opt) => { let eb = exp(context, nb); let bloc = eb.exp.loc; subtype( @@ -1590,15 +1608,24 @@ fn exp(context: &mut Context, ne: Box) -> Box { Type_::bool(bloc), ); let et = exp(context, nt); - let ef = exp(context, nf); - let ty = join( - context, - eloc, - || "Incompatible branches", - et.ty.clone(), - ef.ty.clone(), - ); - (ty, TE::IfElse(eb, et, ef)) + let ef_opt = nf_opt.map(|nf| exp(context, nf)); + let ty = match &ef_opt { + Some(ef) => join( + context, + eloc, + || "Incompatible branches", + et.ty.clone(), + ef.ty.clone(), + ), + None => { + let ty = sp(eloc, Type_::Unit); + let msg = + "Invalid 'if'. The body of an 'if' without an 'else' must have type '()'"; + subtype(context, eloc, || msg, et.ty.clone(), ty.clone()); + ty + } + }; + (ty, TE::IfElse(eb, et, ef_opt)) } NE::Match(nsubject, sp!(aloc, narms_)) => { let esubject = exp(context, nsubject); @@ -1616,7 +1643,7 @@ fn exp(context: &mut Context, ne: Box) -> Box { } }; let result_type = core::make_tvar(context, aloc); - let earms = match_arms(context, &subject_type, &result_type, narms_, &ref_mut); + let earms = match_arms(context, &esubject.ty, &result_type, narms_, &ref_mut); (result_type, TE::Match(esubject, sp(aloc, earms))) } NE::While(name, nb, nloop) => { @@ -1669,14 +1696,9 @@ fn exp(context: &mut Context, ne: Box) -> Box { res } NE::Lambda(_) => { - if context - .env - .check_feature(context.current_package, FeatureGate::Lambda, eloc) - { + if context.check_feature(context.current_package, FeatureGate::Lambda, eloc) { let msg = "Lambdas can only be used directly as arguments to 'macro' functions"; - context - .env - .add_diag(diag!(TypeSafety::UnexpectedLambda, (eloc, msg))) + context.add_diag(diag!(TypeSafety::UnexpectedLambda, (eloc, msg))) } (context.error_type(eloc), TE::UnresolvedError) } @@ -2047,9 +2069,7 @@ fn binop( } Range | Implies | Iff => { - context - .env - .add_diag(ice!((loc, "ICE unexpected specification operator"))); + context.add_diag(ice!((loc, "ICE unexpect specification operator"))); (context.error_type(loc), context.error_type(loc)) } }; @@ -2189,17 +2209,14 @@ fn match_arm( result_type.clone(), ); - sp( - aloc, - T::MatchArm_ { - pattern, - binders, - guard, - guard_binders, - rhs_binders, - rhs, - }, - ) + sp(aloc, T::MatchArm_ { + pattern, + binders, + guard, + guard_binders, + rhs_binders, + rhs, + }) } fn match_pattern( @@ -2334,9 +2351,7 @@ fn match_pattern_( matched in the module in which they are declared", &m, &struct_, ); - context - .env - .add_diag(diag!(TypeSafety::Visibility, (loc, msg))); + context.add_diag(diag!(TypeSafety::Visibility, (loc, msg))); } let bt = rtype!(bt); let pat_ = if field_error { @@ -2630,13 +2645,10 @@ fn lvalue_list( context, loc, || { - format!( - "Invalid value for {}", - match case { - C::Bind => "binding", - C::Assign => "assignment", - } - ) + format!("Invalid value for {}", match case { + C::Bind => "binding", + C::Assign => "assignment", + }) }, ty, var_ty, @@ -2816,15 +2828,15 @@ fn check_mutation(context: &mut Context, loc: Loc, given_ref: Type, rvalue_ty: & //************************************************************************************************** fn resolve_field(context: &mut Context, loc: Loc, ty: Type, field: &Field) -> Type { - use TypeName_::*; use Type_::*; + use TypeName_::*; const UNINFERRED_MSG: &str = "Could not infer the type before field access. Try annotating here"; let msg = || format!("Unbound field '{}'", field); match core::ready_tvars(&context.subst, ty) { sp!(_, UnresolvedError) => context.error_type(loc), sp!(tloc, Anything) => { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::UninferredType, (loc, msg()), (tloc, UNINFERRED_MSG), @@ -2832,7 +2844,7 @@ fn resolve_field(context: &mut Context, loc: Loc, ty: Type, field: &Field) -> Ty context.error_type(loc) } sp!(tloc, Var(i)) if !context.subst.is_num_var(i) => { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::UninferredType, (loc, msg()), (tloc, UNINFERRED_MSG), @@ -2845,9 +2857,7 @@ fn resolve_field(context: &mut Context, loc: Loc, ty: Type, field: &Field) -> Ty "Invalid access of field '{field}' on the struct '{m}::{n}'. The field '{field}' can only \ be accessed within the module '{m}' since it defines '{n}'" ); - context - .env - .add_diag(diag!(TypeSafety::Visibility, (loc, msg))); + context.add_diag(diag!(TypeSafety::Visibility, (loc, msg))); } match context.datatype_kind(&m, &n) { DatatypeKind::Struct => { @@ -2859,9 +2869,7 @@ fn resolve_field(context: &mut Context, loc: Loc, ty: Type, field: &Field) -> Ty structs, not enums", field, &m, &n ); - context - .env - .add_diag(diag!(TypeSafety::ExpectedSpecificType, (loc, msg))); + context.add_diag(diag!(TypeSafety::ExpectedSpecificType, (loc, msg))); context.error_type(loc) } } @@ -2871,7 +2879,7 @@ fn resolve_field(context: &mut Context, loc: Loc, ty: Type, field: &Field) -> Ty "Expected a struct type in the current module but got: {}", core::error_format(&t, &context.subst) ); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::ExpectedSpecificType, (loc, msg()), (t.loc, smsg), @@ -2899,7 +2907,7 @@ fn add_struct_field_types( constructed/deconstructed, and their fields cannot be directly accessed", verb, m, n ); - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidNativeUsage, (loc, msg), (nloc, "Struct declared 'native' here") @@ -2910,15 +2918,13 @@ fn add_struct_field_types( for (_, f_, _) in &fields_ty { if fields.get_(f_).is_none() { let msg = format!("Missing {} for field '{}' in '{}::{}'", verb, f_, m, n); - context - .env - .add_diag(diag!(TypeSafety::TooFewArguments, (loc, msg))) + context.add_diag(diag!(TypeSafety::TooFewArguments, (loc, msg))) } } fields.map(|f, (idx, x)| { let fty = match fields_ty.remove(&f) { None => { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundField, (loc, format!("Unbound field '{}' in '{}::{}'", &f, m, n)) )); @@ -2945,14 +2951,12 @@ fn add_variant_field_types( N::VariantFields::Defined(_, m) => m, N::VariantFields::Empty => { if !fields.is_empty() { - let msg = format!( - "Invalid usage for empty variant '{}::{}::{}'. Empty variants do not take \ - any arguments.", - m, n, v + ice_assert!( + context.reporter, + context.env.has_errors(), + loc, + "Empty variant with fields but no error from naming" ); - context - .env - .add_diag(diag!(TypeSafety::TooManyArguments, (loc, msg),)); return fields.map(|f, (idx, x)| (idx, (context.error_type(f.loc()), x))); } else { return Fields::new(); @@ -2965,15 +2969,13 @@ fn add_variant_field_types( "Missing {} for field '{}' in '{}::{}::{}'", verb, f_, m, n, v ); - context - .env - .add_diag(diag!(TypeSafety::TooFewArguments, (loc, msg))) + context.add_diag(diag!(TypeSafety::TooFewArguments, (loc, msg))) } } fields.map(|f, (idx, x)| { let fty = match fields_ty.remove(&f) { None => { - context.env.add_diag(diag!( + context.add_diag(diag!( NameResolution::UnboundField, ( loc, @@ -3010,7 +3012,7 @@ fn find_index_funs(context: &mut Context, loc: Loc, ty: &Type) -> Option None, sp!(tloc, T::Anything) => { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::UninferredType, (loc, msg()), (*tloc, UNINFERRED_MSG), @@ -3018,7 +3020,7 @@ fn find_index_funs(context: &mut Context, loc: Loc, ty: &Type) -> Option { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::UninferredType, (loc, msg()), (*tloc, UNINFERRED_MSG), @@ -3028,9 +3030,7 @@ fn find_index_funs(context: &mut Context, loc: Loc, ty: &Type) -> Option { let index_opt = core::find_index_funs(context, type_name); if index_opt.is_none() { - context - .env - .add_diag(diag!(Declarations::MissingSyntaxMethod, (loc, msg()),)); + context.add_diag(diag!(Declarations::MissingSyntaxMethod, (loc, msg()),)); } index_opt } @@ -3039,7 +3039,7 @@ fn find_index_funs(context: &mut Context, loc: Loc, ty: &Type) -> Option, @@ -3140,7 +3144,7 @@ impl ExpDotted { fn last_type(&self) -> Type { if let Some(accessor) = self.accessors.last() { match accessor { - ExpDottedAccess::Field(_, ty) => ty.clone(), + ExpDottedAccess::Field(_, _, ty) => ty.clone(), ExpDottedAccess::Index { base_type, .. } => base_type.clone(), } } else { @@ -3213,9 +3217,7 @@ fn process_exp_dotted( sp!(_, Type_::Ref(_, base)) => *base, ty @ sp!(_, Type_::UnresolvedError) => ty, _ => { - context - .env - .add_diag(ice!((dloc, "Index should have failed in naming"))); + context.add_diag(ice!((dloc, "Index should have failed in naming"))); sp(dloc, Type_::UnresolvedError) } }; @@ -3235,7 +3237,7 @@ fn process_exp_dotted( ) -> ExpDotted { match ndot_ { N::ExpDotted_::Exp(e) => process_base_exp(context, constraint_verb, dloc, e), - N::ExpDotted_::Dot(ndot, field) => { + N::ExpDotted_::Dot(ndot, dot_loc, field) => { let mut inner = process_exp_dotted_inner(context, Some("dot access"), *ndot); assert!(inner.autocomplete_last.is_none()); let inner_ty = inner.last_type(); @@ -3243,7 +3245,7 @@ fn process_exp_dotted( inner.loc = dloc; inner .accessors - .push(ExpDottedAccess::Field(field, field_type)); + .push(ExpDottedAccess::Field(dot_loc, field, field_type)); inner } N::ExpDotted_::Index(ndot, sp!(argloc, nargs_)) => { @@ -3262,9 +3264,7 @@ fn process_exp_dotted( inner } N::ExpDotted_::DotAutocomplete(_loc, ndot) => { - context - .env - .add_diag(ice!((dloc, "Found a dot autocomplete where unsupported"))); + context.add_diag(ice!((dloc, "Found a dot autocomplete where unsupported"))); // Keep going after the ICE. process_exp_dotted_inner(context, constraint_verb, *ndot) } @@ -3283,14 +3283,14 @@ fn exp_dotted_usage( let constraint_verb = match &ndotted.value { N::ExpDotted_::Exp(_) => None, _ if matches!(usage, DottedUsage::Borrow(_)) => Some("borrow"), - N::ExpDotted_::Dot(_, _) | N::ExpDotted_::DotAutocomplete(_, _) => Some("dot access"), + N::ExpDotted_::Dot(_, _, _) | N::ExpDotted_::DotAutocomplete(_, _) => Some("dot access"), N::ExpDotted_::Index(_, _) => Some("index"), }; let edotted = process_exp_dotted(context, constraint_verb, ndotted); if matches!(usage, DottedUsage::Borrow(_)) && edotted.accessors.is_empty() { context.add_base_type_constraint(exp_loc, "Invalid borrow", edotted.base.ty.clone()); } - resolve_exp_dotted(context, usage, exp_loc, edotted) + resolve_exp_dotted(context, usage, exp_loc, edotted, None) } fn exp_dotted_expression( @@ -3304,7 +3304,7 @@ fn exp_dotted_expression( if matches!(usage, DottedUsage::Borrow(_)) && edotted.accessors.is_empty() { context.add_base_type_constraint(error_loc, "Invalid borrow", edotted.base.ty.clone()); } - resolve_exp_dotted(context, usage, error_loc, edotted) + resolve_exp_dotted(context, usage, error_loc, edotted, None) } // This comment servees to document the function below. Depending on the shape @@ -3341,6 +3341,7 @@ fn resolve_exp_dotted( usage: DottedUsage, error_loc: Loc, edotted: ExpDotted, + method_dot_loc: Option, ) -> Box { use T::UnannotatedExp_ as TE; @@ -3350,19 +3351,17 @@ fn resolve_exp_dotted( let edotted_ty = core::unfold_type(&context.subst, edotted.last_type()); let autocomplete_last = edotted.autocomplete_last; - let result = match usage { DottedUsage::Move(loc) => { match edotted.base.exp.value { - TE::Use(var) if edotted.accessors.is_empty() => make_exp( - edotted.base.ty, - TE::Move { + TE::Use(var) if edotted.accessors.is_empty() => { + make_exp(edotted.base.ty, TE::Move { var, from_user: true, - }, - ), + }) + } TE::Constant(_, _) if edotted.accessors.is_empty() => { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidMoveOp, (loc, "Invalid 'move'. Cannot 'move' constants") )); @@ -3370,14 +3369,14 @@ fn resolve_exp_dotted( } TE::UnresolvedError => make_exp(edotted.base.ty, TE::UnresolvedError), _ if edotted.accessors.is_empty() => { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidMoveOp, (loc, "Invalid 'move'. Expected a variable or path.") )); make_error(context) } _ => { - if context.env.check_feature( + if context.check_feature( context.current_package(), FeatureGate::Move2024Paths, loc, @@ -3386,9 +3385,7 @@ fn resolve_exp_dotted( borrow_exp_dotted(context, error_loc, false, edotted); let msg = "Invalid 'move'. 'move' works only with \ variables, e.g. 'move x'. 'move' on a path access is not supported"; - context - .env - .add_diag(diag!(TypeSafety::InvalidMoveOp, (loc, msg))); + context.add_diag(diag!(TypeSafety::InvalidMoveOp, (loc, msg))); make_error(context) } else { make_error(context) @@ -3399,15 +3396,12 @@ fn resolve_exp_dotted( DottedUsage::Copy(loc) => { let copy_exp = if edotted.accessors.is_empty() { match edotted.base.exp.value { - TE::Use(var) => make_exp( - edotted.base.ty, - TE::Copy { - var, - from_user: true, - }, - ), + TE::Use(var) => make_exp(edotted.base.ty, TE::Copy { + var, + from_user: true, + }), exp_ @ TE::Constant(_, _) => { - context.env.check_feature( + context.check_feature( context.current_package(), FeatureGate::Move2024Paths, edotted.base.exp.loc, @@ -3417,9 +3411,7 @@ fn resolve_exp_dotted( TE::UnresolvedError => make_exp(edotted.base.ty, TE::UnresolvedError), _ => { let msg = "Invalid 'copy'. Expected a variable or path.".to_owned(); - context - .env - .add_diag(diag!(TypeSafety::InvalidCopyOp, (loc, msg))); + context.add_diag(diag!(TypeSafety::InvalidCopyOp, (loc, msg))); make_error(context) } } @@ -3451,12 +3443,13 @@ fn resolve_exp_dotted( if let Some(loc) = autocomplete_last { assert!(context.env.ide_mode()); - debug_print!(context.debug.autocomplete_resolution, ("computing autocomplete" => result; dbg)); + debug_print!(context.debug.autocomplete_resolution, ("computing unresolved dot autocomplete" => result; dbg)); ide_report_autocomplete(context, &loc, &edotted_ty); - result - } else { - result } + if let Some(mdot_loc) = method_dot_loc { + ide_report_autocomplete(context, &mdot_loc, &edotted_ty); + } + result } // Borrowing proceeds based on mutability and if the base expression was @@ -3504,7 +3497,7 @@ fn borrow_exp_dotted( }; // lhs is immutable and current borrow is mutable if !cur_mut && expected_mut { - context.env.add_diag(diag!( + context.add_diag(diag!( ReferenceSafety::RefTrans, (loc, "Invalid mutable borrow from an immutable reference"), (tyloc, "Immutable because of this position"), @@ -3532,21 +3525,28 @@ fn borrow_exp_dotted( loc, mut_, Box::new(base), - base_type, + base_type.clone(), warn_on_constant, ), BaseRefKind::ImmRef | BaseRefKind::MutRef => Box::new(base), }; + let mut prev_ty_opt = None; for accessor in accessors { check_mut(context, error_loc, exp.ty.clone(), mut_); match accessor { - ExpDottedAccess::Field(name, ty) => { + ExpDottedAccess::Field(dot_loc, name, ty) => { // report autocomplete information for the IDE ide_report_autocomplete(context, &name.loc(), &exp.ty); + if let Some(prev_ty) = &prev_ty_opt { + ide_report_autocomplete(context, &dot_loc, prev_ty); + } else { + ide_report_autocomplete(context, &dot_loc, &base_type); + } let e_ = TE::Borrow(mut_, exp, name); let ty = sp(loc, Type_::Ref(mut_, Box::new(ty))); - exp = Box::new(T::exp(ty, sp(loc, e_))); + exp = Box::new(T::exp(ty.clone(), sp(loc, e_))); + prev_ty_opt = Some(ty); } ExpDottedAccess::Index { index_loc, @@ -3570,7 +3570,6 @@ fn borrow_exp_dotted( } else { let msg = "Could not find a mutable index 'syntax' method"; context - .env .add_diag(diag!(Declarations::MissingSyntaxMethod, (index_loc, msg),)); exp = make_error_exp(context, index_loc); break; @@ -3579,15 +3578,16 @@ fn borrow_exp_dotted( index.target_function } else { let msg = "Could not find an immutable index 'syntax' method"; - context - .env - .add_diag(diag!(Declarations::MissingSyntaxMethod, (index_loc, msg),)); + context.add_diag(diag!(Declarations::MissingSyntaxMethod, (index_loc, msg),)); exp = make_error_exp(context, index_loc); break; }; let sp!(argloc, mut args_) = args; args_.insert(0, *exp); - let mut_type = sp(index_loc, Type_::Ref(mut_, Box::new(index_base_type))); + let mut_type = sp( + index_loc, + Type_::Ref(mut_, Box::new(index_base_type.clone())), + ); // Note that `module_call` here never raise parameter subtyping errors, since we // already checked them when processing the index functions. let (ret_ty, e_) = module_call(context, error_loc, m, f, None, argloc, args_); @@ -3597,11 +3597,12 @@ fn borrow_exp_dotted( core::error_format(&ret_ty, &context.subst), core::error_format(&mut_type, &context.subst) ); - context.env.add_diag(ice!((loc, msg))); + context.add_diag(ice!((loc, msg))); exp = make_error_exp(context, index_loc); break; } exp = Box::new(T::exp(ret_ty, sp(index_loc, e_))); + prev_ty_opt = Some(index_base_type); } } } @@ -3634,13 +3635,13 @@ fn exp_dotted_to_owned( use T::UnannotatedExp_ as TE; let (access_msg, access_type) = if let Some(accessor) = ed.accessors.last() { match accessor { - ExpDottedAccess::Field(name, ty) => (format!("field '{}'", name), ty.clone()), + ExpDottedAccess::Field(_, name, ty) => (format!("field '{}'", name), ty.clone()), ExpDottedAccess::Index { base_type, .. } => { ("index result".to_string(), base_type.clone()) } } } else { - context.env.add_diag(ice!(( + context.add_diag(ice!(( ed.loc, "Attempted to make a dotted path with no dots" ))); @@ -3648,22 +3649,16 @@ fn exp_dotted_to_owned( }; let case = match usage { DottedUsage::Move(_) => { - context - .env - .add_diag(ice!((ed.loc, "Invalid dotted usage 'move' in to_owned"))); + context.add_diag(ice!((ed.loc, "Invalid dotted usage 'move' in to_owned"))); return make_error_exp(context, ed.loc); } DottedUsage::Borrow(_) => { - context - .env - .add_diag(ice!((ed.loc, "Invalid dotted usage 'borrow' in to_owned"))); + context.add_diag(ice!((ed.loc, "Invalid dotted usage 'borrow' in to_owned"))); return make_error_exp(context, ed.loc); } DottedUsage::Use => "implicit copy", DottedUsage::Copy(loc) => { - context - .env - .check_feature(context.current_package(), FeatureGate::Move2024Paths, loc); + context.check_feature(context.current_package(), FeatureGate::Move2024Paths, loc); "'copy'" } }; @@ -3720,8 +3715,8 @@ fn exp_to_borrow_( base_type: Type, warn_on_constant: bool, ) -> Box { - use Type_::*; use T::UnannotatedExp_ as TE; + use Type_::*; if warn_on_constant { warn_on_constant_borrow(context, eb.exp.loc, &eb) }; @@ -3749,9 +3744,7 @@ fn warn_on_constant_borrow(context: &mut Context, loc: Loc, e: &T::Exp) { if matches!(&e.exp.value, TE::Constant(_, _)) { let msg = "This access will make a new copy of the constant. \ Consider binding the value to a variable first to make this copy explicit"; - context - .env - .add_diag(diag!(TypeSafety::ImplicitConstantCopy, (loc, msg))) + context.add_diag(diag!(TypeSafety::ImplicitConstantCopy, (loc, msg))) } } @@ -3801,6 +3794,7 @@ fn method_call( ty_args_opt: Option>, argloc: Loc, mut args: Vec, + dot_loc: Loc, ) -> Option<(Type, T::UnannotatedExp_)> { use T::UnannotatedExp_ as TE; let mut edotted = edotted; @@ -3811,17 +3805,25 @@ fn method_call( // Even if the method name fails to resolve, we want autocomplete information. edotted.autocomplete_last = Some(method.loc); let err_ty = context.error_type(call_loc); - let dot_output = - resolve_exp_dotted(context, DottedUsage::Borrow(false), call_loc, edotted); + let dot_output = resolve_exp_dotted( + context, + DottedUsage::Borrow(false), + call_loc, + edotted, + Some(dot_loc), + ); return Some((err_ty, dot_output.exp.value)); } ResolvedMethodCall::InvalidBaseType | ResolvedMethodCall::UnknownName => return None, }; // report autocomplete information for the IDE - if context.env.ide_mode() { + let method_dot_loc = if context.env.ide_mode() { edotted.autocomplete_last = Some(method.loc); - } - let first_arg = *resolve_exp_dotted(context, usage, call_loc, edotted); + Some(dot_loc) + } else { + None + }; + let first_arg = *resolve_exp_dotted(context, usage, call_loc, edotted, method_dot_loc); args.insert(0, first_arg); let (mut call, ret_ty) = module_call_impl(context, call_loc, m, f, fty, argloc, args); call.method_name = Some(method); @@ -3869,8 +3871,8 @@ fn type_to_type_name_( error_msg: String, report_error: bool, ) -> Option { - use TypeName_ as TN; use Type_ as Ty; + use TypeName_ as TN; match &ty.value { Ty::Apply(_, tn @ sp!(_, TN::ModuleType(_, _) | TN::Builtin(_)), _) => Some(tn.clone()), t => { @@ -3899,7 +3901,7 @@ fn type_to_type_name_( return None; } Ty::Ref(_, _) | Ty::Var(_) => { - context.env.add_diag(ice!(( + context.add_diag(ice!(( loc, "Typing did not unfold type before resolving type name" ))); @@ -3908,7 +3910,7 @@ fn type_to_type_name_( Ty::Apply(_, _, _) => unreachable!(), }; if report_error { - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidMethodCall, (loc, format!("Invalid {error_msg}")), (ty.loc, msg), @@ -4048,7 +4050,7 @@ fn annotated_error_const(context: &mut Context, e: &mut T::Exp, abort_or_assert_ the '#[error]' attribute is added to them." .to_string(), ); - context.env.add_diag(err); + context.add_diag(err); e.ty = context.error_type(e.ty.loc); e.exp = sp(e.exp.loc, T::UnannotatedExp_::UnresolvedError); @@ -4300,7 +4302,7 @@ fn check_call_target( } else { "Normal (non-'macro') function is declared here" }; - context.env.add_diag(diag!( + context.add_diag(diag!( TypeSafety::InvalidCallTarget, (macro_call_loc, call_msg), (decl_loc, decl_msg), @@ -4320,6 +4322,7 @@ fn macro_method_call( ty_args_opt: Option>, argloc: Loc, nargs: Vec, + dot_loc: Loc, ) -> Option<(Type, T::UnannotatedExp_)> { let mut edotted = edotted; let (m, f, fty, usage) = match method_call_resolve(context, loc, &edotted, method, ty_args_opt) @@ -4329,16 +4332,25 @@ fn macro_method_call( // Even if the method name fails to resolve, we want autocomplete information. edotted.autocomplete_last = Some(method.loc); let err_ty = context.error_type(loc); - let dot_output = resolve_exp_dotted(context, DottedUsage::Borrow(false), loc, edotted); + let dot_output = resolve_exp_dotted( + context, + DottedUsage::Borrow(false), + loc, + edotted, + Some(dot_loc), + ); return Some((err_ty, dot_output.exp.value)); } ResolvedMethodCall::InvalidBaseType | ResolvedMethodCall::UnknownName => return None, }; // report autocomplete information for the IDE - if context.env.ide_mode() { + let method_dot_loc = if context.env.ide_mode() { edotted.autocomplete_last = Some(method.loc); - } - let first_arg = *resolve_exp_dotted(context, usage, loc, edotted); + Some(dot_loc) + } else { + None + }; + let first_arg = *resolve_exp_dotted(context, usage, loc, edotted, method_dot_loc); let mut args = vec![macro_expand::EvalStrategy::ByValue(first_arg)]; args.extend( nargs @@ -4526,7 +4538,7 @@ fn expand_macro( { None => { if !(context.env.has_errors() || context.env.ide_mode()) { - context.env.add_diag(ice!(( + context.add_diag(ice!(( call_loc, "No macro found, but name resolution passed." ))); @@ -4644,12 +4656,9 @@ fn process_attributes(context: &mut Context, all_attributes: &UniqueMa /// Generates warnings for unused (private) functions and unused constants. /// Should be called after the whole program has been processed. fn unused_module_members(context: &mut Context, mident: &ModuleIdent_, mdef: &T::ModuleDefinition) { - if !matches!( - mdef.target_kind, - TargetKind::Source { - is_root_package: true - } - ) { + if !matches!(mdef.target_kind, TargetKind::Source { + is_root_package: true + }) { // generate warnings only for modules compiled in this pass rather than for all // modules including pre-compiled libraries for which we do not have // source code available and cannot be analyzed in this pass @@ -4657,24 +4666,18 @@ fn unused_module_members(context: &mut Context, mident: &ModuleIdent_, mdef: &T: } let is_iota_mode = context.env.package_config(mdef.package_name).flavor == Flavor::Iota; - context - .env - .add_warning_filter_scope(mdef.warning_filter.clone()); + context.push_warning_filter_scope(mdef.warning_filter); for (loc, name, c) in &mdef.constants { - context - .env - .add_warning_filter_scope(c.warning_filter.clone()); + context.push_warning_filter_scope(c.warning_filter); let members = context.used_module_members.get(mident); if members.is_none() || !members.unwrap().contains(name) { let msg = format!("The constant '{name}' is never used. Consider removing it."); - context - .env - .add_diag(diag!(UnusedItem::Constant, (loc, msg))) + context.add_diag(diag!(UnusedItem::Constant, (loc, msg))) } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } for (loc, name, fun) in &mdef.functions { @@ -4690,9 +4693,7 @@ fn unused_module_members(context: &mut Context, mident: &ModuleIdent_, mdef: &T: // a Iota-specific filter to avoid signaling that the init function is unused continue; } - context - .env - .add_warning_filter_scope(fun.warning_filter.clone()); + context.push_warning_filter_scope(fun.warning_filter); let members = context.used_module_members.get(mident); if fun.entry.is_none() @@ -4705,12 +4706,10 @@ fn unused_module_members(context: &mut Context, mident: &ModuleIdent_, mdef: &T: "The non-'public', non-'entry' function '{name}' is never called. \ Consider removing it." ); - context - .env - .add_diag(diag!(UnusedItem::Function, (loc, msg))) + context.add_diag(diag!(UnusedItem::Function, (loc, msg))) } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } - context.env.pop_warning_filter_scope(); + context.pop_warning_filter_scope(); } diff --git a/external-crates/move/crates/move-compiler/src/typing/visitor.rs b/external-crates/move/crates/move-compiler/src/typing/visitor.rs index 864443dd53f..cf7b6d7105b 100644 --- a/external-crates/move/crates/move-compiler/src/typing/visitor.rs +++ b/external-crates/move/crates/move-compiler/src/typing/visitor.rs @@ -4,48 +4,650 @@ use crate::{ command_line::compiler::Visitor, - diagnostics::WarningFilters, - expansion::ast::ModuleIdent, - naming::ast as N, + diagnostics::warning_filters::WarningFilters, + expansion::ast::{Fields, ModuleIdent}, + naming::ast::{self as N, Var}, parser::ast::{ConstantName, DatatypeName, FunctionName, VariantName}, shared::CompilationEnv, - typing::ast as T, + typing::ast::{self as T, BuiltinFunction_}, }; +use move_ir_types::location::Loc; +use move_proc_macros::growing_stack; + +pub type TypingVisitorObj = Box; + +pub trait TypingVisitor: Send + Sync { + fn visit(&self, env: &CompilationEnv, program: &T::Program); + + fn visitor(self) -> Visitor + where + Self: 'static + Sized, + { + Visitor::TypingVisitor(Box::new(self)) + } +} + +pub trait TypingVisitorConstructor: Send + Sync { + type Context<'a>: Sized + TypingVisitorContext; + + fn context<'a>(env: &'a CompilationEnv, program: &T::Program) -> Self::Context<'a>; + + fn visit(env: &CompilationEnv, program: &T::Program) { + let mut context = Self::context(env, program); + context.visit(program); + } +} + +pub enum LValueKind { + Bind, + Assign, +} + +pub trait TypingVisitorContext { + fn push_warning_filter_scope(&mut self, filters: WarningFilters); + fn pop_warning_filter_scope(&mut self); + + /// Indicates if types should be visited during the traversal of other forms (struct and enum + /// definitions, function signatures, expressions, etc.). This will not visit lvalue types + /// unless VISIT_LVALUES is also enabled. + const VISIT_TYPES: bool = false; + + /// Indicates if lvalues should be visited during the traversal of sequence forms. + const VISIT_LVALUES: bool = false; + + /// Indicates if use_funs should be visited during the traversal. + const VISIT_USE_FUNS: bool = false; + + /// By default, the visitor will visit all modules, and all functions and constants therein. + /// For functions and constants, it will also visit their expressions. To change this behavior, + /// consider enabling `VISIT_LVALUES`, VISIT_TYPES`, and `VISIT_USE_FUNS` or overwriting one of + /// the `visit__custom` functions defined on this trait, as appropriate. + fn visit(&mut self, program: &T::Program) { + for (mident, mdef) in program.modules.key_cloned_iter() { + self.visit_module(mident, mdef); + } + } + + // -- MODULE DEFINITIONS -- + + fn visit_module_custom(&mut self, _ident: ModuleIdent, _mdef: &T::ModuleDefinition) -> bool { + false + } + + fn visit_module(&mut self, ident: ModuleIdent, mdef: &T::ModuleDefinition) { + self.push_warning_filter_scope(mdef.warning_filter); + if self.visit_module_custom(ident, mdef) { + self.pop_warning_filter_scope(); + return; + } + for (struct_name, sdef) in mdef.structs.key_cloned_iter() { + self.visit_struct(ident, struct_name, sdef) + } + for (enum_name, edef) in mdef.enums.key_cloned_iter() { + self.visit_enum(ident, enum_name, edef) + } + for (constant_name, cdef) in mdef.constants.key_cloned_iter() { + self.visit_constant(ident, constant_name, cdef) + } + for (function_name, fdef) in mdef.functions.key_cloned_iter() { + self.visit_function(ident, function_name, fdef) + } + if Self::VISIT_USE_FUNS { + self.visit_use_funs(&mdef.use_funs); + } + + self.pop_warning_filter_scope(); + } + + // -- MODULE MEMBER DEFINITIONS -- + + fn visit_struct_custom( + &mut self, + _module: ModuleIdent, + _struct_name: DatatypeName, + _sdef: &N::StructDefinition, + ) -> bool { + false + } + + fn visit_struct( + &mut self, + module: ModuleIdent, + struct_name: DatatypeName, + sdef: &N::StructDefinition, + ) { + self.push_warning_filter_scope(sdef.warning_filter); + if self.visit_struct_custom(module, struct_name, sdef) { + self.pop_warning_filter_scope(); + return; + } + if Self::VISIT_TYPES { + match &sdef.fields { + N::StructFields::Defined(_, fields) => { + for (_, _, (_, ty)) in fields { + self.visit_type(None, ty) + } + } + N::StructFields::Native(_) => (), + } + } + self.pop_warning_filter_scope(); + } + + fn visit_enum_custom( + &mut self, + _module: ModuleIdent, + _enum_name: DatatypeName, + _edef: &N::EnumDefinition, + ) -> bool { + false + } + + fn visit_enum( + &mut self, + module: ModuleIdent, + enum_name: DatatypeName, + edef: &N::EnumDefinition, + ) { + self.push_warning_filter_scope(edef.warning_filter); + if self.visit_enum_custom(module, enum_name, edef) { + self.pop_warning_filter_scope(); + return; + } + for (vname, vdef) in edef.variants.key_cloned_iter() { + self.visit_variant(&module, &enum_name, vname, vdef); + } + self.pop_warning_filter_scope(); + } + + fn visit_variant_custom( + &mut self, + _module: &ModuleIdent, + _enum_name: &DatatypeName, + _variant_name: VariantName, + _vdef: &N::VariantDefinition, + ) -> bool { + false + } + + fn visit_variant( + &mut self, + module: &ModuleIdent, + enum_name: &DatatypeName, + variant_name: VariantName, + vdef: &N::VariantDefinition, + ) { + if self.visit_variant_custom(module, enum_name, variant_name, vdef) { + return; + } + if Self::VISIT_TYPES { + match &vdef.fields { + N::VariantFields::Defined(_, fields) => { + for (_, _, (_, ty)) in fields { + self.visit_type(None, ty) + } + } + N::VariantFields::Empty => (), + } + } + } + + // TODO field visitor + + fn visit_constant_custom( + &mut self, + _module: ModuleIdent, + _constant_name: ConstantName, + _cdef: &T::Constant, + ) -> bool { + false + } + + fn visit_constant( + &mut self, + module: ModuleIdent, + constant_name: ConstantName, + cdef: &T::Constant, + ) { + self.push_warning_filter_scope(cdef.warning_filter); + if self.visit_constant_custom(module, constant_name, cdef) { + self.pop_warning_filter_scope(); + return; + } + self.visit_exp(&cdef.value); + self.pop_warning_filter_scope(); + } + + fn visit_function_custom( + &mut self, + _module: ModuleIdent, + _function_name: FunctionName, + _fdef: &T::Function, + ) -> bool { + false + } + + fn visit_function( + &mut self, + module: ModuleIdent, + function_name: FunctionName, + fdef: &T::Function, + ) { + self.push_warning_filter_scope(fdef.warning_filter); + if self.visit_function_custom(module, function_name, fdef) { + self.pop_warning_filter_scope(); + return; + } + if Self::VISIT_TYPES { + fdef.signature + .parameters + .iter() + .map(|(_, _, ty)| ty) + .for_each(|ty| self.visit_type(None, ty)); + self.visit_type(None, &fdef.signature.return_type); + } + if let T::FunctionBody_::Defined(seq) = &fdef.body.value { + self.visit_seq(fdef.body.loc, seq); + } + self.pop_warning_filter_scope(); + } + + // -- TYPES -- + + fn visit_type_custom(&mut self, _exp_loc: Option, _ty: &N::Type) -> bool { + false + } + + /// Visit a type, including recursively. Note that this may be called manually even if + /// `VISIT_TYPES` is set to `false`. + #[growing_stack] + fn visit_type(&mut self, exp_loc: Option, ty: &N::Type) { + if self.visit_type_custom(exp_loc, ty) { + return; + } + match &ty.value { + N::Type_::Unit => (), + N::Type_::Ref(_, inner) => self.visit_type(exp_loc, inner), + N::Type_::Param(_) => (), + N::Type_::Apply(_, _, args) => args.iter().for_each(|ty| self.visit_type(exp_loc, ty)), + N::Type_::Fun(args, ret) => { + args.iter().for_each(|ty| self.visit_type(exp_loc, ty)); + self.visit_type(exp_loc, ret); + } + N::Type_::Var(_) => (), + N::Type_::Anything => (), + N::Type_::UnresolvedError => (), + } + } + + // -- USE FUNS -- + + fn visit_use_funs_custom(&mut self, _use_funs: &N::UseFuns) -> bool { + false + } + + fn visit_use_funs(&mut self, use_funs: &N::UseFuns) { + let _ = self.visit_use_funs_custom(use_funs); + // Nothing to traverse in the other case + } + + // -- SEQUENCES AND EXPRESSIONS -- + + /// Custom visit for a sequence. It will skip `visit_seq` if `visit_seq_custom` returns true. + fn visit_seq_custom(&mut self, _loc: Loc, _seq: &T::Sequence) -> bool { + false + } + + fn visit_seq(&mut self, loc: Loc, seq @ (use_funs, seq_): &T::Sequence) { + if self.visit_seq_custom(loc, seq) { + return; + } + if Self::VISIT_USE_FUNS { + self.visit_use_funs(use_funs); + } + for s in seq_ { + self.visit_seq_item(s); + } + } + + /// Custom visit for a sequence item. It will skip `visit_seq_item` if `visit_seq_item_custom` + /// returns true. + fn visit_seq_item_custom(&mut self, _seq_item: &T::SequenceItem) -> bool { + false + } + + fn visit_seq_item(&mut self, seq_item: &T::SequenceItem) { + use T::SequenceItem_ as SI; + if self.visit_seq_item_custom(seq_item) { + return; + } + match &seq_item.value { + SI::Seq(e) => self.visit_exp(e), + SI::Declare(lvalues) if Self::VISIT_LVALUES => { + self.visit_lvalue_list(&LValueKind::Bind, lvalues); + } + SI::Declare(_) => (), + SI::Bind(lvalues, ty_ann, e) => { + // visit the RHS first to better match control flow + self.visit_exp(e); + if Self::VISIT_LVALUES { + self.visit_lvalue_list(&LValueKind::Bind, lvalues); + } + if Self::VISIT_TYPES { + ty_ann + .iter() + .flatten() + .for_each(|ty| self.visit_type(Some(ty.loc), ty)); + } + } + } + } + + /// Visit an lvalue list. Note that this may be called manually even if `VISIT_LVALUES` is set + /// to `false`. + fn visit_lvalue_list(&mut self, kind: &LValueKind, lvalues: &T::LValueList) { + for lvalue in &lvalues.value { + self.visit_lvalue(kind, lvalue); + } + } + + /// Custom visit for an lvalue. It will skip `visit_lvalue` if `visit_lvalue_custom` returns true. + fn visit_lvalue_custom(&mut self, _kind: &LValueKind, _lvalue: &T::LValue) -> bool { + false + } + + /// Visit an lvalue, including recursively. Note that this may be called manually even if + /// `VISIT_LVALUES` is set to `false`. + #[growing_stack] + fn visit_lvalue(&mut self, kind: &LValueKind, lvalue: &T::LValue) { + if self.visit_lvalue_custom(kind, lvalue) { + return; + } + match &lvalue.value { + T::LValue_::Ignore => (), + T::LValue_::Var { + mut_: _, + var: _, + ty, + unused_binding: _, + } => { + if Self::VISIT_TYPES { + self.visit_type(Some(lvalue.loc), ty); + } + } + T::LValue_::UnpackVariant(_, _, _, tyargs, fields) + | T::LValue_::BorrowUnpackVariant(_, _, _, _, tyargs, fields) + | T::LValue_::Unpack(_, _, tyargs, fields) + | T::LValue_::BorrowUnpack(_, _, _, tyargs, fields) => { + if Self::VISIT_TYPES { + tyargs + .iter() + .for_each(|ty| self.visit_type(Some(lvalue.loc), ty)); + } + for (_, _, (_, (ty, lvalue))) in fields.iter() { + if Self::VISIT_TYPES { + self.visit_type(Some(lvalue.loc), ty); + } + self.visit_lvalue(kind, lvalue); + } + } + } + } -use move_ir_types::location::Loc; -use move_proc_macros::growing_stack; + /// Custom visit for an expression. It will skip `visit_exp` if `visit_exp_custom` returns true. + fn visit_exp_custom(&mut self, _exp: &T::Exp) -> bool { + false + } -pub type TypingVisitorObj = Box; + #[growing_stack] + fn visit_exp(&mut self, exp: &T::Exp) { + use T::UnannotatedExp_ as E; + if self.visit_exp_custom(exp) { + return; + } + if Self::VISIT_TYPES { + self.visit_type(Some(exp.exp.loc), &exp.ty); + } + let sp!(exp_loc, uexp) = &exp.exp; + let exp_loc = *exp_loc; + match uexp { + E::ModuleCall(c) => { + if Self::VISIT_TYPES { + c.type_arguments + .iter() + .for_each(|ty| self.visit_type(Some(exp_loc), ty)); + c.parameter_types + .iter() + .for_each(|ty| self.visit_type(Some(exp_loc), ty)); + } + self.visit_exp(&c.arguments) + } + E::Builtin(bf, e) => { + // visit the argument first to better match control flow + self.visit_exp(e); + use T::BuiltinFunction_ as BF; + match &bf.value { + BF::Freeze(t) => { + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), t) + } + } + BF::Assert(_) => (), + } + } + E::Vector(_, _, ty, e) => { + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), ty); + } + self.visit_exp(e); + } + E::IfElse(e1, e2, e3_opt) => { + self.visit_exp(e1); + self.visit_exp(e2); + if let Some(e3) = e3_opt { + self.visit_exp(e3); + } + } + E::Match(esubject, arms) => { + self.visit_exp(esubject); + for sp!(_, arm) in arms.value.iter() { + if let Some(guard) = arm.guard.as_ref() { + self.visit_exp(guard) + } + self.visit_exp(&arm.rhs); + } + } + E::VariantMatch(esubject, _, arms) => { + self.visit_exp(esubject); + for (_, earm) in arms.iter() { + self.visit_exp(earm); + } + } + E::While(_, e1, e2) => { + self.visit_exp(e1); + self.visit_exp(e2); + } + E::Loop { body, .. } => self.visit_exp(body), + E::NamedBlock(_, seq) => self.visit_seq(exp.exp.loc, seq), + E::Block(seq) => self.visit_seq(exp.exp.loc, seq), + E::Assign(lvalues, ty_ann, e) => { + // visit the RHS first to better match control flow + self.visit_exp(e); + if Self::VISIT_LVALUES { + for lvalue in lvalues.value.iter() { + self.visit_lvalue(&LValueKind::Assign, lvalue); + } + } + if Self::VISIT_TYPES { + ty_ann + .iter() + .flatten() + .for_each(|ty| self.visit_type(Some(exp_loc), ty)); + } + } + E::Mutate(e1, e2) => { + self.visit_exp(e1); + self.visit_exp(e2); + } + E::Return(e) => self.visit_exp(e), + E::Abort(e) => self.visit_exp(e), + E::Give(_, e) => self.visit_exp(e), + E::Dereference(e) => self.visit_exp(e), + E::UnaryExp(_, e) => self.visit_exp(e), + E::BinopExp(e1, _, ty, e2) => { + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), ty); + } + self.visit_exp(e1); + self.visit_exp(e2); + } + E::Pack(_, _, tyargs, fields) | E::PackVariant(_, _, _, tyargs, fields) => { + if Self::VISIT_TYPES { + tyargs + .iter() + .for_each(|ty| self.visit_type(Some(exp_loc), ty)); + } + fields.iter().for_each(|(_, _, (_, (ty, e)))| { + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), ty) + } + self.visit_exp(e); + }); + } + E::ExpList(list) => { + for l in list { + match l { + T::ExpListItem::Single(e, ty) => { + self.visit_exp(e); + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), ty) + } + } + T::ExpListItem::Splat(_, e, tys) => { + self.visit_exp(e); + if Self::VISIT_TYPES { + tys.iter().for_each(|ty| self.visit_type(Some(exp_loc), ty)); + } + } + } + } + } + E::Borrow(_, e, _) => self.visit_exp(e), + E::TempBorrow(_, e) => self.visit_exp(e), + E::Cast(e, ty) => { + self.visit_exp(e); + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), ty) + } + } + E::Annotate(e, ty) => { + self.visit_exp(e); + if Self::VISIT_TYPES { + self.visit_type(Some(exp_loc), ty) + } + } + E::Unit { .. } + | E::Value(_) + | E::Move { .. } + | E::Copy { .. } + | E::Use(_) + | E::Constant(..) + | E::Continue(_) + | E::BorrowLocal(..) + | E::ErrorConstant { .. } + | E::UnresolvedError => (), + } + } +} -pub trait TypingVisitor { - fn visit(&mut self, env: &mut CompilationEnv, program: &mut T::Program); +impl From for TypingVisitorObj { + fn from(value: V) -> Self { + Box::new(value) + } +} - fn visitor(self) -> Visitor - where - Self: 'static + Sized, - { - Visitor::TypingVisitor(Box::new(self)) +impl TypingVisitor for V { + fn visit(&self, env: &CompilationEnv, program: &T::Program) { + Self::visit(env, program) } } -pub trait TypingVisitorConstructor { - type Context<'a>: Sized + TypingVisitorContext; +macro_rules! simple_visitor { + ($visitor:ident, $($overrides:item),*) => { + pub struct $visitor; + + pub struct Context<'a> { + #[allow(unused)] + env: &'a crate::shared::CompilationEnv, + reporter: crate::diagnostics::DiagnosticReporter<'a>, + } - fn context<'a>(env: &'a mut CompilationEnv, program: &T::Program) -> Self::Context<'a>; + impl crate::typing::visitor::TypingVisitorConstructor for $visitor { + type Context<'a> = Context<'a>; - fn visit(&mut self, env: &mut CompilationEnv, program: &mut T::Program) { - let mut context = Self::context(env, program); - context.visit(program); + fn context<'a>( + env: &'a crate::shared::CompilationEnv, + _program: &crate::typing::ast::Program, + ) -> Self::Context<'a> { + let reporter = env.diagnostic_reporter_at_top_level(); + Context { + env, + reporter, + } + } + } + + impl Context<'_> { + #[allow(unused)] + pub fn add_diag(&self, diag: crate::diagnostics::Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: crate::diagnostics::Diagnostics) { + self.reporter.add_diags(diags); + } + } + + impl crate::typing::visitor::TypingVisitorContext for Context<'_> { + fn push_warning_filter_scope( + &mut self, + filters: crate::diagnostics::warning_filters::WarningFilters, + ) { + self.reporter.push_warning_filter_scope(filters) + } + + fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + + $($overrides)* + } } } +pub(crate) use simple_visitor; -pub enum LValueKind { - Bind, - Assign, +//************************************************************************************************** +// Mut Vistor +//************************************************************************************************** + +pub trait TypingMutVisitor: Send + Sync { + fn visit(&self, env: &CompilationEnv, program: &mut T::Program); } -pub trait TypingVisitorContext { - fn add_warning_filter_scope(&mut self, filter: WarningFilters); +pub trait TypingMutVisitorConstructor: Send + Sync { + type Context<'a>: Sized + TypingMutVisitorContext; + + fn context<'a>(env: &'a CompilationEnv, program: &T::Program) -> Self::Context<'a>; + + fn visit(env: &CompilationEnv, program: &mut T::Program) { + let mut context = Self::context(env, program); + context.visit(program); + } +} + +pub trait TypingMutVisitorContext { + fn push_warning_filter_scope(&mut self, filter: WarningFilters); fn pop_warning_filter_scope(&mut self); /// Indicates if types should be visited during the traversal of other forms @@ -84,7 +686,7 @@ pub trait TypingVisitorContext { } fn visit_module(&mut self, ident: ModuleIdent, mdef: &mut T::ModuleDefinition) { - self.add_warning_filter_scope(mdef.warning_filter.clone()); + self.push_warning_filter_scope(mdef.warning_filter); if self.visit_module_custom(ident, mdef) { self.pop_warning_filter_scope(); return; @@ -125,7 +727,7 @@ pub trait TypingVisitorContext { struct_name: DatatypeName, sdef: &mut N::StructDefinition, ) { - self.add_warning_filter_scope(sdef.warning_filter.clone()); + self.push_warning_filter_scope(sdef.warning_filter); if self.visit_struct_custom(module, struct_name, sdef) { self.pop_warning_filter_scope(); return; @@ -158,7 +760,7 @@ pub trait TypingVisitorContext { enum_name: DatatypeName, edef: &mut N::EnumDefinition, ) { - self.add_warning_filter_scope(edef.warning_filter.clone()); + self.push_warning_filter_scope(edef.warning_filter); if self.visit_enum_custom(module, enum_name, edef) { self.pop_warning_filter_scope(); return; @@ -216,7 +818,7 @@ pub trait TypingVisitorContext { constant_name: ConstantName, cdef: &mut T::Constant, ) { - self.add_warning_filter_scope(cdef.warning_filter.clone()); + self.push_warning_filter_scope(cdef.warning_filter); if self.visit_constant_custom(module, constant_name, cdef) { self.pop_warning_filter_scope(); return; @@ -240,7 +842,7 @@ pub trait TypingVisitorContext { function_name: FunctionName, fdef: &mut T::Function, ) { - self.add_warning_filter_scope(fdef.warning_filter.clone()); + self.push_warning_filter_scope(fdef.warning_filter); if self.visit_function_custom(module, function_name, fdef) { self.pop_warning_filter_scope(); return; @@ -444,10 +1046,12 @@ pub trait TypingVisitorContext { } self.visit_exp(e); } - E::IfElse(e1, e2, e3) => { + E::IfElse(e1, e2, e3_opt) => { self.visit_exp(e1); self.visit_exp(e2); - self.visit_exp(e3); + if let Some(e3) = e3_opt { + self.visit_exp(e3); + } } E::Match(esubject, arms) => { self.visit_exp(esubject); @@ -562,14 +1166,252 @@ pub trait TypingVisitorContext { } } -impl From for TypingVisitorObj { - fn from(value: V) -> Self { - Box::new(value) +impl TypingMutVisitor for V { + fn visit(&self, env: &CompilationEnv, program: &mut T::Program) { + Self::visit(env, program) + } +} + +//************************************************************************************************** +// util +//************************************************************************************************** + +pub fn exp_satisfies(e: &T::Exp, mut p: F) -> bool +where + F: FnMut(&T::Exp) -> bool, +{ + exp_satisfies_(e, &mut p) +} + +pub fn seq_satisfies(seq: &T::Sequence, mut p: F) -> bool +where + F: FnMut(&T::Exp) -> bool, +{ + seq_satisfies_(seq, &mut p) +} + +pub fn exp_satisfies_list(list: &[T::ExpListItem], mut p: F) -> bool +where + F: FnMut(&T::Exp) -> bool, +{ + exp_list_satisfies_(list, &mut p) +} + +#[growing_stack] +fn exp_satisfies_(e: &T::Exp, p: &mut F) -> bool +where + F: FnMut(&T::Exp) -> bool, +{ + use T::UnannotatedExp_ as E; + if p(e) { + return true; + } + match &e.exp.value { + E::Unit { .. } + | E::Value(_) + | E::Move { .. } + | E::Copy { .. } + | E::Use(_) + | E::Constant(..) + | E::Continue(_) + | E::BorrowLocal(..) + | E::ErrorConstant { .. } + | E::UnresolvedError => false, + E::Builtin(_, e) + | E::Vector(_, _, _, e) + | E::Loop { body: e, .. } + | E::Assign(_, _, e) + | E::Return(e) + | E::Abort(e) + | E::Give(_, e) + | E::Dereference(e) + | E::UnaryExp(_, e) + | E::Borrow(_, e, _) + | E::TempBorrow(_, e) + | E::Cast(e, _) + | E::Annotate(e, _) => exp_satisfies_(e, p), + E::While(_, e1, e2) | E::Mutate(e1, e2) | E::BinopExp(e1, _, _, e2) => { + exp_satisfies_(e1, p) || exp_satisfies_(e2, p) + } + E::IfElse(e1, e2, e3_opt) => { + exp_satisfies_(e1, p) + || exp_satisfies_(e2, p) + || e3_opt.iter().any(|e3| exp_satisfies_(e3, p)) + } + E::ModuleCall(c) => exp_satisfies_(&c.arguments, p), + E::Match(esubject, arms) => { + exp_satisfies_(esubject, p) + || arms + .value + .iter() + .any(|sp!(_, arm)| exp_satisfies_(&arm.rhs, p)) + } + E::VariantMatch(esubject, _, arms) => { + exp_satisfies_(esubject, p) || arms.iter().any(|(_, arm)| exp_satisfies_(arm, p)) + } + + E::NamedBlock(_, seq) | E::Block(seq) => seq_satisfies_(seq, p), + + E::Pack(_, _, _, fields) | E::PackVariant(_, _, _, _, fields) => fields + .iter() + .any(|(_, _, (_, (_, e)))| exp_satisfies_(e, p)), + E::ExpList(list) => exp_list_satisfies_(list, p), + } +} + +fn seq_satisfies_(seq: &T::Sequence, p: &mut F) -> bool +where + F: FnMut(&T::Exp) -> bool, +{ + seq.1.iter().any(|item| match &item.value { + T::SequenceItem_::Declare(_) => false, + T::SequenceItem_::Seq(e) | T::SequenceItem_::Bind(_, _, e) => exp_satisfies_(e, p), + }) +} + +fn exp_list_satisfies_(list: &[T::ExpListItem], p: &mut F) -> bool +where + F: FnMut(&T::Exp) -> bool, +{ + list.iter().any(|item| match item { + T::ExpListItem::Single(e, _) | T::ExpListItem::Splat(_, e, _) => exp_satisfies_(e, p), + }) +} + +pub fn same_local(lhs: &Var, rhs: &T::Exp) -> Option<(Loc, Loc)> { + if same_local_(lhs, &rhs.exp.value) { + Some((lhs.loc, rhs.exp.loc)) + } else { + None + } +} + +fn same_local_(lhs: &Var, rhs: &T::UnannotatedExp_) -> bool { + use T::UnannotatedExp_ as E; + match &rhs { + E::Copy { var: r, .. } | E::Move { var: r, .. } | E::BorrowLocal(_, r) => lhs == r, + _ => false, + } +} + +/// Assumes equal types and as such will not check type arguments for equality. +/// Assumes function calls, assignments, and similar expressions are effectful and thus not equal. +pub fn same_value_exp(e1: &T::Exp, e2: &T::Exp) -> bool { + same_value_exp_(&e1.exp.value, &e2.exp.value) +} + +#[growing_stack] +pub fn same_value_exp_(e1: &T::UnannotatedExp_, e2: &T::UnannotatedExp_) -> bool { + use T::UnannotatedExp_ as E; + macro_rules! effectful { + () => { + E::Builtin(_, _) + | E::ModuleCall(_) + | E::Assign(_, _, _) + | E::Mutate(_, _) + | E::Return(_) + | E::Abort(_) + | E::Give(_, _) + }; + } + macro_rules! brittle { + () => { + E::ErrorConstant { .. } + | E::IfElse(_, _, _) + | E::Match(_, _) + | E::VariantMatch(_, _, _) + | E::While(_, _, _) + | E::Loop { .. } + }; + } + match (e1, e2) { + (E::Dereference(e) | E::TempBorrow(_, e) | E::Cast(e, _) | E::Annotate(e, _), other) + | (other, E::Dereference(e) | E::TempBorrow(_, e) | E::Cast(e, _) | E::Annotate(e, _)) => { + same_value_exp_(&e.exp.value, other) + } + (E::NamedBlock(_, s) | E::Block(s), other) | (other, E::NamedBlock(_, s) | E::Block(s)) => { + same_value_seq_exp_(s, other) + } + (E::ExpList(l), other) | (other, E::ExpList(l)) if l.len() == 1 => match &l[0] { + T::ExpListItem::Single(e, _) => same_value_exp_(&e.exp.value, other), + T::ExpListItem::Splat(_, e, _) => same_value_exp_(&e.exp.value, other), + }, + + (E::Value(v1), E::Value(v2)) => v1 == v2, + (E::Unit { .. }, E::Unit { .. }) => true, + (E::Constant(m1, c1), E::Constant(m2, c2)) => m1 == m2 && c1 == c2, + ( + E::Move { var, .. } | E::Copy { var, .. } | E::Use(var) | E::BorrowLocal(_, var), + other, + ) + | ( + other, + E::Move { var, .. } | E::Copy { var, .. } | E::Use(var) | E::BorrowLocal(_, var), + ) => same_local_(var, other), + + (E::Vector(_, _, _, e1), E::Vector(_, _, _, e2)) => same_value_exp(e1, e2), + + (E::Builtin(b, e), other) | (other, E::Builtin(b, e)) + if matches!(&b.value, BuiltinFunction_::Freeze(_)) => + { + same_value_exp_(&e.exp.value, other) + } + + (E::ExpList(l1), E::ExpList(l2)) => same_value_exp_list(l1, l2), + + (E::UnaryExp(op1, e1), E::UnaryExp(op2, e2)) => op1 == op2 && same_value_exp(e1, e2), + (E::BinopExp(l1, op1, _, r1), E::BinopExp(l2, op2, _, r2)) => { + op1 == op2 && same_value_exp(l1, l2) && same_value_exp(r1, r2) + } + + (E::Pack(m1, n1, _, fields1), E::Pack(m2, n2, _, fields2)) => { + m1 == m2 && n1 == n2 && same_value_fields(fields1, fields2) + } + (E::PackVariant(m1, n1, v1, _, fields1), E::PackVariant(m2, n2, v2, _, fields2)) => { + m1 == m2 && n1 == n2 && v1 == v2 && same_value_fields(fields1, fields2) + } + + (E::Borrow(_, e1, f1), E::Borrow(_, e2, f2)) => f1 == f2 && same_value_exp(e1, e2), + + // false for anything effectful + (effectful!(), _) | (_, effectful!()) => false, + + // TODO there is some potential for equality here, but a bit too brittle now + (brittle!(), _) | (_, brittle!()) => false, + + _ => false, } } -impl TypingVisitor for V { - fn visit(&mut self, env: &mut CompilationEnv, program: &mut T::Program) { - self.visit(env, program) +fn same_value_fields( + fields1: &Fields<(N::Type, T::Exp)>, + fields2: &Fields<(N::Type, T::Exp)>, +) -> bool { + fields1.key_cloned_iter().all(|(f1, (_, (_, e1)))| { + fields2 + .get(&f1) + .is_some_and(|(_, (_, e2))| same_value_exp(e1, e2)) + }) +} + +fn same_value_exp_list(l1: &[T::ExpListItem], l2: &[T::ExpListItem]) -> bool { + l1.len() == l2.len() + && l1.iter().zip(l2).all(|(i1, i2)| match (i1, i2) { + (T::ExpListItem::Single(e1, _), T::ExpListItem::Single(e2, _)) => { + same_value_exp(e1, e2) + } + // TODO handle splat + _ => false, + }) +} + +fn same_value_seq_exp_((_, seq_): &T::Sequence, other: &T::UnannotatedExp_) -> bool { + match seq_.len() { + 0 => panic!("ICE should not have empty sequence"), + 1 => match &seq_[0].value { + T::SequenceItem_::Seq(e) => same_value_exp_(&e.exp.value, other), + _ => false, + }, + _ => false, } } diff --git a/external-crates/move/crates/move-compiler/src/unit_test/filter_test_members.rs b/external-crates/move/crates/move-compiler/src/unit_test/filter_test_members.rs index 669ce6992c5..738136afe5d 100644 --- a/external-crates/move/crates/move-compiler/src/unit_test/filter_test_members.rs +++ b/external-crates/move/crates/move-compiler/src/unit_test/filter_test_members.rs @@ -11,6 +11,7 @@ use move_symbol_pool::Symbol; use crate::{ command_line::compiler::FullyCompiledProgram, diag, + diagnostics::DiagnosticReporter, parser::{ ast::{self as P, NamePath, PathEntry}, filter::{filter_program, FilterContext}, @@ -19,13 +20,13 @@ use crate::{ }; struct Context<'env> { - env: &'env mut CompilationEnv, + env: &'env CompilationEnv, is_source_def: bool, current_package: Option, } impl<'env> Context<'env> { - fn new(env: &'env mut CompilationEnv) -> Self { + fn new(env: &'env CompilationEnv) -> Self { Self { env, is_source_def: false, @@ -95,11 +96,12 @@ pub const UNIT_TEST_POISON_FUN_NAME: Symbol = symbol!("unit_test_poison"); // no filtering is performed, and instead a test plan is created for use by the // testing framework. pub fn program( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, pre_compiled_lib: Option>, prog: P::Program, ) -> P::Program { - if !check_has_unit_test_module(compilation_env, pre_compiled_lib, &prog) { + let reporter = compilation_env.diagnostic_reporter_at_top_level(); + if !check_has_unit_test_module(compilation_env, &reporter, pre_compiled_lib, &prog) { return prog; } @@ -130,7 +132,8 @@ fn has_unit_test_module(prog: &P::Program) -> bool { } fn check_has_unit_test_module( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, + reporter: &DiagnosticReporter, pre_compiled_lib: Option>, prog: &P::Program, ) -> bool { @@ -148,7 +151,7 @@ fn check_has_unit_test_module( P::Definition::Module(P::ModuleDefinition { name, .. }) => name.0.loc, P::Definition::Address(P::AddressDefinition { loc, .. }) => *loc, }; - compilation_env.add_diag(diag!( + reporter.add_diag(diag!( Attributes::InvalidTest, ( loc, diff --git a/external-crates/move/crates/move-compiler/src/unit_test/mod.rs b/external-crates/move/crates/move-compiler/src/unit_test/mod.rs index 7eccd784e2e..04feb4cc563 100644 --- a/external-crates/move/crates/move-compiler/src/unit_test/mod.rs +++ b/external-crates/move/crates/move-compiler/src/unit_test/mod.rs @@ -6,6 +6,7 @@ use crate::{ compiled_unit::NamedCompiledModule, shared::files::MappedFiles, shared::NumericalAddress, }; +use move_binary_format::CompiledModule; use move_core_types::{ account_address::AccountAddress, identifier::Identifier, @@ -24,6 +25,7 @@ pub struct TestPlan { pub mapped_files: MappedFiles, pub module_tests: BTreeMap, pub module_info: BTreeMap, + pub bytecode_deps_modules: Vec, } #[derive(Debug, Clone)] @@ -92,6 +94,7 @@ impl TestPlan { tests: Vec, mapped_files: MappedFiles, units: Vec, + bytecode_deps_modules: Vec, ) -> Self { let module_tests: BTreeMap<_, _> = tests .into_iter() @@ -107,6 +110,7 @@ impl TestPlan { mapped_files, module_tests, module_info, + bytecode_deps_modules, } } } diff --git a/external-crates/move/crates/move-compiler/src/unit_test/plan_builder.rs b/external-crates/move/crates/move-compiler/src/unit_test/plan_builder.rs index 4609e50d719..ec2a19a89a2 100644 --- a/external-crates/move/crates/move-compiler/src/unit_test/plan_builder.rs +++ b/external-crates/move/crates/move-compiler/src/unit_test/plan_builder.rs @@ -6,6 +6,7 @@ use crate::{ cfgir::ast as G, diag, + diagnostics::{warning_filters::WarningFilters, Diagnostic, DiagnosticReporter, Diagnostics}, expansion::ast::{ self as E, Address, Attribute, AttributeValue, Attributes, ModuleAccess_, ModuleIdent, ModuleIdent_, @@ -34,12 +35,14 @@ use move_symbol_pool::Symbol; use std::collections::BTreeMap; struct Context<'env> { - env: &'env mut CompilationEnv, + #[allow(unused)] + env: &'env CompilationEnv, + reporter: DiagnosticReporter<'env>, constants: UniqueMap, Attributes)>>, } impl<'env> Context<'env> { - fn new(compilation_env: &'env mut CompilationEnv, prog: &G::Program) -> Self { + fn new(compilation_env: &'env CompilationEnv, prog: &G::Program) -> Self { let constants = prog.modules.ref_map(|_mident, module| { module.constants.ref_map(|_name, constant| { let v_opt = constant.value.as_ref().and_then(|v| match v { @@ -49,12 +52,31 @@ impl<'env> Context<'env> { (constant.loc, v_opt, constant.attributes.clone()) }) }); + let reporter = compilation_env.diagnostic_reporter_at_top_level(); Self { env: compilation_env, + reporter, constants, } } + pub fn add_diag(&self, diag: Diagnostic) { + self.reporter.add_diag(diag); + } + + #[allow(unused)] + pub fn add_diags(&self, diags: Diagnostics) { + self.reporter.add_diags(diags); + } + + pub fn push_warning_filter_scope(&mut self, filters: WarningFilters) { + self.reporter.push_warning_filter_scope(filters) + } + + pub fn pop_warning_filter_scope(&mut self) { + self.reporter.pop_warning_filter_scope() + } + fn resolve_address(&self, addr: &Address) -> NumericalAddress { (*addr).into_addr_bytes() } @@ -73,7 +95,7 @@ impl<'env> Context<'env> { // Constructs a test plan for each module in `prog`. This also validates the // structure of the attributes as the test plan is constructed. pub fn construct_test_plan( - compilation_env: &mut CompilationEnv, + compilation_env: &CompilationEnv, package_filter: Option, prog: &G::Program, ) -> Option> { @@ -86,7 +108,15 @@ pub fn construct_test_plan( prog.modules .key_cloned_iter() .flat_map(|(module_ident, module_def)| { - construct_module_test_plan(&mut context, package_filter, module_ident, module_def) + context.push_warning_filter_scope(module_def.warning_filter); + let plan = construct_module_test_plan( + &mut context, + package_filter, + module_ident, + module_def, + ); + context.pop_warning_filter_scope(); + plan }) .collect(), ) @@ -105,8 +135,11 @@ fn construct_module_test_plan( .functions .iter() .filter_map(|(loc, fn_name, func)| { - build_test_info(context, loc, fn_name, func) - .map(|test_case| (fn_name.to_string(), test_case)) + context.push_warning_filter_scope(func.warning_filter); + let info = build_test_info(context, loc, fn_name, func) + .map(|test_case| (fn_name.to_string(), test_case)); + context.pop_warning_filter_scope(); + info }) .collect(); @@ -144,7 +177,7 @@ fn build_test_info<'func>( let fn_msg = "Only functions defined as a test with #[test] can also have an \ #[expected_failure] attribute"; let abort_msg = "Attributed as #[expected_failure] here"; - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidUsage, (fn_loc, fn_msg), (abort_attribute.loc, abort_msg), @@ -155,7 +188,7 @@ fn build_test_info<'func>( (Some(test_attribute), Some(random_test_attribute)) => { let msg = "Function annotated as both #[test] and #[random_test]. You need to declare \ it as either one or the other"; - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidUsage, (random_test_attribute.loc, msg), (test_attribute.loc, PREVIOUSLY_ANNOTATED_MSG), @@ -171,7 +204,7 @@ fn build_test_info<'func>( if let Some(test_only_attribute) = test_only_attribute_opt { let msg = "Function annotated as both #[test] and #[test_only]. You need to declare \ it as either one or the other"; - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidUsage, (test_only_attribute.loc, msg), (test_attribute.loc, PREVIOUSLY_ANNOTATED_MSG), @@ -205,7 +238,7 @@ fn build_test_info<'func>( "Supported builti-in types are: bool, u8, u16, u32, u64, \ u128, u256, address, and vector where T is a built-in type", ); - context.env.add_diag(diag); + context.add_diag(diag); return None; } }; @@ -214,7 +247,7 @@ fn build_test_info<'func>( None => { let missing_param_msg = "Missing test parameter assignment in test. Expected a \ parameter to be assigned in this attribute"; - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidTest, (test_attribute.loc, missing_param_msg), (vloc, "Corresponding to this parameter"), @@ -227,7 +260,7 @@ fn build_test_info<'func>( if is_random_test && arguments.is_empty() { let msg = "No parameters to generate for random test. A #[random_test] function must \ have at least one parameter to generate."; - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidTest, (test_attribute.loc, msg), (fn_loc, IN_THIS_TEST_MSG), @@ -266,7 +299,7 @@ fn parse_test_attribute( match test_attribute { EA::Name(_) | EA::Parameterized(_, _) if depth > 0 => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidTest, (*aloc, "Unexpected nested attribute in test declaration"), )); @@ -281,7 +314,7 @@ fn parse_test_attribute( } EA::Assigned(nm, attr_value) => { if depth != 1 { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidTest, (*aloc, "Unexpected nested attribute in test declaration"), )); @@ -291,7 +324,7 @@ fn parse_test_attribute( let value = match convert_attribute_value_to_move_value(context, attr_value) { Some(move_value) => move_value, None => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (*assign_loc, "Unsupported attribute value"), (*aloc, "Assigned in this attribute"), @@ -338,7 +371,7 @@ fn parse_failure_attribute( let invalid_assignment_msg = "Invalid expected failure code assignment"; let expected_msg = "Expect an #[expected_failure(...)] attribute for error specification"; - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (assign_loc, invalid_assignment_msg), (*aloc, expected_msg), @@ -371,9 +404,7 @@ fn parse_failure_attribute( .to_vec() .join(", ") ); - context - .env - .add_diag(diag!(Attributes::InvalidValue, (*aloc, invalid_attr_msg))); + context.add_diag(diag!(Attributes::InvalidValue, (*aloc, invalid_attr_msg))); return None; } let (expected_failure_kind, (attr_loc, attr)) = @@ -402,7 +433,7 @@ fn parse_failure_attribute( attribute.", TestingAttribute::ERROR_LOCATION ); - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::ValueWarning, (attr_loc, BAD_ABORT_VALUE_WARNING), (value_loc, tip) @@ -502,7 +533,7 @@ fn parse_failure_attribute( ); let no_code = format!("No status code associated with value '{move_error_type}'"); - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (value_name_loc, bad_value), (major_value_loc, no_code) @@ -543,9 +574,7 @@ fn parse_failure_attribute( "Unused attribute for {}", TestingAttribute::ExpectedFailure.name() ); - context - .env - .add_diag(diag!(UnusedItem::Attribute, (loc, msg))); + context.add_diag(diag!(UnusedItem::Attribute, (loc, msg))); } Some(ExpectedFailure::ExpectedWithError(ExpectedMoveError( status_code, @@ -573,7 +602,7 @@ fn check_attribute_unassigned( "Expected no assigned value, e.g. '{}', for expected failure attribute", kind ); - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (attr_loc, "Unsupported attribute in this location"), (loc, msg) @@ -600,7 +629,7 @@ fn get_assigned_attribute( "Expected assigned value, e.g. '{}=...', for expected failure attribute", kind ); - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (attr_loc, "Unsupported attribute in this location"), (loc, msg) @@ -617,7 +646,7 @@ fn convert_location(context: &mut Context, attr_loc: Loc, attr: Attribute) -> Op match value { sp!(vloc, EAV::Module(module)) => convert_module_id(context, vloc, &module), sp!(vloc, _) => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (loc, INVALID_VALUE), (vloc, "Expected a module identifier, e.g. 'std::vector'") @@ -647,7 +676,7 @@ fn convert_constant_value_u64_constant_or_value( let modules_constants = context.constants().get(module).unwrap(); let constant = match modules_constants.get_(&member.value) { None => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (vloc, INVALID_VALUE), ( @@ -669,7 +698,7 @@ fn convert_constant_value_u64_constant_or_value( "Constant '{module}::{member}' has a non-u64 value. \ Only 'u64' values are permitted" ); - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (vloc, INVALID_VALUE), (*cloc, msg), @@ -682,7 +711,7 @@ fn convert_constant_value_u64_constant_or_value( fn convert_module_id(context: &mut Context, vloc: Loc, module: &ModuleIdent) -> Option { if !context.constants.contains_key(module) { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (vloc, INVALID_VALUE), (module.loc, format!("Unbound module '{module}'")), @@ -695,7 +724,7 @@ fn convert_module_id(context: &mut Context, vloc: Loc, module: &ModuleIdent) -> value: sp!(_, a), .. } => a.into_inner(), Address::NamedUnassigned(addr) => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (vloc, INVALID_VALUE), (*mloc, format!("Unbound address '{addr}'")), @@ -724,7 +753,7 @@ fn convert_attribute_value_u64( | sp!(vloc, EAV::Value(sp!(_, EV::U32(_)))) | sp!(vloc, EAV::Value(sp!(_, EV::U128(_)))) | sp!(vloc, EAV::Value(sp!(_, EV::U256(_)))) => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (loc, INVALID_VALUE), (*vloc, "Annotated non-u64 literals are not permitted"), @@ -732,7 +761,7 @@ fn convert_attribute_value_u64( None } sp!(vloc, _) => { - context.env.add_diag(diag!( + context.add_diag(diag!( Attributes::InvalidValue, (loc, INVALID_VALUE), (*vloc, "Unsupported value in this assignment"), @@ -767,9 +796,7 @@ fn check_location( "Expected '{}' following '{attr}'", TestingAttribute::ERROR_LOCATION ); - context - .env - .add_diag(diag!(Attributes::InvalidUsage, (loc, msg))); + context.add_diag(diag!(Attributes::InvalidUsage, (loc, msg))); } location } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/coin_field.exp b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/coin_field.exp index a6e066608cf..a3d910b141c 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/coin_field.exp +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/coin_field.exp @@ -1,22 +1,16 @@ warning[Lint W99003]: sub-optimal 'iota::coin::Coin' field type - ┌─ tests/iota_mode/linter/coin_field.move:12:12 + ┌─ tests/iota_mode/linter/coin_field.move:14:12 │ -12 │ struct S2 has key, store { - │ ^^ The field 'c' of 'S2' has type 'iota::coin::Coin' -13 │ id: UID, 14 │ c: Coin, - │ - Storing 'iota::balance::Balance' in this field will typically be more space-efficient + │ ^^^^^^^^ Sub-optimal 'iota::coin::Coin' field type. Using 'iota::balance::Balance' instead will be more space efficient │ = This warning can be suppressed with '#[allow(lint(coin_field))]' applied to the 'module' or module member ('const', 'fun', or 'struct') warning[Lint W99003]: sub-optimal 'iota::coin::Coin' field type - ┌─ tests/iota_mode/linter/coin_field.move:26:12 + ┌─ tests/iota_mode/linter/coin_field.move:28:12 │ -26 │ struct S2 has key, store { - │ ^^ The field 'c' of 'S2' has type 'iota::coin::Coin' -27 │ id: UID, 28 │ c: Balance, - │ - Storing 'iota::balance::Balance' in this field will typically be more space-efficient + │ ^^^^^^^^^^^ Sub-optimal 'iota::coin::Coin' field type. Using 'iota::balance::Balance' instead will be more space efficient │ = This warning can be suppressed with '#[allow(lint(coin_field))]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.exp b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.exp index 168b51a4cf9..bd8eb2d2fb3 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.exp +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.exp @@ -2,38 +2,38 @@ warning[Lint W99002]: potentially unenforceable custom transfer/share/freeze pol ┌─ tests/iota_mode/linter/custom_state_change.move:16:16 │ 16 │ public fun custom_transfer_bad(o: S1, ctx: &TxContext) { - │ ^^^^^^^^^^^^^^^^^^^ - An instance of a module-private type with a store ability to be transferred coming from here + │ ^^^^^^^^^^^^^^^^^^^ - An instance of a module-private type with a 'store' ability to be transferred coming from here │ │ │ Potential unintended implementation of a custom transfer function. 17 │ transfer::transfer(o, tx_context::sender(ctx)) - │ -------- Instances of a type with a store ability can be transferred using the public_transfer function which often negates the intent of enforcing a custom transfer policy + │ -------- Instances of a type with a 'store' ability can be transferred using the 'public_transfer' function which often negates the intent of enforcing a custom transfer policy │ - = A custom transfer policy for a given type is implemented through calling the private transfer function variant in the module defining this type + = A custom transfer policy for a given type is implemented through calling the private 'transfer' function variant in the module defining this type = This warning can be suppressed with '#[allow(lint(custom_state_change))]' applied to the 'module' or module member ('const', 'fun', or 'struct') warning[Lint W99002]: potentially unenforceable custom transfer/share/freeze policy ┌─ tests/iota_mode/linter/custom_state_change.move:21:16 │ 21 │ public fun custom_share_bad(o: S1) { - │ ^^^^^^^^^^^^^^^^ - An instance of a module-private type with a store ability to be shared coming from here + │ ^^^^^^^^^^^^^^^^ - An instance of a module-private type with a 'store' ability to be shared coming from here │ │ - │ Potential unintended implementation of a custom share_object function. + │ Potential unintended implementation of a custom share function. 22 │ transfer::share_object(o) - │ ------------ Instances of a type with a store ability can be shared using the public_share_object function which often negates the intent of enforcing a custom share policy + │ ------------ Instances of a type with a 'store' ability can be shared using the 'public_share_object' function which often negates the intent of enforcing a custom share policy │ - = A custom share policy for a given type is implemented through calling the private share_object function variant in the module defining this type + = A custom share policy for a given type is implemented through calling the private 'share_object' function variant in the module defining this type = This warning can be suppressed with '#[allow(lint(custom_state_change))]' applied to the 'module' or module member ('const', 'fun', or 'struct') warning[Lint W99002]: potentially unenforceable custom transfer/share/freeze policy ┌─ tests/iota_mode/linter/custom_state_change.move:25:16 │ 25 │ public fun custom_freeze_bad(o: S1) { - │ ^^^^^^^^^^^^^^^^^ - An instance of a module-private type with a store ability to be frozen coming from here + │ ^^^^^^^^^^^^^^^^^ - An instance of a module-private type with a 'store' ability to be frozen coming from here │ │ - │ Potential unintended implementation of a custom freeze_object function. + │ Potential unintended implementation of a custom freeze function. 26 │ transfer::freeze_object(o) - │ ------------- Instances of a type with a store ability can be frozen using the public_freeze_object function which often negates the intent of enforcing a custom freeze policy + │ ------------- Instances of a type with a 'store' ability can be frozen using the 'public_freeze_object' function which often negates the intent of enforcing a custom freeze policy │ - = A custom freeze policy for a given type is implemented through calling the private freeze_object function variant in the module defining this type + = A custom freeze policy for a given type is implemented through calling the private 'freeze_object' function variant in the module defining this type = This warning can be suppressed with '#[allow(lint(custom_state_change))]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.move index 66dce7da418..6f193cb3753 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/custom_state_change.move @@ -28,11 +28,12 @@ module a::test { } module iota::object { + const ZERO: u64 = 0; struct UID has store { id: address, } public fun new(_: &mut iota::tx_context::TxContext): UID { - abort 0 + abort ZERO } } @@ -44,15 +45,16 @@ module iota::tx_context { } module iota::transfer { + const ZERO: u64 = 0; public fun transfer(_: T, _: address) { - abort 0 + abort ZERO } public fun freeze_object(_: T) { - abort 0 + abort ZERO } public fun share_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.exp b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.exp new file mode 100644 index 00000000000..20f7df540c3 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.exp @@ -0,0 +1,34 @@ +warning[Lint W99000]: possible owned object share + ┌─ tests/iota_mode/linter/false_positive_share_owned.move:12:9 + │ + 6 │ struct Obj has key, store { + │ ----- Potentially an owned object because 'store' grants access to public transfers + · +10 │ public fun arg_object(o: Obj) { + │ - A potentially owned object coming from here +11 │ let arg = o; +12 │ transfer::public_share_object(arg); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Creating a fresh object and sharing it within the same function will ensure this does not abort. + │ Potential abort from a (potentially) owned object created by a different transaction. + │ + = This warning can be suppressed with '#[allow(lint(share_owned))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W99000]: possible owned object share + ┌─ tests/iota_mode/linter/false_positive_share_owned.move:42:9 + │ +30 │ fun make_obj(o: Obj2, ctx: &mut iota::tx_context::TxContext): Obj { + │ --- A potentially owned object coming from here + · +37 │ transfer::transfer(o, iota::tx_context::sender(ctx)); + │ ---------------------------------------------------- Transferred as an owned object here + · +42 │ transfer::share_object(o); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Creating a fresh object and sharing it within the same function will ensure this does not abort. + │ Potential abort from a (potentially) owned object created by a different transaction. + │ + = This warning can be suppressed with '#[allow(lint(share_owned))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.move new file mode 100644 index 00000000000..f9d0a39bcc2 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/false_positive_share_owned.move @@ -0,0 +1,77 @@ +// object has store but is never created externally +module a::has_store { + use iota::transfer; + use iota::object::UID; + + struct Obj has key, store { + id: UID + } + + public fun arg_object(o: Obj) { + let arg = o; + transfer::public_share_object(arg); + } +} + +// object is created locally, but the analysis cannot determine that currently +module a::cannot_determine_to_be_new { + use iota::transfer; + use iota::object::UID; + + struct Obj has key { + id: UID + } + + struct Obj2 has key { + id: UID + } + + // we do not do interprodedural analysis here + fun make_obj(o: Obj2, ctx: &mut iota::tx_context::TxContext): Obj { + transfer::transfer(o, @0); + Obj { id: iota::object::new(ctx) } + } + + public fun transfer(o2: Obj2, ctx: &mut iota::tx_context::TxContext) { + let o = make_obj(o2, ctx); + transfer::transfer(o, iota::tx_context::sender(ctx)); + } + + public fun share(o2: Obj2, ctx: &mut iota::tx_context::TxContext) { + let o = make_obj(o2, ctx); // cannot determine this is local because of `X` + transfer::share_object(o); + } +} + +module iota::tx_context { + struct TxContext has drop {} + public fun sender(_: &TxContext): address { + @0 + } +} + +module iota::object { + const ZERO: u64 = 0; + struct UID has store { + id: address, + } + public fun delete(_: UID) { + abort ZERO + } + public fun new(_: &mut iota::tx_context::TxContext): UID { + abort ZERO + } +} + +module iota::transfer { + const ZERO: u64 = 0; + public fun transfer(_: T, _: address) { + abort ZERO + } + public fun share_object(_: T) { + abort ZERO + } + public fun public_share_object(_: T) { + abort ZERO + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freeze_wrapped.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freeze_wrapped.move index 74bc4e982ee..dd032b52b5d 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freeze_wrapped.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freeze_wrapped.move @@ -74,7 +74,8 @@ module iota::object { } module iota::transfer { + const ZERO: u64 = 0; public fun public_freeze_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_negatives.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_negatives.move index 2bd5a31e07d..22da27bf74b 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_negatives.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_negatives.move @@ -46,7 +46,8 @@ module iota::object { } module iota::transfer { + const ZERO: u64 = 0; public fun public_freeze_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_positives.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_positives.move index c3913724ffc..4ee1fa3ead9 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_positives.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_false_positives.move @@ -46,7 +46,8 @@ module iota::object { } module iota::transfer { + const ZERO: u64 = 0; public fun public_freeze_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_suppression.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_suppression.move index 05e4efc06c2..4ab5e3cac35 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_suppression.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_suppression.move @@ -41,7 +41,8 @@ module iota::object { } module iota::transfer { + const ZERO: u64 = 0; public fun public_freeze_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_negatives.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_negatives.move index 4b4f4f091e5..a239b1b04a9 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_negatives.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_negatives.move @@ -70,7 +70,8 @@ module iota::object { } module iota::transfer { + const ZERO: u64 = 0; public fun public_freeze_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_positives.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_positives.move index 7faad775504..e3cc81d90ee 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_positives.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/freezing_capability_true_positives.move @@ -38,7 +38,8 @@ module iota::object { } module iota::transfer { + const ZERO: u64 = 0; public fun public_freeze_object(_: T) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/self_transfer.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/self_transfer.move index 5d4ca4815b0..2f21381a389 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/self_transfer.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/self_transfer.move @@ -58,11 +58,12 @@ module a::test { } module iota::object { + const ZERO: u64 = 0; struct UID has store { id: address, } public fun new(_: &mut iota::tx_context::TxContext): UID { - abort 0 + abort ZERO } } @@ -74,11 +75,12 @@ module iota::tx_context { } module iota::transfer { + const ZERO: u64 = 0; public fun transfer(_: T, _: address) { - abort 0 + abort ZERO } public fun public_transfer(_: T, _: address) { - abort 0 + abort ZERO } } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.exp b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.exp deleted file mode 100644 index 260523a0432..00000000000 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.exp +++ /dev/null @@ -1,27 +0,0 @@ -warning[Lint W99000]: possible owned object share - ┌─ tests/iota_mode/linter/share_owned.move:15:9 - │ -13 │ public entry fun arg_object(o: Obj) { - │ - A potentially owned object coming from here -14 │ let arg = o; -15 │ transfer::public_share_object(arg); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Creating a fresh object and sharing it within the same function will ensure this does not abort. - │ Potential abort from a (potentially) owned object created by a different transaction. - │ - = This warning can be suppressed with '#[allow(lint(share_owned))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W99000]: possible owned object share - ┌─ tests/iota_mode/linter/share_owned.move:35:9 - │ -34 │ let Wrapper { id, i: _, o } = w; - │ - A potentially owned object coming from here -35 │ transfer::public_share_object(o); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Creating a fresh object and sharing it within the same function will ensure this does not abort. - │ Potential abort from a (potentially) owned object created by a different transaction. - │ - = This warning can be suppressed with '#[allow(lint(share_owned))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.move deleted file mode 100644 index c022f754002..00000000000 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/share_owned.move +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -module a::test1 { - use iota::transfer; - use iota::object::UID; - - struct Obj has key, store { - id: UID - } - - public entry fun arg_object(o: Obj) { - let arg = o; - transfer::public_share_object(arg); - } -} - -module a::test2 { - use iota::transfer; - use iota::object::{Self, UID}; - - struct Obj has key, store { - id: UID - } - - struct Wrapper has key, store { - id: UID, - i: u32, - o: Obj, - } - - public entry fun unpack_obj(w: Wrapper) { - let Wrapper { id, i: _, o } = w; - transfer::public_share_object(o); - object::delete(id); - } - - #[allow(lint(share_owned))] - public entry fun unpack_obj_suppressed(w: Wrapper) { - let Wrapper { id, i: _, o } = w; - transfer::public_share_object(o); - object::delete(id); - } -} - -module iota::object { - struct UID has store { - id: address, - } - public fun delete(_: UID) { - abort 0 - } -} - -module iota::transfer { - public fun public_share_object(_: T) { - abort 0 - } -} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_negative_share_owned.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_negative_share_owned.move new file mode 100644 index 00000000000..1cc85ec66a6 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_negative_share_owned.move @@ -0,0 +1,108 @@ +// object is re shared, but it is never transferred and doesn't have public transfer +module a::is_not_transferred { + use iota::transfer; + use iota::tx_context::TxContext; + use iota::object::UID; + + struct Obj has key { + id: UID + } + + public fun make_obj(ctx: &mut TxContext): Obj { + Obj { id: iota::object::new(ctx) } + } + + public fun crate(ctx: &mut TxContext) { + transfer::share_object(make_obj(ctx)); + } + + public fun share(o: Obj) { + transfer::share_object(o); + } +} + +// object is created locally, even though it is transferred somewhere else and has public share +module a::can_determine_to_be_new { + use iota::transfer; + use iota::object::UID; + + struct Obj has key, store { + id: UID + } + + fun make_obj(_: u64, _: vector>, ctx: &mut iota::tx_context::TxContext): Obj { + Obj { id: iota::object::new(ctx) } + } + + public fun transfer(ctx: &mut iota::tx_context::TxContext) { + let o = make_obj(0, vector[], ctx); + transfer::transfer(o, @0); + } + + public fun share(ctx: &mut iota::tx_context::TxContext) { + let o = make_obj(0, vector[], ctx); + transfer::share_object(o); + } +} + + +// object is created locally, but the analysis cannot determine that currently +module b::can_determine_to_be_new_with_struct { + use iota::transfer; + use iota::object::UID; + + struct Obj has key { + id: UID + } + + struct X has drop {} + + fun make_obj(_: X, ctx: &mut iota::tx_context::TxContext): Obj { + Obj { id: iota::object::new(ctx) } + } + + public fun transfer(ctx: &mut iota::tx_context::TxContext) { + let o = make_obj(X {}, ctx); + transfer::transfer(o, iota::tx_context::sender(ctx)); + } + + public fun share(ctx: &mut iota::tx_context::TxContext) { + let o = make_obj(X {}, ctx); + transfer::share_object(o); + } +} + + + +module iota::tx_context { + struct TxContext has drop {} + public fun sender(_: &TxContext): address { + @0 + } +} + +module iota::object { + const ZERO: u64 = 0; + struct UID has store { + id: address, + } + public fun delete(_: UID) { + abort ZERO + } + public fun new(_: &mut iota::tx_context::TxContext): UID { + abort ZERO + } +} + +module iota::transfer { + const ZERO: u64 = 0; + public fun transfer(_: T, _: address) { + abort ZERO + } + public fun share_object(_: T) { + abort ZERO + } + public fun public_share_object(_: T) { + abort ZERO + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.exp b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.exp new file mode 100644 index 00000000000..b47f371dfa1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.exp @@ -0,0 +1,34 @@ +warning[Lint W99000]: possible owned object share + ┌─ tests/iota_mode/linter/true_positive_share_owned.move:17:9 + │ + 7 │ struct Obj has key, store { + │ ----- Potentially an owned object because 'store' grants access to public transfers + · +15 │ public fun share(o: Obj) { + │ - A potentially owned object coming from here +16 │ let arg = o; +17 │ transfer::public_share_object(arg); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Creating a fresh object and sharing it within the same function will ensure this does not abort. + │ Potential abort from a (potentially) owned object created by a different transaction. + │ + = This warning can be suppressed with '#[allow(lint(share_owned))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W99000]: possible owned object share + ┌─ tests/iota_mode/linter/true_positive_share_owned.move:42:9 + │ +37 │ transfer::transfer(arg, tx_context::sender(ctx)); + │ ------------------------------------------------ Transferred as an owned object here + · +40 │ public fun share(o: Obj) { + │ - A potentially owned object coming from here +41 │ let arg = o; +42 │ transfer::share_object(arg); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Creating a fresh object and sharing it within the same function will ensure this does not abort. + │ Potential abort from a (potentially) owned object created by a different transaction. + │ + = This warning can be suppressed with '#[allow(lint(share_owned))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.move b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.move new file mode 100644 index 00000000000..4dc28a92649 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/linter/true_positive_share_owned.move @@ -0,0 +1,77 @@ +// object has store, might be transferred elsewhere +module a::has_store { + use iota::transfer; + use iota::tx_context::TxContext; + use iota::object::UID; + + struct Obj has key, store { + id: UID + } + + public fun make_obj(ctx: &mut TxContext): Obj { + Obj { id: iota::object::new(ctx) } + } + + public fun share(o: Obj) { + let arg = o; + transfer::public_share_object(arg); + } +} + +// object does not have store and is transferred +module a::is_transferred { + use iota::transfer; + use iota::tx_context::{Self, TxContext}; + use iota::object::UID; + + struct Obj has key { + id: UID + } + + public fun make_obj(ctx: &mut TxContext): Obj { + Obj { id: iota::object::new(ctx) } + } + + public fun transfer(o: Obj, ctx: &mut TxContext) { + let arg = o; + transfer::transfer(arg, tx_context::sender(ctx)); + } + + public fun share(o: Obj) { + let arg = o; + transfer::share_object(arg); + } +} + +module iota::tx_context { + struct TxContext has drop {} + public fun sender(_: &TxContext): address { + @0 + } +} + +module iota::object { + const ZERO: u64 = 0; + struct UID has store { + id: address, + } + public fun delete(_: UID) { + abort ZERO + } + public fun new(_: &mut iota::tx_context::TxContext): UID { + abort ZERO + } +} + +module iota::transfer { + const ZERO: u64 = 0; + public fun transfer(_: T, _: address) { + abort ZERO + } + public fun share_object(_: T) { + abort ZERO + } + public fun public_share_object(_: T) { + abort ZERO + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.exp b/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.exp index c509b1a175d..1a14d8e914f 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.exp +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.exp @@ -9,12 +9,12 @@ error[Iota E02007]: invalid object declaration │ Invalid object 'S'. Structs with the 'key' ability must have 'id: iota::object::UID' as their first field error[Iota E02007]: invalid object declaration - ┌─ tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.move:13:9 + ┌─ tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.move:12:9 │ -12 │ struct S has key { +11 │ struct S has key { │ --- The 'key' ability is used to declare objects in Iota -13 │ id: UID - │ ^^ --- But found type: '0x2::object::UID' +12 │ id: UID + │ ^^ --- But found type: '0x3::object::UID' │ │ │ Invalid object 'S'. Structs with the 'key' ability must have 'id: iota::object::UID' as their first field diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.move b/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.move index c79eddab7cd..03e079d8830 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/struct_with_key/key_struct_id_field_incorrect_struct_address.move @@ -6,8 +6,7 @@ module a::object { } } -// TODO we might want to support this -module 0x2::object { +module 0x3::object { struct UID has store { flag: bool } struct S has key { id: UID diff --git a/external-crates/move/crates/move-compiler/tests/linter/correct_redundant_ref_deref.move b/external-crates/move/crates/move-compiler/tests/linter/correct_redundant_ref_deref.move new file mode 100644 index 00000000000..9d985802b70 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/correct_redundant_ref_deref.move @@ -0,0 +1,10 @@ +module 0x42::M { + struct MyResource has copy, drop{ + value: u64, + } + + public fun test_borrow_deref_ref() { + let resource = MyResource { value: 10 }; + let _ref1 = &resource; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_combinable_comparisons.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_combinable_comparisons.move new file mode 100644 index 00000000000..4df6ba1a675 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_combinable_comparisons.move @@ -0,0 +1,7 @@ +// tests lints against combinable comparisons that can be simplified to a single comparison. +// these cases should work but do not +module a::m { + fun negated(x: u64, y: u64) { + !(x == y) || x > y; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operands.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operands.move new file mode 100644 index 00000000000..bf05f444b13 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operands.move @@ -0,0 +1,8 @@ +// this should warn, but it does not at the current state of optimizations in the compiler + +module a::m { + fun test_equal_operand() { + let x = 0; + &x == &0; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_loop_without_exit.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_loop_without_exit.move new file mode 100644 index 00000000000..2ad2db4c826 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_loop_without_exit.move @@ -0,0 +1,15 @@ +// tests for false negatives in the loop without exit lint + +module a::m { + public fun t1() { + loop { + if (false) break + } + } + + public fun t2() { + loop { + if (false) return + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.move new file mode 100644 index 00000000000..0621d6e2517 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.move @@ -0,0 +1,13 @@ +#[allow(lint(always_equal_operands))] +module 0x42::M { + public fun zero_shift_complex(x: u64, y: u64): u64 { + x * (y - y) // This is effectively * 0, but is not currently caught + } + + public fun ast_fold() { + // we do not lint on these because they are folded to a single value + let x = 0; + x * 1; + 1 * 0; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_self_assigment.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_self_assigment.move new file mode 100644 index 00000000000..49416a182b4 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_self_assigment.move @@ -0,0 +1,26 @@ +// tests for cases that self-assignment could warn, but currently dont + +module a::m { + fun t(cond: bool, other: u64) { + let x = 0; + x = if (cond) x else x; + x; + + x = if (cond) x else other; + x; + + x = { 0; x }; + x; + + x = { let y = 0; y; x }; + x; + + // TODO move most lints to 2024 + // x = match (cond) { true => x, false => x }; + // x; + + let x = &other; + other = *x; + other; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_conditional.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_conditional.move new file mode 100644 index 00000000000..a70e993da5b --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_conditional.move @@ -0,0 +1,14 @@ +module a::m { + // These very simply could be rewritten but we are overly conservative when it comes to blocks + public fun t0(condition: bool) { + if (condition) { foo(); true } else false; + if (condition) b"" else { foo(); foo(); vector[] }; + } + + // we don't do this check after constant folding + public fun t1(condition: bool) { + if (condition) 1 + 1 else 2; + } + + fun foo() {} +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.exp b/external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.exp new file mode 100644 index 00000000000..553be5f47cb --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.exp @@ -0,0 +1,172 @@ +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:10:21 + │ +10 │ let _ref = &*(&resource); // Redundant borrow-dereference + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:15:25 + │ +15 │ let _ref = &mut *(&mut resource); // Redundant mutable borrow-dereference + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:20:22 + │ +20 │ let _value = *(&resource.value); // Redundant dereference of field borrow + │ ^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:57:21 + │ +57 │ let _ref = &*(&*(&resource)); // Triple nested borrow-dereference, might be missed + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:57:24 + │ +57 │ let _ref = &*(&*(&resource)); // Triple nested borrow-dereference, might be missed + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E04010]: cannot infer type + ┌─ tests/linter/incorrect_redundant_ref_deref.move:68:13 + │ +68 │ let _value = *((&resource).value); // Complex expression, might be missed + │ ^^^^^^ Could not infer this type. Try adding an annotation + +error[E04007]: incompatible types + ┌─ tests/linter/incorrect_redundant_ref_deref.move:68:22 + │ + 3 │ value: u64, + │ --- Given: 'u64' + · +68 │ let _value = *((&resource).value); // Complex expression, might be missed + │ ^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Invalid dereference. + │ Expected: '&_' + +error[E04010]: cannot infer type + ┌─ tests/linter/incorrect_redundant_ref_deref.move:68:22 + │ +68 │ let _value = *((&resource).value); // Complex expression, might be missed + │ ^^^^^^^^^^^^^^^^^^^^ Could not infer this type. Try adding an annotation + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:75:21 + │ +75 │ let _ref = &*&resource.value; // Redundant borrow-dereference on field + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:80:21 + │ +80 │ let _ref = &*&(&resource).value; // Nested redundant borrow-dereference on field + │ ^^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:86:21 + │ +86 │ let _ref = &*&0; // Redundant borrow-dereference on literal + │ ^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:94:21 + │ +94 │ let _ref = &*&get_resource(); // Redundant borrow-dereference on function call result + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:107:21 + │ +107 │ let _ref = &*&(&*&resource.value); // Multiple redundant borrows on field + │ ^^^^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E04004]: expected a single non-reference type + ┌─ tests/linter/incorrect_redundant_ref_deref.move:107:22 + │ +107 │ let _ref = &*&(&*&resource.value); // Multiple redundant borrows on field + │ ^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Expected a single non-reference type, but found: '&u64' + │ Invalid borrow + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:107:25 + │ +107 │ let _ref = &*&(&*&resource.value); // Multiple redundant borrows on field + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[W09002]: unused variable + ┌─ tests/linter/incorrect_redundant_ref_deref.move:111:13 + │ +111 │ let mut resource = MyResource { value: 10 }; + │ ^^^ Unused local variable 'mut'. Consider removing or prefixing with an underscore: '_mut' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E01002]: unexpected token + ┌─ tests/linter/incorrect_redundant_ref_deref.move:111:17 + │ +111 │ let mut resource = MyResource { value: 10 }; + │ ^^^^^^^^ + │ │ + │ Unexpected 'resource' + │ Expected ';' + +error[E04010]: cannot infer type + ┌─ tests/linter/incorrect_redundant_ref_deref.move:112:21 + │ +112 │ let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows + │ ^^^^^^^^^^^^^^^^ Could not infer this type. Try adding an annotation + +error[E04010]: cannot infer type + ┌─ tests/linter/incorrect_redundant_ref_deref.move:112:27 + │ +112 │ let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows + │ ^^^^^^^^^^ Could not infer this type. Try adding an annotation + +error[E03009]: unbound variable + ┌─ tests/linter/incorrect_redundant_ref_deref.move:112:29 + │ +112 │ let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows + │ ^^^^^^^^ Unbound variable 'resource' + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:117:25 + │ +117 │ let _value = *&(*&resource.value + 1); // Redundant borrows in complex expression + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/incorrect_redundant_ref_deref.move:124:21 + │ +124 │ let _ref = &*(&resource.value); // Complex nested borrow on field, might be missed + │ ^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.move b/external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.move new file mode 100644 index 00000000000..fdbe0c3e3b7 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/incorrect_redundant_ref_deref.move @@ -0,0 +1,140 @@ +module 0x42::M { + struct MyResource has copy, drop { + value: u64, + } + + // True Positive Cases + + public fun true_positive_1() { + let resource = MyResource { value: 10 }; + let _ref = &*(&resource); // Redundant borrow-dereference + } + + public fun true_positive_2() { + let resource = MyResource { value: 10 }; + let _ref = &mut *(&mut resource); // Redundant mutable borrow-dereference + } + + public fun true_positive_3() { + let resource = MyResource { value: 10 }; + let _value = *(&resource.value); // Redundant dereference of field borrow + } + + // True Negative Cases + + public fun true_negative_1() { + let resource = MyResource { value: 10 }; + let _ref = &resource; // Direct borrow, no redundancy + } + + public fun true_negative_2() { + let resource = MyResource { value: 10 }; + let ref = &resource; + let _value = ref.value; // Accessing field through reference, no redundancy + } + + public fun true_negative_3() { + let resource = MyResource { value: 10 }; + let _copy = resource; // Creating a copy, no borrow involved + } + + // False Positive Cases + + public fun false_positive_2() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + let _ref2 = &*ref1; // Might be intentional for creating a new reference + } + + public fun false_positive_3(resource: &mut MyResource) { + let _ref = &mut *resource; // Might be necessary in generic contexts + } + + // False Negative Cases + + public fun false_negative_1() { + let resource = MyResource { value: 10 }; + let _ref = &*(&*(&resource)); // Triple nested borrow-dereference, might be missed + } + + public fun false_negative_2() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + let _ref2 = &(*ref1); // Dereference then reference, might be missed + } + + public fun false_negative_3() { + let resource = MyResource { value: 10 }; + let _value = *((&resource).value); // Complex expression, might be missed + } + + // New cases for field borrows + + public fun field_borrow_redundant() { + let resource = MyResource { value: 10 }; + let _ref = &*&resource.value; // Redundant borrow-dereference on field + } + + public fun field_borrow_nested() { + let resource = MyResource { value: 10 }; + let _ref = &*&(&resource).value; // Nested redundant borrow-dereference on field + } + + // New cases for non-local borrows + + public fun non_local_borrow_literal() { + let _ref = &*&0; // Redundant borrow-dereference on literal + } + + public fun get_resource(): MyResource { + MyResource { value: 20 } + } + + public fun non_local_borrow_function_call() { + let _ref = &*&get_resource(); // Redundant borrow-dereference on function call result + } + + // Helper method for the above test cases + public fun do_something(self: &MyResource) { + // Dummy implementation + let _ = self.value; + } + + // Additional test cases to cover more scenarios + + public fun multiple_field_borrows() { + let resource = MyResource { value: 10 }; + let _ref = &*&(&*&resource.value); // Multiple redundant borrows on field + } + + public fun mixed_borrow_types() { + let mut resource = MyResource { value: 10 }; + let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows + } + + public fun complex_expression() { + let resource = MyResource { value: 10 }; + let _value = *&(*&resource.value + 1); // Redundant borrows in complex expression + } + + // False negative cases for the new scenarios + + public fun false_negative_complex_field_borrow() { + let resource = MyResource { value: 10 }; + let _ref = &*(&resource.value); // Complex nested borrow on field, might be missed + } + + // Suppress Cases + + #[allow(lint(redundant_ref_deref))] + public fun suppress_case_1() { + let resource = MyResource { value: 10 }; + let _ref = &*(&resource); // Suppressed warning + } + + #[allow(lint(redundant_ref_deref))] + public fun suppress_case_2() { + let resource = MyResource { value: 10 }; + let _value = *(&resource.value); // Suppressed warning + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/allowed_unneeded_return.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/allowed_unneeded_return.move new file mode 100644 index 00000000000..6eac4f04655 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/allowed_unneeded_return.move @@ -0,0 +1,56 @@ +module 0x42::m; + +#[allow(lint(unneeded_return))] +fun t0(): u64 { return 5 } + +#[allow(lint(unneeded_return))] +fun t1(): u64 { return t0() } + +public struct S { } + +#[allow(lint(unneeded_return))] +fun t2(): S { return S { } } + +public enum E { V } + +#[allow(lint(unneeded_return))] +fun t3(): E { return E::V } + +#[allow(lint(unneeded_return))] +fun t4(): vector { return vector[1,2,3] } + +#[allow(lint(unneeded_return))] +fun t5() { return () } + +#[allow(lint(unneeded_return))] +fun t6(): u64 { let x = 0; return move x +} + +#[allow(lint(unneeded_return))] +fun t7(): u64 { + let x = 0; + return copy x +} + +const VALUE: u64 = 0; + +#[allow(lint(unneeded_return))] +fun t8(): u64 { return VALUE } + +#[allow(lint(unneeded_return))] +fun t9(): u64 { return 5 + 2 } + +#[allow(lint(unneeded_return))] +fun t10(): bool { return !true } + +#[allow(lint(unneeded_return))] +fun t11(x: &u64): u64 { return *x } + +#[allow(lint(unneeded_return))] +fun t12(x: u64): u128 { return x as u128 } + +#[allow(lint(unneeded_return))] +fun t13(): u64 { return (0: u64) } + +#[allow(lint(unneeded_return))] +fun t14(): u64 { return loop { break 5 } } diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/false_negative_equal_operands.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/false_negative_equal_operands.move new file mode 100644 index 00000000000..be5e3619785 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/false_negative_equal_operands.move @@ -0,0 +1,8 @@ +// this should warn, but it does not at the current state of optimizations in the compiler + +module a::m; +fun test_equal_operand() { + let x = 0; + &x == &0; + &1 == 1; +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.exp b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.exp new file mode 100644 index 00000000000..d82ebd52f64 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.exp @@ -0,0 +1,72 @@ +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:10:17 + │ +10 │ let _ref = &*&0; // Redundant borrow-dereference on literal + │ ^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:18:17 + │ +18 │ let _ref = &*&get_resource(); // Redundant borrow-dereference on function call result + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:27:17 + │ +27 │ let _ref = &*(&*&resource.a); // Multiple redundant borrows on field + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:27:20 + │ +27 │ let _ref = &*(&*&resource.a); // Multiple redundant borrows on field + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:32:18 + │ +32 │ let _ref = &(copy resource.a); // Multiple redundant borrows on field + │ ^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:37:17 + │ +37 │ let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:37:23 + │ +37 │ let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:47:17 + │ +47 │ let _a = *&(*&resource.a + 1); // Redundant borrows in complex expression + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_complex.move:52:15 + │ +52 │ let _a = (copy resource.a) + 1; // Redundant borrows in complex expression + │ ^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.move new file mode 100644 index 00000000000..de1b87a17f1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_complex.move @@ -0,0 +1,53 @@ +module 0x42::ComplexCases; + +public struct S has copy, drop { + a: u64, +} + +// Non-Local but Simple Borrow Cases + +public fun literal_case() { + let _ref = &*&0; // Redundant borrow-dereference on literal +} + +public fun literal_case_valid() { let _ref = &0; } + +public fun get_resource(): S { S { a: 20 } } + +public fun function_call_case() { + let _ref = &*&get_resource(); // Redundant borrow-dereference on function call result +} + +public fun function_call_case_valid() { let _ref = &get_resource(); } + +//Complex cases + +public fun field_borrows() { + let resource = S { a: 10 }; + let _ref = &*(&*&resource.a); // Multiple redundant borrows on field +} + +public fun field_borrows_valid() { + let resource = S { a: 10 }; + let _ref = &(copy resource.a); // Multiple redundant borrows on field +} + +public fun mixed_borrow_types() { + let resource = S { a: 10 }; + let _ref = &*&mut *&resource; // Mixed mutable and immutable redundant borrows +} + +public fun mixed_borrow_types_valid() { + let resource = S { a: 10 }; + let _ref = &(copy resource); // Mixed mutable and immutable redundant borrows +} + +public fun complex_expression() { + let resource = S { a: 10 }; + let _a = *&(*&resource.a + 1); // Redundant borrows in complex expression +} + +public fun complex_expression_valid() { + let resource = S { a: 10 }; + let _a = (copy resource.a) + 1; // Redundant borrows in complex expression +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.exp b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.exp new file mode 100644 index 00000000000..1be49356b88 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.exp @@ -0,0 +1,113 @@ +error[E01003]: invalid modifier + ┌─ tests/linter/move_2024/ref_deref_conditional.move:3:1 + │ +3 │ struct MyResource has copy, drop { + │ ^^^^^^ Invalid struct declaration. Internal struct declarations are not yet supported + │ + = Visibility annotations are required on struct declarations from the Move 2024 edition onwards. + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:10:17 + │ +10 │ let _ref = &*&resource; // Should be flagged + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:16:21 + │ +16 │ let _ref = &mut *&resource; // Should be flagged + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:22:17 + │ +22 │ let _ref = &*&resource.value; // Should be flagged + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E04024]: invalid usage of immutable variable + ┌─ tests/linter/move_2024/ref_deref_conditional.move:30:5 + │ +28 │ let resource = MyResource { value: 10 }; + │ -------- To use the variable mutably, it must be declared 'mut', e.g. 'mut resource' +29 │ let ref1 = &resource; +30 │ resource.value = 20; // Modifying the resource + │ ^^^^^^^^^^^^^^ Invalid mutable borrow of immutable variable 'resource' + +error[E07002]: mutable ownership violated + ┌─ tests/linter/move_2024/ref_deref_conditional.move:30:5 + │ +29 │ let ref1 = &resource; + │ --------- It is still being borrowed by this reference +30 │ resource.value = 20; // Modifying the resource + │ ^^^^^^^^^^^^^^ Invalid mutable borrow at field 'value'. + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:37:17 + │ +37 │ let _ref = &*(&*&resource); // Should be flagged + │ ^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:37:20 + │ +37 │ let _ref = &*(&*&resource); // Should be flagged + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:50:17 + │ +50 │ let _copy = *&resource; // Should be flagged, making a copy + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:59:17 + │ +59 │ let _ref = &*&get_resource(); // Should be flagged + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:64:17 + │ +64 │ let _ref = &*&0; // Should be flagged + │ ^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:72:21 + │ +72 │ let _ref = &*&resource; // Should be flagged regardless + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:83:17 + │ +83 │ let _ref = &*&E; // Should be flagged + │ ^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_conditional.move:88:17 + │ +88 │ let _ref = &*&vector[1,2,3]; // Should be flagged + │ ^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Remove this borrow-deref and use the expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.move new file mode 100644 index 00000000000..652628b3ee3 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional.move @@ -0,0 +1,89 @@ +module 0x42::ConstrainedRefDerefCases; + +struct MyResource has copy, drop { + value: u64, +} + +// Case 1: Should be flagged - simple &*& pattern +public fun should_flag_simple() { + let resource = MyResource { value: 10 }; + let _ref = &*&resource; // Should be flagged +} + +// Case 2: Should be flagged - &mut *& pattern +public fun should_flag_mut() { + let resource = MyResource { value: 10 }; + let _ref = &mut *&resource; // Should be flagged +} + +// Case 3: Should be flagged - &*& pattern with field access +public fun should_flag_field() { + let mut resource = MyResource { value: 10 }; + let _ref = &*&resource.value; // Should be flagged + resource.value = 10; +} + +// Case 3: Should not be flagged - &* pattern without extra & +public fun should_not_flag_modified() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + resource.value = 20; // Modifying the resource + let _ref2 = &*ref1; // No flag -- ref was made elsewhere +} + +// Case 5: Should be flagged - nested &*& pattern +public fun should_flag_nested() { + let resource = MyResource { value: 10 }; + let _ref = &*(&*&resource); // Should be flagged +} + +// Case 6: Should not be flagged - &* pattern without extra & +public fun should_not_flag_deref_only() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + let _ref2 = &*ref1; // Should not be flagged +} + +// Case 7: Should be flagged - *& pattern without leading & +public fun should_flag_copy() { + let resource = MyResource { value: 10 }; + let _copy = *&resource; // Should be flagged, making a copy +} + +// Case 8: Should be flagged for removal - &*& pattern with function call +public fun get_resource(): MyResource { + MyResource { value: 20 } +} + +public fun should_flag_function_call() { + let _ref = &*&get_resource(); // Should be flagged +} + +// Case 9: Should be flagged for removal - &*& pattern with constant value +public fun should_flag_value() { + let _ref = &*&0; // Should be flagged +} + +// Case 10: Should be flagged - &*& pattern but path is mutated in a loop +public fun should_flag_loop_mutation() { + let mut resource = MyResource { value: 10 }; + let mut i = 0; + while (i < 5) { + let _ref = &*&resource; // Should be flagged regardless + resource.value = resource.value + 1; + i = i + 1; + } +} + +const E: u64 = 0; + +// Case 11: Should be flagged -- constant +#[allow(implicit_const_copy)] +public fun should_flag_constant() { + let _ref = &*&E; // Should be flagged +} + +// Case 12: Should be flagged -- vector +public fun should_flag_vector() { + let _ref = &*&vector[1,2,3]; // Should be flagged +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional_valid.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional_valid.move new file mode 100644 index 00000000000..3392b4336cb --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_conditional_valid.move @@ -0,0 +1,85 @@ +module 0x42::ConstrainedRefDerefCases; + +public struct MyResource has copy, drop { + value: u64, +} + +// Case 1 +public fun should_not_flag_simple() { + let resource = MyResource { value: 10 }; + let _ref = & resource; +} + +// Case 2 +public fun should_not_flag_mut() { + let resource = MyResource { value: 10 }; + let _ref = &mut copy resource; +} + +// Case 3 +public fun should_not_flag_field() { + let mut resource = MyResource { value: 10 }; + let _ref = &resource.value; + resource.value = 10; +} + +// Case 4 -- invalid control flow +public fun should_not_flag_modified() { + let mut resource = MyResource { value: 10 }; + let ref1 = © resource; + resource.value = 20; + let _ref2 = &*ref1; // No flag -- ref was made elsewhere +} + +// Case 5 +public fun should_not_flag_nested() { + let resource = MyResource { value: 10 }; + let _ref = © resource; +} + +// Case 6 +public fun should_not_flag_deref_only() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + let _ref2 = &*ref1; // Should not be flagged +} + +// Case 7 +public fun should_not_flag_copy() { + let resource = MyResource { value: 10 }; + let _copy = copy resource; +} + +// Case 8 +public fun get_resource(): MyResource { + MyResource { value: 20 } +} + +// Case 9 +public fun should_not_flag_value() { + let _ref = &0; +} + +// Case 10 +public fun should_not_flag_loop_mutation() { + let mut resource = MyResource { value: 10 }; + let mut i = 0; + while (i < 5) { + let _ref = © resource; // Should be flagged regardless + resource.value = resource.value + 1; + i = i + 1; + } +} + +const E: u64 = 0; + +// Case 11 +#[allow(implicit_const_copy)] +public fun should_flag_constant() { + let _ref = &E; // Should be flagged +} + +// Case 12 +public fun should_not_flag_vector() { + let _ref = &vector[1,2,3]; // Should be flagged +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.exp b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.exp new file mode 100644 index 00000000000..a2eb4c408d1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.exp @@ -0,0 +1,80 @@ +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:26:21 + │ +26 │ let _value: T = *&((&s).value); // Complex field expression + │ ^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:36:17 + │ +36 │ let _ref = &*(&*(&resource)); // Triple nested borrow-dereference, might be missed + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:36:20 + │ +36 │ let _ref = &*(&*(&resource)); // Triple nested borrow-dereference, might be missed + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:44:21 + │ +44 │ let _value: T = *&(copy s.value); // Complex field expression + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:44:24 + │ +44 │ let _value: T = *&(copy s.value); // Complex field expression + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:49:22 + │ +49 │ let _value: T = copy s.value; // Complex field expression -- bad copy + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:53:22 + │ +53 │ let _value: T = copy s.value; // Complex field expression -- bad copy + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:58:17 + │ +58 │ let _ref = &*(&resource.value); // Complex nested borrow on field + │ ^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:65:17 + │ +65 │ let _ref = &*&resource.value; // Direct, redundant borrow-dereference on field + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/move_2024/ref_deref_fields.move:70:17 + │ +70 │ let _ref = &*&(&resource).value; // Nested redundant borrow-dereference on field + │ ^^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.move new file mode 100644 index 00000000000..6381962bb95 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields.move @@ -0,0 +1,71 @@ +module 0x42::complex_ref_deref; + +public struct MyResource has copy, drop { + value: u64, +} + +// Ignored Cases + +public fun case_1() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + let _ref2 = &*ref1; // Might be intentional for creating a new reference +} + +public fun case_2(resource: &mut MyResource) { + let _ref = &mut *resource; // Might be necessary in generic contexts +} + +public fun case_3() { + let resource = MyResource { value: 10 }; + let ref1 = &resource; + let _ref2 = &(*ref1); // Dereference then reference -- c'est la vie +} + +public fun case_5(s: S) { + let _value: T = *&((&s).value); // Complex field expression + // Could be removed in favor of the implicit copy, but path + // processing makes it unclear what to do after typing rewrites + // it. See note in lint analysis. +} + +// Flagged Cases + +public fun case_4() { + let resource = MyResource { value: 10 }; + let _ref = &*(&*(&resource)); // Triple nested borrow-dereference, might be missed +} + +public struct S has drop { + value: T, +} + +public fun case_5_b(s: S) { + let _value: T = *&(copy s.value); // Complex field expression + // Could be removed in favor of the implicit copy +} + +public fun case_5_c(s: &S) { + let _value: T = copy s.value; // Complex field expression -- bad copy +} + +public fun case_5_d(s: &mut S) { + let _value: T = copy s.value; // Complex field expression -- bad copy +} + +public fun case_6() { + let resource = MyResource { value: 10 }; + let _ref = &*(&resource.value); // Complex nested borrow on field +} + +//Field Borrow Cases + +public fun redundant_case() { + let resource = MyResource { value: 10 }; + let _ref = &*&resource.value; // Direct, redundant borrow-dereference on field +} + +public fun nested_case() { + let resource = MyResource { value: 10 }; + let _ref = &*&(&resource).value; // Nested redundant borrow-dereference on field +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields_valid.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields_valid.move new file mode 100644 index 00000000000..fc963e8bd18 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/ref_deref_fields_valid.move @@ -0,0 +1,49 @@ +module 0x42::complex_ref_deref_valid; + +public struct MyResource has copy, drop { + value: u64, +} + +// Flagged Cases + +public fun case_4() { + let resource = MyResource { value: 10 }; + let _ref = & copy resource; +} + +public struct S has drop { + value: T, +} + +public fun case_5(s: S) { + let _value: T = s.value; // Complex field expression +} + +public fun case_5_b(s: S) { + let _value: T = s.value; // Complex field expression +} + +public fun case_5_c(s: &S) { + let _value: T = s.value; // Complex field expression -- bad copy +} + +public fun case_5_d(s: &mut S) { + let _value: T = s.value; // Complex field expression -- bad copy +} + +public fun case_6() { + let resource = MyResource { value: 10 }; + let _ref = &resource.value; // Complex nested borrow on field +} + +//Field Borrow Cases + +public fun redundant_case() { + let resource = MyResource { value: 10 }; + let _ref = &resource.value; // Direct, redundant borrow-dereference on field +} + +public fun nested_case() { + let resource = MyResource { value: 10 }; + let _ref = &(&resource).value; // Nested redundant borrow-dereference on field +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.exp b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.exp new file mode 100644 index 00000000000..db1ca33d284 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.exp @@ -0,0 +1,137 @@ +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:3:17 + │ +3 │ fun t0(): u64 { return 5 } + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:5:17 + │ +5 │ fun t1(): u64 { return t0() } + │ ^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:9:15 + │ +9 │ fun t2(): S { return S { } } + │ ^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:13:15 + │ +13 │ fun t3(): E { return E::V } + │ ^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:15:25 + │ +15 │ fun t4(): vector { return vector[1,2,3] } + │ ^^^^^^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:17:12 + │ +17 │ fun t5() { return () } + │ ^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:19:28 + │ +19 │ fun t6(): u64 { let x = 0; return move x + │ ^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:24:5 + │ +24 │ return copy x + │ ^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:29:17 + │ +29 │ fun t8(): u64 { return VALUE } + │ ^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:33:5 + │ +33 │ return &x + │ ^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E07004]: invalid return of locally borrowed state + ┌─ tests/linter/move_2024/unneeded_return.move:33:5 + │ +33 │ return &x + │ ^^^^^^^^^ + │ │ │ + │ │ It is still being borrowed by this reference + │ Invalid return. Local variable 'x' is still being borrowed. + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:36:18 + │ +36 │ fun t10(): u64 { return 5 + 2 } + │ ^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:38:19 + │ +38 │ fun t11(): bool { return !true } + │ ^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:40:25 + │ +40 │ fun t12(x: &u64): u64 { return *x } + │ ^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:42:25 + │ +42 │ fun t13(x: u64): u128 { return x as u128 } + │ ^^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:44:18 + │ +44 │ fun t14(): u64 { return (0: u64) } + │ ^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return.move:46:18 + │ +46 │ fun t15(): u64 { return loop { break 5 } } + │ ^^^^^^^^^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.move new file mode 100644 index 00000000000..891cd62de16 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return.move @@ -0,0 +1,46 @@ +module 0x42::m; + +fun t0(): u64 { return 5 } + +fun t1(): u64 { return t0() } + +public struct S { } + +fun t2(): S { return S { } } + +public enum E { V } + +fun t3(): E { return E::V } + +fun t4(): vector { return vector[1,2,3] } + +fun t5() { return () } + +fun t6(): u64 { let x = 0; return move x +} + +fun t7(): u64 { + let x = 0; + return copy x +} + +const VALUE: u64 = 0; + +fun t8(): u64 { return VALUE } + +fun t9(): &u64 { + let x = 0; + return &x +} + +fun t10(): u64 { return 5 + 2 } + +fun t11(): bool { return !true } + +fun t12(x: &u64): u64 { return *x } + +fun t13(x: u64): u128 { return x as u128 } + +fun t14(): u64 { return (0: u64) } + +fun t15(): u64 { return loop { break 5 } } diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.exp b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.exp new file mode 100644 index 00000000000..c6b514b6023 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.exp @@ -0,0 +1,113 @@ +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:5:17 + │ +5 │ if (cond) { return 5 } else { abort ZERO } + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:9:17 + │ +9 │ if (cond) { return 5 } else { return 0 } + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:9:35 + │ +9 │ if (cond) { return 5 } else { return 0 } + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:13:5 + │ +13 │ return if (cond) { 5 } else { 0 } + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:17:5 + │ +17 │ return if (cond) { return 5 } else { 0 } + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:21:5 + │ +21 │ return if (cond) { 5 } else { return 0 } + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:30:5 + │ +30 │ â•­ return match (e) { +31 │ │ E::V0 => 0, +32 │ │ E::V1 => 1, +33 │ │ } + │ ╰─────^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:38:18 + │ +38 │ E::V0 => return 0, + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:45:18 + │ +45 │ E::V0 => return 0, + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:46:18 + │ +46 │ E::V1 => return 1, + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:52:18 + │ +52 │ E::V0 => return 0, + │ ^^^^^^^^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:58:5 + │ +58 │ â•­ return match (e) { +59 │ │ E::V0 => 0, +60 │ │ E::V1 => abort ZERO, +61 │ │ } + │ ╰─────^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04004]: unneeded return + ┌─ tests/linter/move_2024/unneeded_return_branch.move:65:5 + │ +65 │ â•­ return match (e) { +66 │ │ E::V0 => if (true) { return 0 } else { 1 }, +67 │ │ E::V1 => 2, +68 │ │ } + │ ╰─────^ Remove unnecessary 'return', the expression is already in a 'return' position + │ + = This warning can be suppressed with '#[allow(lint(unneeded_return))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.move new file mode 100644 index 00000000000..6481436833a --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_branch.move @@ -0,0 +1,69 @@ +module 0x42::m; +const ZERO: u64 = 0; + +fun t0(cond: bool): u64 { + if (cond) { return 5 } else { abort ZERO } +} + +fun t1(cond: bool): u64 { + if (cond) { return 5 } else { return 0 } +} + +fun t2(cond: bool): u64 { + return if (cond) { 5 } else { 0 } +} + +fun t3(cond: bool): u64 { + return if (cond) { return 5 } else { 0 } +} + +fun t4(cond: bool): u64 { + return if (cond) { 5 } else { return 0 } +} + +public enum E has drop { + V0, + V1 +} + +fun t5(e: E): u64{ + return match (e) { + E::V0 => 0, + E::V1 => 1, + } +} + +fun t6(e: E): u64{ + match (e) { + E::V0 => return 0, + E::V1 => 1, + } +} + +fun t7(e: E): u64 { + match (e) { + E::V0 => return 0, + E::V1 => return 1, + } +} + +fun t8(e: E): u64{ + match (e) { + E::V0 => return 0, + E::V1 => abort ZERO, + } +} + +fun t9(e: E): u64 { + return match (e) { + E::V0 => 0, + E::V1 => abort ZERO, + } +} + +fun t10(e: E): u64 { + return match (e) { + E::V0 => if (true) { return 0 } else { 1 }, + E::V1 => 2, + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.exp b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.exp new file mode 100644 index 00000000000..3d707bdbde0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.exp @@ -0,0 +1,54 @@ +warning[W09002]: unused variable + ┌─ tests/linter/move_2024/unneeded_return_okay.move:14:9 + │ +14 │ let y = &mut x; + │ ^ Unused local variable 'y'. Consider removing or prefixing with an underscore: '_y' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E04007]: incompatible types + ┌─ tests/linter/move_2024/unneeded_return_okay.move:15:14 + │ +13 │ let mut x = 0; + │ ----- Given: integer +14 │ let y = &mut x; +15 │ return (*x = 1) + │ ^ + │ │ + │ Invalid mutation. Expected a mutable reference + │ Expected: '&mut _' + +error[E04007]: incompatible types + ┌─ tests/linter/move_2024/unneeded_return_okay.move:19:12 + │ +19 │ fun t3() { 'a: { return { return 'a 0 } } } + │ -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Invalid return expression + │ │ Given: integer + │ Expected: '()' + +error[E04014]: invalid loop control + ┌─ tests/linter/move_2024/unneeded_return_okay.move:23:19 + │ +23 │ fun t4() { return continue } + │ ^^^^^^^^ Invalid usage of 'continue'. 'continue' can only be used inside a loop body or lambda + +error[E04014]: invalid loop control + ┌─ tests/linter/move_2024/unneeded_return_okay.move:25:19 + │ +25 │ fun t5() { return break } + │ ^^^^^ Invalid usage of 'break'. 'break' can only be used inside a loop body or lambda + +error[E04014]: invalid loop control + ┌─ tests/linter/move_2024/unneeded_return_okay.move:27:20 + │ +27 │ fun t6() { return (break + 5) } + │ ^^^^^ Invalid usage of 'break'. 'break' can only be used inside a loop body or lambda + +error[E03005]: unbound unscoped name + ┌─ tests/linter/move_2024/unneeded_return_okay.move:29:19 + │ +29 │ fun t7() { return unnamed_fun() } + │ ^^^^^^^^^^^ Unbound function 'unnamed_fun' in current scope + diff --git a/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.move b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.move new file mode 100644 index 00000000000..17c7477a6c1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/move_2024/unneeded_return_okay.move @@ -0,0 +1,31 @@ +module 0x42::m; + +fun t0() { return abort 0 } + +// invalid type, so no lint +fun t1() { + let mut x = 0; + return (x = 1) +} + +// invalid syntax, so no lint +fun t2() { + let mut x = 0; + let y = &mut x; + return (*x = 1) +} + +// invalid type, so no lint +fun t3() { 'a: { return { return 'a 0 } } } + +// the following are all invalid syntax, so no lint + +fun t4() { return continue } + +fun t5() { return break } + +fun t6() { return (break + 5) } + +fun t7() { return unnamed_fun() } + +fun t8(cond: bool) { return while (cond) { break } } diff --git a/external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.exp b/external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.exp new file mode 100644 index 00000000000..63f19d5427f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.exp @@ -0,0 +1,24 @@ +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/redundant_ref_deref.move:8:21 + │ +8 │ let _ref = &*(&resource); // Redundant borrow-dereference + │ ^^^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/redundant_ref_deref.move:13:25 + │ +13 │ let _ref = &mut *(&mut resource); + │ ^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/redundant_ref_deref.move:18:22 + │ +18 │ let _value = *(&resource.value); + │ ^^^^^^^^^^^^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.move b/external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.move new file mode 100644 index 00000000000..bf0a3a61ab4 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/redundant_ref_deref.move @@ -0,0 +1,20 @@ +module 0x42::TruePositiveCases { + struct MyResource has copy, drop { + value: u64, + } + + public fun case_1() { + let resource = MyResource { value: 10 }; + let _ref = &*(&resource); // Redundant borrow-dereference + } + + public fun case_2() { + let resource = MyResource { value: 10 }; + let _ref = &mut *(&mut resource); + } + + public fun case_3() { + let resource = MyResource { value: 10 }; + let _value = *(&resource.value); + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/ref_deref_negative.move b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_negative.move new file mode 100644 index 00000000000..16394f72fef --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_negative.move @@ -0,0 +1,21 @@ +module 0x42::TrueNegativeCases { + struct MyResource has copy, drop { + value: u64, + } + + public fun case_1() { + let resource = MyResource { value: 10 }; + let _ref = &resource; // Direct borrow, no redundancy + } + + public fun case_2() { + let resource = MyResource { value: 10 }; + let ref = &resource; + let _value = ref.value; // Accessing field through reference, no redundancy + } + + public fun case_3() { + let resource = MyResource { value: 10 }; + let _copy = resource; // Creating a copy, no borrow involved + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.exp b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.exp new file mode 100644 index 00000000000..070a9b2001d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.exp @@ -0,0 +1,16 @@ +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/ref_deref_path.move:5:19 + │ +5 │ let _x = &*&*&s.x.x; + │ ^^^^^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/ref_deref_path.move:5:21 + │ +5 │ let _x = &*&*&s.x.x; + │ ^^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.move b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.move new file mode 100644 index 00000000000..36287fdd195 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_path.move @@ -0,0 +1,7 @@ +module 0x42::m { + struct S has copy, drop { x: T } + + public fun test(s: S>) { + let _x = &*&*&s.x.x; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.exp b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.exp new file mode 100644 index 00000000000..29908b27821 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.exp @@ -0,0 +1,16 @@ +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/ref_deref_triple.move:5:19 + │ +5 │ let _x = &*&*&s; + │ ^^^^^ Redundant borrow-dereference detected. Use the inner expression directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/ref_deref_triple.move:5:21 + │ +5 │ let _x = &*&*&s; + │ ^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.move b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.move new file mode 100644 index 00000000000..bb46ed086e0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/ref_deref_triple.move @@ -0,0 +1,7 @@ +module 0x42::m { + struct S has copy, drop {} + + public fun test(s: S) { + let _x = &*&*&s; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_abort_constant.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_abort_constant.move new file mode 100644 index 00000000000..31257a72a7d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_abort_constant.move @@ -0,0 +1,19 @@ +module 0x42::M { + const ERROR_NOT_OWNER: u64 = 2; + + #[allow(lint(abort_without_constant))] + fun test_lint_abort_incorrect() { + abort 100 + } +} + +#[allow(lint(abort_without_constant))] +module 0x42::M2 { + const ERROR_NOT_OWNER: u64 = 2; + + fun test_lint_abort_incorrect() { + abort 100 + } +} + + diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_combinable_comparisons.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_combinable_comparisons.move new file mode 100644 index 00000000000..48a47ff5e1a --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_combinable_comparisons.move @@ -0,0 +1,17 @@ +#[allow(lint(combinable_comparisons))] +module a::m { + fun t(x: u64, y: u64): bool { + x > y || x == y + } +} + + +module a::n { + #[allow(lint(combinable_comparisons))] + const C: bool = 5 > 3 || 5 == 3; + + #[allow(lint(combinable_comparisons))] + fun t(x: u64, y: u64): bool { + x > y || x == y + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operands.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operands.move new file mode 100644 index 00000000000..8c452aea023 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operands.move @@ -0,0 +1,9 @@ +#[allow(lint(always_equal_operands))] +module a::m { + fun t(x: u64): bool { x == x } +} + +module a::n { + #[allow(lint(always_equal_operands))] + fun t(x: u64): bool { x == x } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_loop_without_exit.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_loop_without_exit.move new file mode 100644 index 00000000000..431c75e4757 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_loop_without_exit.move @@ -0,0 +1,7 @@ +module a::m { + // Suppress Case + #[allow(lint(loop_without_exit))] + public fun suppressed_empty_loop() { + loop {} + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_meaningless_math_operation.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_meaningless_math_operation.move new file mode 100644 index 00000000000..8f2bc2d3a2a --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_meaningless_math_operation.move @@ -0,0 +1,8 @@ +// tests suppression of unnecessary math operations +module 0x42::M { + + #[allow(lint(unnecessary_math))] + public fun add_zero(x: u64): u64 { + x + 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_self_assignment.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_self_assignment.move new file mode 100644 index 00000000000..494d5ca7dac --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_self_assignment.move @@ -0,0 +1,15 @@ +#[allow(lint(self_assignment))] +module a::m { + fun foo(x: u64): u64 { + x = x; + x + } +} + +module a::m2 { + #[allow(lint(self_assignment))] + fun foo(x: u64): u64 { + x = x; + x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_conditional.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_conditional.move new file mode 100644 index 00000000000..c91bbf14bc5 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_conditional.move @@ -0,0 +1,17 @@ +module a::m { + + #[allow(lint(unnecessary_conditional))] + public fun t0(condition: bool) { + if (condition) true else false; + } + + #[allow(lint(unnecessary_conditional))] + public fun t1(condition: bool) { + if (condition) vector[] else vector[]; + } + + #[allow(lint(unnecessary_conditional))] + public fun t2(condition: bool) { + if (condition) @0 else @0; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_unit.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_unit.move new file mode 100644 index 00000000000..da9533c8d58 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_unit.move @@ -0,0 +1,12 @@ +// suppress unnecessary_unit lint +module a::m { + + #[allow(lint(unnecessary_unit))] + public fun test_empty_else(x: bool): bool { + if (x) { x = true; } else {}; + if (!x) () else { test_empty_else(x); }; + { (); }; + (); + x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_while_loop.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_while_loop.move index 1477d966a74..ed9337b4915 100644 --- a/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_while_loop.move +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_unnecessary_while_loop.move @@ -1,7 +1,7 @@ -module 0x42::loop_test { +module a::loop_test { #[allow(lint(while_true))] public fun suppressed_while_true() { - while (true) {}; + while(true) {} } } diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppressed_case_redundant_ref_deref.move b/external-crates/move/crates/move-compiler/tests/linter/suppressed_case_redundant_ref_deref.move new file mode 100644 index 00000000000..8ec1a8e5f1d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppressed_case_redundant_ref_deref.move @@ -0,0 +1,17 @@ +module 0x42::SuppressCases { + struct MyResource has copy, drop { + value: u64, + } + + #[allow(lint(redundant_ref_deref))] + public fun case_1() { + let resource = MyResource { value: 10 }; + let _ref = &*(&resource); // Suppressed warning + } + + #[allow(lint(redundant_ref_deref))] + public fun case_2() { + let resource = MyResource { value: 10 }; + let _value = *(&resource.value); // Suppressed warning + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_abort_constant.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_abort_constant.move new file mode 100644 index 00000000000..dd20e9f34d6 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_abort_constant.move @@ -0,0 +1,17 @@ +module 0x42::M { + const ERR_INVALID_ARGUMENT: u64 = 1; + const ERROR_NOT_OWNER: u64 = 2; + const COMPLEX_ERROR: u64 = 3 + 4; + + fun test_lint_abort_correct() { + abort ERR_INVALID_ARGUMENT // Correct: using a named constant + } + + fun test_lint_assert_correct() { + assert!(false, ERROR_NOT_OWNER); // Correct: using a named constant + } + + fun test_lint_abort_complex_constant() { + abort COMPLEX_ERROR // Correct: using a more complex constant expression + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_loop_without_exit.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_loop_without_exit.move new file mode 100644 index 00000000000..965ae9f9b7d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_loop_without_exit.move @@ -0,0 +1,19 @@ +// tests for negatives in the loop without exit lint + +module a::m { + public fun t1() { + let i = 0; + loop { + if (i >= 10) break; + i = i + 1; + } + } + + public fun t2() { + let i = 0; + loop { + if (i >= 10) return; + i = i + 1; + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_meaningless_math_operation.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_meaningless_math_operation.move new file mode 100644 index 00000000000..8c75f707639 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_meaningless_math_operation.move @@ -0,0 +1,17 @@ +module 0x42::M { + public fun multiply_by_two(x: u64): u64 { + x * 2 // Should not trigger the linter + } + + public fun left_shift_by_one(x: u64): u64 { + x << 1 // Should not trigger the linter + } + + public fun add_one(x: u64): u64 { + x + 1 // Should not trigger the linter + } + + public fun divide_by_two(x: u64): u64 { + x / 2 // Should not trigger the linter + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_self_assignment.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_self_assignment.move new file mode 100644 index 00000000000..da67aefdcae --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_self_assignment.move @@ -0,0 +1,63 @@ +// tests for cases that self-assignment should not warn + +module a::m { + const C: u64 = 112; + + fun t() { + let x1 = 5; + x1; + x1 = 5; // we don't track values + x1; + + let c1 = C; + c1; + c1 = C; // we don't track values + c1; + + let x2 = 5; + x2; + let x2 = x2; // shadowing is not self-assignment + x2; + + let (x3, x4) = (5, 5); + x3; + x4; + (x4, x3) = (x3, x4); // swap is not self-assignment + x3; + x4; + + let r1 = &mut 0; + let r2 = &mut 0; + *r1; + *r2; + *r1 = *r2; // different references + *r1; + + let r = &mut 0; + *id(r) = *id(r); + + let x5 = 0; + x5; + x5 = { let x5 = 0; x5 }; // different x's + x5; + } + + + struct S has copy, drop { f1: u64, f2: u64 } + struct P has copy, drop { s1: S, s2: S } + fun fields(m1: &mut S, m2: &mut S, s1: S, s2: S) { + s1.f1 = s1.f2; // different fields + m1.f1 = m1.f2; // different fields + s1.f1 = s2.f1; // different locals + m1.f1 = m2.f1; // different references + } + + fun nested_fields(p1: &mut P, p2: &mut P) { + p1.s1.f1 = p1.s1.f2; // different fields + p1.s1.f1 = p2.s1.f1; // different references + } + + fun id(x: &mut T): &mut T { + x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_conditional.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_conditional.move new file mode 100644 index 00000000000..fc94f500664 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_conditional.move @@ -0,0 +1,17 @@ +// true negative cases for redundant conditional +module a::m { + public fun t0(condition: bool) { + if (condition) 1 else { 0 }; + if (condition) vector[] else vector[1]; + } + + public fun t1(x: u64, y: u64) { + let _ = if (x > y) { x } else y; + } + + // has side effects, too complex to analyze + public fun t2(condition: &mut bool) { + let _ = if (*condition) { *condition = false; true } else { *condition = true; false }; + } + +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_unit.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_unit.move new file mode 100644 index 00000000000..dac10008319 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_unit.move @@ -0,0 +1,12 @@ +// tests unnecessary units. These caeses are not errors and should not be reported +module a::unnecessary_unit { + public fun t_if_without_else(cond: bool): u64 { + let x = 0; + if (cond) x = 1; + x + } + + public fun t() { + () // unit here is okay + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.exp new file mode 100644 index 00000000000..ea630d5687e --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.exp @@ -0,0 +1,126 @@ +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:6:15 + │ +6 │ abort 100 // Should trigger: using a numeric literal + │ ^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:10:15 + │ +10 │ abort 1 + 2 // Should trigger + │ ^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:15:15 + │ +15 │ abort 0 // Should trigger + │ ^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:19:15 + │ +19 │ abort 0x1F // Should trigger + │ ^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:23:15 + │ +23 │ abort 1 + ERROR_NOT_OWNER // Should trigger + │ ^^^^^^^^^^^^^^^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:27:15 + │ +27 │ abort ERROR_NOT_OWNER + ERROR_NOT_OWNER // Should trigger + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:32:15 + │ +32 │ abort x + │ ^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:36:15 + │ +36 │ abort error_code // trigger, since it's a dynamic value, not a constant + │ ^^^^^^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:40:24 + │ +40 │ assert!(false, 2); // Should trigger: using a numeric literal + │ ^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:44:24 + │ +44 │ assert!(false, 1 + 1); // Should trigger + │ ^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:48:24 + │ +48 │ assert!(false, 0xC0FFEE); // Should trigger + │ ^^^^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:52:24 + │ +52 │ assert!(false, 1 + ERROR_NOT_OWNER); // Should trigger + │ ^^^^^^^^^^^^^^^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:56:24 + │ +56 │ assert!(false, ERROR_NOT_OWNER + ERROR_NOT_OWNER) // Should trigger + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04005]: 'abort' or 'assert' without named constant + ┌─ tests/linter/true_positive_abort_constant.move:61:24 + │ +61 │ assert!(false, x); // Should trigger + │ ^ Prefer using a named constant. + │ + = Consider using an error constant with the '#[error]' to allow for a more descriptive error. + = This warning can be suppressed with '#[allow(lint(abort_without_constant))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.move new file mode 100644 index 00000000000..0198d4dc0f4 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_abort_constant.move @@ -0,0 +1,72 @@ +module 0x42::M { + const ERROR_NOT_OWNER: u64 = 2; + + // True Positives: These should trigger the lint + fun test_lint_abort_incorrect() { + abort 100 // Should trigger: using a numeric literal + } + + fun test_lint_abort_complex_expression() { + abort 1 + 2 // Should trigger + } + + // Additional edge cases + fun test_lint_abort_zero() { + abort 0 // Should trigger + } + + fun test_lint_abort_hex_literal() { + abort 0x1F // Should trigger + } + + fun test_lint_abort_addition_with_constant() { + abort 1 + ERROR_NOT_OWNER // Should trigger + } + + fun test_lint_abort_addition_all_constants() { + abort ERROR_NOT_OWNER + ERROR_NOT_OWNER // Should trigger + } + + fun test_lint_abort_named_value() { + let x = 10; + abort x + } + + fun test_lint_abort_dynamic_value(error_code: u64) { + abort error_code // trigger, since it's a dynamic value, not a constant + } + + fun test_lint_assert_literal() { + assert!(false, 2); // Should trigger: using a numeric literal + } + + fun test_lint_assert_addition() { + assert!(false, 1 + 1); // Should trigger + } + + fun test_lint_assert_hex_literal() { + assert!(false, 0xC0FFEE); // Should trigger + } + + fun test_lint_assert_addition_with_constant() { + assert!(false, 1 + ERROR_NOT_OWNER); // Should trigger + } + + fun test_lint_assert_addition_all_constants() { + assert!(false, ERROR_NOT_OWNER + ERROR_NOT_OWNER) // Should trigger + } + + fun test_lint_assert_named_value() { + let x = 10; + assert!(false, x); // Should trigger + } + + fun test_lint_assert_function_call() { + assert!(true, get_error_code()); // trigger, since it's a function call + } + + // Helper function for testing + fun get_error_code(): u64 { + ERROR_NOT_OWNER + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.exp new file mode 100644 index 00000000000..45d20929184 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.exp @@ -0,0 +1,1136 @@ +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:4:9 + │ +4 │ x == y && x != y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:5:9 + │ +5 │ x == y && x > y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:6:9 + │ +6 │ x == y && x < y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:7:9 + │ +7 │ x == y && x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:8:9 + │ +8 │ x == y && x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:9:9 + │ +9 │ x != y && x > y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:10:9 + │ +10 │ x != y && x < y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:11:9 + │ +11 │ x != y && x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:12:9 + │ +12 │ x != y && x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:13:9 + │ +13 │ x > y && x < y; + │ ^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:14:9 + │ +14 │ x > y && x >= y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:15:9 + │ +15 │ x > y && x <= y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:16:9 + │ +16 │ x < y && x >= y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:17:9 + │ +17 │ x < y && x <= y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:18:9 + │ +18 │ x >= y && x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:19:9 + │ +19 │ x == y || x != y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:20:9 + │ +20 │ x == y || x > y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:21:9 + │ +21 │ x == y || x < y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:22:9 + │ +22 │ x == y || x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:23:9 + │ +23 │ x == y || x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:24:9 + │ +24 │ x != y || x > y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:25:9 + │ +25 │ x != y || x < y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:26:9 + │ +26 │ x != y || x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:27:9 + │ +27 │ x != y || x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:28:9 + │ +28 │ x > y || x < y; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:29:9 + │ +29 │ x > y || x >= y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:30:9 + │ +30 │ x > y || x <= y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:31:9 + │ +31 │ x < y || x >= y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:32:9 + │ +32 │ x < y || x <= y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:33:9 + │ +33 │ x >= y || x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:34:9 + │ +34 │ x != y && x == y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:35:9 + │ +35 │ x > y && x == y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:36:9 + │ +36 │ x < y && x == y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:37:9 + │ +37 │ x >= y && x == y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:38:9 + │ +38 │ x <= y && x == y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:39:9 + │ +39 │ x > y && x != y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:40:9 + │ +40 │ x < y && x != y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:41:9 + │ +41 │ x >= y && x != y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:42:9 + │ +42 │ x <= y && x != y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:43:9 + │ +43 │ x < y && x > y; + │ ^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:44:9 + │ +44 │ x >= y && x > y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:45:9 + │ +45 │ x <= y && x > y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:46:9 + │ +46 │ x >= y && x < y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:47:9 + │ +47 │ x <= y && x < y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:48:9 + │ +48 │ x <= y && x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:49:9 + │ +49 │ x != y || x == y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:50:9 + │ +50 │ x > y || x == y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:51:9 + │ +51 │ x < y || x == y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:52:9 + │ +52 │ x >= y || x == y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:53:9 + │ +53 │ x <= y || x == y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:54:9 + │ +54 │ x > y || x != y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:55:9 + │ +55 │ x < y || x != y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:56:9 + │ +56 │ x >= y || x != y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:57:9 + │ +57 │ x <= y || x != y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:58:9 + │ +58 │ x < y || x > y; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:59:9 + │ +59 │ x >= y || x > y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:60:9 + │ +60 │ x <= y || x > y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:61:9 + │ +61 │ x >= y || x < y; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:62:9 + │ +62 │ x <= y || x < y; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:63:9 + │ +63 │ x <= y || x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:67:9 + │ +67 │ x == y && y != x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:68:9 + │ +68 │ x == y && y > x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:69:9 + │ +69 │ x == y && y < x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:70:9 + │ +70 │ x == y && y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:71:9 + │ +71 │ x == y && y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:72:9 + │ +72 │ x != y && y > x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:73:9 + │ +73 │ x != y && y < x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:74:9 + │ +74 │ x != y && y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:75:9 + │ +75 │ x != y && y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:76:9 + │ +76 │ x > y && y > x; + │ ^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:77:9 + │ +77 │ x > y && y >= x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:78:9 + │ +78 │ x > y && y <= x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:79:9 + │ +79 │ x < y && y >= x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:80:9 + │ +80 │ x < y && y <= x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:81:9 + │ +81 │ x >= y && y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:82:9 + │ +82 │ x == y || y != x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:83:9 + │ +83 │ x == y || y > x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:84:9 + │ +84 │ x == y || y < x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:85:9 + │ +85 │ x == y || y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:86:9 + │ +86 │ x == y || y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:87:9 + │ +87 │ x != y || y > x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:88:9 + │ +88 │ x != y || y < x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:89:9 + │ +89 │ x != y || y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:90:9 + │ +90 │ x != y || y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:91:9 + │ +91 │ x > y || y > x; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:92:9 + │ +92 │ x > y || y >= x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:93:9 + │ +93 │ x > y || y <= x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:94:9 + │ +94 │ x < y || y >= x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:95:9 + │ +95 │ x < y || y <= x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:96:9 + │ +96 │ x >= y || y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:97:9 + │ +97 │ x != y && y == x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:98:9 + │ +98 │ x > y && y == x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:99:9 + │ +99 │ x < y && y == x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:100:9 + │ +100 │ x >= y && y == x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:101:9 + │ +101 │ x <= y && y == x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:102:9 + │ +102 │ x > y && y != x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:103:9 + │ +103 │ x < y && y != x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:104:9 + │ +104 │ x >= y && y != x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:105:9 + │ +105 │ x <= y && y != x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:106:9 + │ +106 │ x < y && y < x; + │ ^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:107:9 + │ +107 │ x >= y && y > x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:108:9 + │ +108 │ x <= y && y > x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:109:9 + │ +109 │ x >= y && y < x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:110:9 + │ +110 │ x <= y && y < x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'false' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:111:9 + │ +111 │ x <= y && y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:112:9 + │ +112 │ x != y || y == x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:113:9 + │ +113 │ x > y || y == x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:114:9 + │ +114 │ x < y || y == x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:115:9 + │ +115 │ x >= y || y == x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:116:9 + │ +116 │ x <= y || y == x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:117:9 + │ +117 │ x > y || y != x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:118:9 + │ +118 │ x < y || y != x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:119:9 + │ +119 │ x >= y || y != x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:120:9 + │ +120 │ x <= y || y != x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:121:9 + │ +121 │ x < y || y < x; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:122:9 + │ +122 │ x >= y || y > x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:123:9 + │ +123 │ x <= y || y > x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:124:9 + │ +124 │ x >= y || y < x; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:125:9 + │ +125 │ x <= y || y < x; + │ ^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:126:9 + │ +126 │ x <= y || y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison is always 'true' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:130:9 + │ +130 │ x == y && x == y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:131:9 + │ +131 │ x != y && x != y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:132:9 + │ +132 │ x > y && x > y; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:133:9 + │ +133 │ x < y && x < y; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:134:9 + │ +134 │ x >= y && x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:135:9 + │ +135 │ x <= y && x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:136:9 + │ +136 │ x == y || x == y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:137:9 + │ +137 │ x != y || x != y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:138:9 + │ +138 │ x > y || x > y; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:139:9 + │ +139 │ x < y || x < y; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:140:9 + │ +140 │ x >= y || x >= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:141:9 + │ +141 │ x <= y || x <= y; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:142:9 + │ +142 │ x == y && y == x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '==' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:143:9 + │ +143 │ x != y && y != x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '!=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:144:9 + │ +144 │ x > y && y < x; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:145:9 + │ +145 │ x < y && y > x; + │ ^^^^^^^^^^^^^^ This comparison simplifies to the operation '<' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:146:9 + │ +146 │ x >= y && y <= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:147:9 + │ +147 │ x <= y && y >= x; + │ ^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:150:26 + │ +150 │ const Values: bool = 5 > 3 || 5 == 3; + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:153:9 + │ +153 │ 5 != 3 && 5 > 3 + │ ^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:158:9 + │ +158 │ {&x} == &y || (x as u64) > (*&y:u64); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '>=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01012]: comparison operations condition can be simplified + ┌─ tests/linter/true_positive_combinable_comparisons.move:159:9 + │ +159 │ © x == &y || x < move y; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ This comparison simplifies to the operation '<=' + │ + = This warning can be suppressed with '#[allow(lint(combinable_comparisons))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.move new file mode 100644 index 00000000000..4f209cb5864 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_combinable_comparisons.move @@ -0,0 +1,161 @@ +// tests lints against combinable comparisons that can be simplified to a single comparison. +module a::m { + fun t(x: u64, y: u64) { + x == y && x != y; + x == y && x > y; + x == y && x < y; + x == y && x >= y; + x == y && x <= y; + x != y && x > y; + x != y && x < y; + x != y && x >= y; + x != y && x <= y; + x > y && x < y; + x > y && x >= y; + x > y && x <= y; + x < y && x >= y; + x < y && x <= y; + x >= y && x <= y; + x == y || x != y; + x == y || x > y; + x == y || x < y; + x == y || x >= y; + x == y || x <= y; + x != y || x > y; + x != y || x < y; + x != y || x >= y; + x != y || x <= y; + x > y || x < y; + x > y || x >= y; + x > y || x <= y; + x < y || x >= y; + x < y || x <= y; + x >= y || x <= y; + x != y && x == y; + x > y && x == y; + x < y && x == y; + x >= y && x == y; + x <= y && x == y; + x > y && x != y; + x < y && x != y; + x >= y && x != y; + x <= y && x != y; + x < y && x > y; + x >= y && x > y; + x <= y && x > y; + x >= y && x < y; + x <= y && x < y; + x <= y && x >= y; + x != y || x == y; + x > y || x == y; + x < y || x == y; + x >= y || x == y; + x <= y || x == y; + x > y || x != y; + x < y || x != y; + x >= y || x != y; + x <= y || x != y; + x < y || x > y; + x >= y || x > y; + x <= y || x > y; + x >= y || x < y; + x <= y || x < y; + x <= y || x >= y; + } + + fun flipped(x: u64, y: u64) { + x == y && y != x; + x == y && y > x; + x == y && y < x; + x == y && y >= x; + x == y && y <= x; + x != y && y > x; + x != y && y < x; + x != y && y >= x; + x != y && y <= x; + x > y && y > x; + x > y && y >= x; + x > y && y <= x; + x < y && y >= x; + x < y && y <= x; + x >= y && y >= x; + x == y || y != x; + x == y || y > x; + x == y || y < x; + x == y || y >= x; + x == y || y <= x; + x != y || y > x; + x != y || y < x; + x != y || y >= x; + x != y || y <= x; + x > y || y > x; + x > y || y >= x; + x > y || y <= x; + x < y || y >= x; + x < y || y <= x; + x >= y || y >= x; + x != y && y == x; + x > y && y == x; + x < y && y == x; + x >= y && y == x; + x <= y && y == x; + x > y && y != x; + x < y && y != x; + x >= y && y != x; + x <= y && y != x; + x < y && y < x; + x >= y && y > x; + x <= y && y > x; + x >= y && y < x; + x <= y && y < x; + x <= y && y <= x; + x != y || y == x; + x > y || y == x; + x < y || y == x; + x >= y || y == x; + x <= y || y == x; + x > y || y != x; + x < y || y != x; + x >= y || y != x; + x <= y || y != x; + x < y || y < x; + x >= y || y > x; + x <= y || y > x; + x >= y || y < x; + x <= y || y < x; + x <= y || y <= x; + } + + fun same_op(x: u64, y: u64) { + x == y && x == y; + x != y && x != y; + x > y && x > y; + x < y && x < y; + x >= y && x >= y; + x <= y && x <= y; + x == y || x == y; + x != y || x != y; + x > y || x > y; + x < y || x < y; + x >= y || x >= y; + x <= y || x <= y; + x == y && y == x; + x != y && y != x; + x > y && y < x; + x < y && y > x; + x >= y && y <= x; + x <= y && y >= x; + } + + const Values: bool = 5 > 3 || 5 == 3; + + fun values(): bool { + 5 != 3 && 5 > 3 + } + + #[allow(lint(redundant_ref_deref))] + fun mismatched(x: u64, y: u64) { + {&x} == &y || (x as u64) > (*&y:u64); + © x == &y || x < move y; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.exp new file mode 100644 index 00000000000..0041277dae8 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.exp @@ -0,0 +1,144 @@ +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:6:9 + │ +6 │ x % copy x; + │ ^^^^^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to '0' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:7:9 + │ +7 │ copy x ^ x; + │ ^^^^^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to '0' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:8:9 + │ +8 │ x / x; + │ ^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to '1' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:10:9 + │ +10 │ x | x; + │ ^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to the same value + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:11:9 + │ +11 │ x & x; + │ ^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to the same value + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:13:9 + │ +13 │ x != x; + │ ^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'false' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:14:9 + │ +14 │ x < x; + │ ^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'false' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:15:9 + │ +15 │ x > x; + │ ^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'false' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:17:9 + │ +17 │ x == x; + │ ^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'true' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:18:9 + │ +18 │ x <= x; + │ ^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'true' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:19:9 + │ +19 │ copy x >= move x; + │ ^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'true' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: redundant, always-equal operands for binary operation + ┌─ tests/linter/true_positive_equal_operands.move:22:9 + │ +22 │ x == x; + │ ^^^^^^ + │ │ │ + │ │ Will always evaluate to the same value as this expression + │ Always equal operands detected in binary operation, which will evaluate to 'true' + │ This expression + │ + = This warning can be suppressed with '#[allow(lint(always_equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.move new file mode 100644 index 00000000000..8c01376acda --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operands.move @@ -0,0 +1,24 @@ +// warn on operands that are always equal and the binary operation results in a constant value +// this excludes expressions that are folded by the compiler + +module a::m { + fun test_equal_operand(x: u64) { + x % copy x; + copy x ^ x; + x / x; + + x | x; + x & x; + + x != x; + x < x; + x > x; + + x == x; + x <= x; + copy x >= move x; + } + fun all_types(x: T) { + x == x; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.exp new file mode 100644 index 00000000000..ed14df04816 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.exp @@ -0,0 +1,27 @@ +warning[Lint W02006]: 'loop' without 'break' or 'return' + ┌─ tests/linter/true_positive_loop_without_exit.move:5:9 + │ +5 │ loop {} + │ ^^^^^^^ 'loop' without 'break' or 'return'. This code will until it errors, e.g. reaching an 'abort' or running out of gas + │ + = This warning can be suppressed with '#[allow(lint(loop_without_exit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02006]: 'loop' without 'break' or 'return' + ┌─ tests/linter/true_positive_loop_without_exit.move:10:9 + │ +10 │ loop { abort ZERO } + │ ^^^^^^^^^^^^^^^^^^^ 'loop' without 'break' or 'return'. This code will until it errors, e.g. reaching an 'abort' or running out of gas + │ + = This warning can be suppressed with '#[allow(lint(loop_without_exit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02006]: 'loop' without 'break' or 'return' + ┌─ tests/linter/true_positive_loop_without_exit.move:14:9 + │ +14 │ â•­ loop { +15 │ │ t2(); +16 │ │ t2(); +17 │ │ } + │ ╰─────────^ 'loop' without 'break' or 'return'. This code will until it errors, e.g. reaching an 'abort' or running out of gas + │ + = This warning can be suppressed with '#[allow(lint(loop_without_exit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.move new file mode 100644 index 00000000000..48876fe8c57 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_loop_without_exit.move @@ -0,0 +1,19 @@ +// tests for positives in the loop without exit lint + +module a::m { + public fun t1() { + loop {} + } + + const ZERO: u64 = 0; + public fun t2() { + loop { abort ZERO } + } + + public fun t3() { + loop { + t2(); + t2(); + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp new file mode 100644 index 00000000000..2f96dcd1e65 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp @@ -0,0 +1,340 @@ +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:3:9 + │ +3 │ x * 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:4:9 + │ +4 │ 1 * x; + │ ^^^^^ + │ │ + │ This operation has no effect and can be removed + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:5:9 + │ +5 │ x / 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:6:9 + │ +6 │ x + 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:7:9 + │ +7 │ 0 + x; + │ ^^^^^ + │ │ + │ This operation has no effect and can be removed + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:8:9 + │ +8 │ x - 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:9:9 + │ +9 │ x << 0; + │ ^^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:10:9 + │ +10 │ x << 0; + │ ^^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:14:9 + │ +14 │ x * 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:15:9 + │ +15 │ 0 * x; + │ ^^^^^ + │ │ + │ This operation is always zero and can be replaced with '0' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:16:9 + │ +16 │ 0 / x; + │ ^^^^^ + │ │ + │ This operation is always zero and can be replaced with '0' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:17:9 + │ +17 │ 0 % x; + │ ^^^^^ + │ │ + │ This operation is always zero and can be replaced with '0' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:18:9 + │ +18 │ x % 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:22:9 + │ +22 │ 1 % x; + │ ^^^^^ + │ │ + │ This operation is always one and can be replaced with '1' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:27:9 + │ +26 │ let y = 1; + │ - Because of this operand +27 │ x * y; + │ ^^^^^ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:28:9 + │ +28 │ x - (1 - 1); + │ ^^^^^^^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:32:9 + │ +32 │ x * 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:33:9 + │ +33 │ x * 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:34:9 + │ +34 │ 1 % x; + │ ^^^^^ + │ │ + │ This operation is always one and can be replaced with '1' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:38:9 + │ +38 │ x * 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:39:9 + │ +39 │ x * 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:40:9 + │ +40 │ 1 % x; + │ ^^^^^ + │ │ + │ This operation is always one and can be replaced with '1' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:44:9 + │ +44 │ x * 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:45:9 + │ +45 │ x * 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:46:9 + │ +46 │ 1 % x; + │ ^^^^^ + │ │ + │ This operation is always one and can be replaced with '1' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:50:9 + │ +50 │ x * 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:51:9 + │ +51 │ x * 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:52:9 + │ +52 │ 1 % x; + │ ^^^^^ + │ │ + │ This operation is always one and can be replaced with '1' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:56:9 + │ +56 │ x * 1; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:57:9 + │ +57 │ x * 0; + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation is always zero and can be replaced with '0' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/true_positive_meaningless_math_operation.move:58:9 + │ +58 │ 1 % x; + │ ^^^^^ + │ │ + │ This operation is always one and can be replaced with '1' + │ Because of this operand + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.move new file mode 100644 index 00000000000..157cf274e08 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.move @@ -0,0 +1,60 @@ +module 0x42::M { + public fun unchanged(x: u64) { + x * 1; + 1 * x; + x / 1; + x + 0; + 0 + x; + x - 0; + x << 0; + x << 0; + } + + public fun always_zero(x: u64) { + x * 0; + 0 * x; + 0 / x; + 0 % x; + x % 1; + } + + public fun always_one(x: u64) { + 1 % x; + } + + public fun ast_fold(x: u64) { + let y = 1; + x * y; + x - (1 - 1); + } + + public fun t_u8(x: u8) { + x * 1; + x * 0; + 1 % x; + } + + public fun t_u16(x: u16) { + x * 1; + x * 0; + 1 % x; + } + + public fun t_u32(x: u32) { + x * 1; + x * 0; + 1 % x; + } + + public fun t_u128(x: u128) { + x * 1; + x * 0; + 1 % x; + } + + public fun t_u256(x: u256) { + x * 1; + x * 0; + 1 % x; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.exp new file mode 100644 index 00000000000..5b9cc76f34d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.exp @@ -0,0 +1,318 @@ +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:5:9 + │ +5 │ p = p; // warn + │ ^ - Is the same as this location + │ │ + │ Unnecessary self-assignment. The assignment is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:10:9 + │ +10 │ x = x; // warn + │ ^ - Is the same as this location + │ │ + │ Unnecessary self-assignment. The assignment is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:13:9 + │ +13 │ x = move x; // warn + │ ^ ------ Is the same as this location + │ │ + │ Unnecessary self-assignment. The assignment is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:15:9 + │ +15 │ x = copy x; // warn + │ ^ ------ Is the same as this location + │ │ + │ Unnecessary self-assignment. The assignment is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:18:10 + │ +18 │ (p, other, x) = (p, 0, x); // warn x2 + │ ^ - Is the same as this location + │ │ + │ Unnecessary self-assignment. The assignment is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:18:20 + │ +18 │ (p, other, x) = (p, 0, x); // warn x2 + │ ^ - Is the same as this location + │ │ + │ Unnecessary self-assignment. The assignment is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:27:9 + │ +27 │ *&mut m.f1 = m.f1; + │ ^^^^^^^^^^^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:28:9 + │ +28 │ m.f1 = *&mut m.f1; + │ ^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Is the same as this location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:28:17 + │ +28 │ m.f1 = *&mut m.f1; + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:29:9 + │ +29 │ m.f1 = *&m.f1; + │ ^^^^^^^^^^^^^^ + │ │ │ + │ │ Is the same as this location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:29:17 + │ +29 │ m.f1 = *&m.f1; + │ ^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:30:9 + │ +30 │ *&mut m.f1 = *&m.f1; + │ ^^^^^^^^^^^^^^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:30:23 + │ +30 │ *&mut m.f1 = *&m.f1; + │ ^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:31:9 + │ +31 │ *&mut m.f1 = *&mut m.f1; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:31:23 + │ +31 │ *&mut m.f1 = *&mut m.f1; + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:33:9 + │ +33 │ *&mut s.f1 = s.f1; + │ ^^^^^^^^^^^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:34:9 + │ +34 │ s.f1 = *&mut s.f1; + │ ^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Is the same as this location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:34:17 + │ +34 │ s.f1 = *&mut s.f1; + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:35:9 + │ +35 │ s.f1 = *&s.f1; + │ ^^^^^^^^^^^^^^ + │ │ │ + │ │ Is the same as this location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:35:17 + │ +35 │ s.f1 = *&s.f1; + │ ^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:36:9 + │ +36 │ *&mut s.f1 = *&s.f1; + │ ^^^^^^^^^^^^^^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:36:23 + │ +36 │ *&mut s.f1 = *&s.f1; + │ ^^^^^^ Redundant borrow-dereference detected. Use the field access directly. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:37:9 + │ +37 │ *&mut s.f1 = *&mut s.f1; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:37:23 + │ +37 │ *&mut s.f1 = *&mut s.f1; + │ ^^^^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:43:9 + │ +43 │ p.s1.f1 = p.s1.f1; + │ ^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Is the same as this location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ This location + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:47:9 + │ +47 │ *r = *r; + │ ^^^^^^^ + │ ││ │ + │ ││ Is the same as this location + │ │This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:49:9 + │ +49 │ *copy r = *r; + │ ^^^^^^^^^^^^ + │ │ │ │ + │ │ │ Is the same as this location + │ │ This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:50:9 + │ +50 │ *move r = *copy r; + │ ^^^^^^^^^^^^^^^^^ + │ │ │ │ + │ │ │ Is the same as this location + │ │ This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02008]: assignment preserves the same value + ┌─ tests/linter/true_positive_self_assignment.move:53:9 + │ +53 │ *&mut x = *&mut x; + │ ^^^^^^^^^^^^^^^^^ + │ │ │ │ + │ │ │ Is the same as this location + │ │ This location + │ Unnecessary self-mutation. The mutation is redundant and will not change the value + │ + = This warning can be suppressed with '#[allow(lint(self_assignment))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01009]: redundant reference/dereference + ┌─ tests/linter/true_positive_self_assignment.move:53:19 + │ +53 │ *&mut x = *&mut x; + │ ^^^^^^^ Redundant borrow-dereference detected. Replace this borrow-deref with 'copy'. + │ + = This warning can be suppressed with '#[allow(lint(redundant_ref_deref))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.move new file mode 100644 index 00000000000..efddd0a5da1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_self_assignment.move @@ -0,0 +1,55 @@ +// tests for cases that self-assignment should warn + +module a::m { + fun variables(p: u64) { + p = p; // warn + p; + + let x = 0; + x; + x = x; // warn + x; + + x = move x; // warn + x; + x = copy x; // warn + + let other; + (p, other, x) = (p, 0, x); // warn x2 + p; + x; + other; + } + + struct S has copy, drop { f1: u64, f2: u64 } + + fun fields(m: &mut S, s: S) { + *&mut m.f1 = m.f1; + m.f1 = *&mut m.f1; + m.f1 = *&m.f1; + *&mut m.f1 = *&m.f1; + *&mut m.f1 = *&mut m.f1; + + *&mut s.f1 = s.f1; + s.f1 = *&mut s.f1; + s.f1 = *&s.f1; + *&mut s.f1 = *&s.f1; + *&mut s.f1 = *&mut s.f1; + } + + struct P has copy, drop { s1: S, s2: S } + + fun nested_fields(p: &mut P) { + p.s1.f1 = p.s1.f1; + } + + fun references(r: &mut u64) { + *r = *r; + *r; + *copy r = *r; + *move r = *copy r; + + let x = 0; + *&mut x = *&mut x; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.exp new file mode 100644 index 00000000000..747a6aa889c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.exp @@ -0,0 +1,52 @@ +warning[Lint W01007]: 'if' expression can be removed + ┌─ tests/linter/true_positive_unnecessary_conitional.move:4:9 + │ +4 │ if (!condition) true else false; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Detected an unnecessary conditional expression 'if (cond)'. Consider using the condition directly, i.e. 'cond' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_conditional))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01007]: 'if' expression can be removed + ┌─ tests/linter/true_positive_unnecessary_conitional.move:5:9 + │ +5 │ if (condition) { { false } } else { (true: bool) }; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Detected an unnecessary conditional expression 'if (cond)'. Consider using the condition directly, i.e. '!cond' + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_conditional))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01007]: 'if' expression can be removed + ┌─ tests/linter/true_positive_unnecessary_conitional.move:9:9 + │ +9 │ if (true) true else true; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ │ + │ │ │ is the same as this value + │ │ This value + │ Detected a redundant conditional expression 'if (..) v else v', where each branch results in the same value 'v'. Consider using the value directly + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_conditional))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01007]: 'if' expression can be removed + ┌─ tests/linter/true_positive_unnecessary_conitional.move:10:9 + │ +10 │ if (foo()) 0 else 0; + │ ^^^^^^^^^^^^^^^^^^^ + │ │ │ │ + │ │ │ is the same as this value + │ │ This value + │ Detected a redundant conditional expression 'if (..) v else v', where each branch results in the same value 'v'. Consider using the value directly + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_conditional))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01007]: 'if' expression can be removed + ┌─ tests/linter/true_positive_unnecessary_conitional.move:11:9 + │ +11 │ if (!foo()) b"" else x""; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ │ + │ │ │ is the same as this value + │ │ This value + │ Detected a redundant conditional expression 'if (..) v else v', where each branch results in the same value 'v'. Consider using the value directly + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_conditional))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.move new file mode 100644 index 00000000000..407718b2f05 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_conitional.move @@ -0,0 +1,15 @@ +// tests cases where a lint is reported for a redundant conditional expression +module a::m { + public fun t0(condition: bool) { + if (!condition) true else false; + if (condition) { { false } } else { (true: bool) }; + } + + public fun t1() { + if (true) true else true; + if (foo()) 0 else 0; + if (!foo()) b"" else x""; + } + + fun foo(): bool { true } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.exp new file mode 100644 index 00000000000..3b81304356f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.exp @@ -0,0 +1,151 @@ +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:6:16 + │ +6 │ if (b) () else { x = 1 }; + │ - ^^ Unnecessary unit '()' + │ │ + │ Consider negating the 'if' condition and simplifying + │ + = For example 'if (cond) () else e' can be simplified to 'if (!cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:8:16 + │ +8 │ if (b) {} else { x = 1 }; + │ - ^^ Unnecessary unit '()' + │ │ + │ Consider negating the 'if' condition and simplifying + │ + = For example 'if (cond) () else e' can be simplified to 'if (!cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:10:16 + │ +10 │ if (b) { () } else { x = 1 }; + │ - ^^^^^^ Unnecessary unit '()' + │ │ + │ Consider negating the 'if' condition and simplifying + │ + = For example 'if (cond) () else e' can be simplified to 'if (!cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:12:16 + │ +12 │ if (b) { + │ - Consider negating the 'if' condition and simplifying + │ ╭────────────────^ +13 │ │ // new line and comment does not suppress it +14 │ │ } else { x = 1 }; + │ ╰─────────^ Unnecessary unit '()' + │ + = For example 'if (cond) () else e' can be simplified to 'if (!cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:21:31 + │ +21 │ if (b) { x = 1 } else (); + │ ----------------------^^ + │ │ │ + │ │ Unnecessary 'else ()'. + │ An 'if' without an 'else' has an implicit 'else ()'. Consider removing the 'else' branch + │ + = For example 'if (cond) e else ()' can be simplified to 'if (cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:23:31 + │ +23 │ if (b) { x = 1 } else {}; + │ ----------------------^^ + │ │ │ + │ │ Unnecessary 'else ()'. + │ An 'if' without an 'else' has an implicit 'else ()'. Consider removing the 'else' branch + │ + = For example 'if (cond) e else ()' can be simplified to 'if (cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:25:31 + │ +25 │ if (b) { x = 1 } else { () }; + │ ----------------------^^^^^^ + │ │ │ + │ │ Unnecessary 'else ()'. + │ An 'if' without an 'else' has an implicit 'else ()'. Consider removing the 'else' branch + │ + = For example 'if (cond) e else ()' can be simplified to 'if (cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:27:31 + │ +27 │ â•­ if (b) { x = 1 } else { + │ ╭─────────────────────────────────^ +28 │ │ │ // new line and comment does not suppress it +29 │ │ │ }; + │ ╰─│─────────^ Unnecessary 'else ()'. + │ ╰─────────' An 'if' without an 'else' has an implicit 'else ()'. Consider removing the 'else' branch + │ + = For example 'if (cond) e else ()' can be simplified to 'if (cond) e' + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:34:9 + │ +34 │ (); + │ ^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:37:18 + │ +37 │ if (b) { (); () } else { x = 1 }; // doesn't trigger if/else case + │ ^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:39:33 + │ +39 │ if (b) { x = 1 } else { (); (); () }; // doesn't trigger if/else case + │ ^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:39:37 + │ +39 │ if (b) { x = 1 } else { (); (); () }; // doesn't trigger if/else case + │ ^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:41:9 + │ +41 │ {}; + │ ^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:42:9 + │ +42 │ { () }; // inner isn't an error but the outer is + │ ^^^^^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W04010]: unit `()` expression can be removed or simplified + ┌─ tests/linter/true_positive_unnecessary_unit.move:43:11 + │ +43 │ { (); }; // inner is an error but outer isn't + │ ^^ Unnecessary unit in sequence '();'. Consider removing + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_unit))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.move new file mode 100644 index 00000000000..3cd380ffbd1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_unit.move @@ -0,0 +1,52 @@ +// tests unnecessary units in if, else, and block +module a::unnecessary_unit { + public fun t_if(b: bool) { + let x = 0; + x; + if (b) () else { x = 1 }; + x; + if (b) {} else { x = 1 }; + x; + if (b) { () } else { x = 1 }; + x; + if (b) { + // new line and comment does not suppress it + } else { x = 1 }; + x; + } + + public fun t_else(b: bool) { + let x = 0; + x; + if (b) { x = 1 } else (); + x; + if (b) { x = 1 } else {}; + x; + if (b) { x = 1 } else { () }; + x; + if (b) { x = 1 } else { + // new line and comment does not suppress it + }; + x; + } + + public fun t_block(b: bool) { + (); + let x = 0; + x; + if (b) { (); () } else { x = 1 }; // doesn't trigger if/else case + x; + if (b) { x = 1 } else { (); (); () }; // doesn't trigger if/else case + x; + {}; + { () }; // inner isn't an error but the outer is + { (); }; // inner is an error but outer isn't + () + } + + // public fun t_if_else_if(b: bool, c: bool) { + // let x = 0; + // x; + // if (b) { x = 1 } else if (c) {}; + // } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_while_loop.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_while_loop.exp index 2ba9789c925..d1ccfb59730 100644 --- a/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_while_loop.exp +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_unnecessary_while_loop.exp @@ -1,4 +1,4 @@ -warning[Lint W01004]: unnecessary 'while (true)', replace with 'loop' +warning[Lint W04002]: unnecessary 'while (true)', replace with 'loop' ┌─ tests/linter/true_positive_unnecessary_while_loop.move:3:9 │ 3 │ while (true) {}; @@ -7,7 +7,7 @@ warning[Lint W01004]: unnecessary 'while (true)', replace with 'loop' = A 'loop' is more useful in these cases. Unlike 'while', 'loop' can have a 'break' with a value, e.g. 'let x = loop { break 42 };' = This warning can be suppressed with '#[allow(lint(while_true))]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[Lint W01004]: unnecessary 'while (true)', replace with 'loop' +warning[Lint W04002]: unnecessary 'while (true)', replace with 'loop' ┌─ tests/linter/true_positive_unnecessary_while_loop.move:4:9 │ 4 │ while (true) { break } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_conditional.move b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_conditional.move new file mode 100644 index 00000000000..29bd6a53f11 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_conditional.move @@ -0,0 +1,9 @@ +module 0x42::m; + +fun test(cond: bool): u64 { + 'a: { + loop { + if (cond) { return 'a 5 } + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_0.move b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_0.move new file mode 100644 index 00000000000..93877d2dc9f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_0.move @@ -0,0 +1,9 @@ +module 0x42::m; + +fun test(): u64 { + 'a: { + loop { + return 'a 5 + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_1.move b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_1.move new file mode 100644 index 00000000000..90888d9f0d4 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/cfg_panic_1.move @@ -0,0 +1,7 @@ +module 0x42::m; + +fun test(): u64 { + 'a: { + return 'a 5 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/expand_test.move b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/expand_test.move new file mode 100644 index 00000000000..8743d82de93 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/expand_test.move @@ -0,0 +1,19 @@ +module a::m { + + public macro fun for_each<$T>($v: vector<$T>, $f: |$T|) { + let mut v = $v; + v.reverse(); + let mut i = 0; + while (!v.is_empty()) { + $f(v.pop_back()); + i = i + 1; + }; + v.destroy_empty(); + } + + public fun sum(v: vector): u64 { + let mut sum = 0; + for_each!(v, |x| { sum = sum + x; }); + sum + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/named_loop_no_value.move b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/named_loop_no_value.move new file mode 100644 index 00000000000..730939fb73f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/cfgir/named_loop_no_value.move @@ -0,0 +1,7 @@ +module 0x42::m; + +fun test(): u64 { + 'a: { + return 5 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/expansion/type_hole_as_type_param.exp b/external-crates/move/crates/move-compiler/tests/move_2024/expansion/type_hole_as_type_param.exp index 803ff99dde1..01c80599303 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/expansion/type_hole_as_type_param.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/expansion/type_hole_as_type_param.exp @@ -1,9 +1,3 @@ -error[E03011]: invalid use of reserved name - ┌─ tests/move_2024/expansion/type_hole_as_type_param.move:2:21 - │ -2 │ public struct S<_>() - │ ^ Invalid type parameter name '_'. '_' is restricted and cannot be used to name a type parameter - warning[W09006]: unused struct type parameter ┌─ tests/move_2024/expansion/type_hole_as_type_param.move:2:21 │ @@ -12,6 +6,12 @@ warning[W09006]: unused struct type parameter │ = This warning can be suppressed with '#[allow(unused_type_parameter)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E03011]: invalid use of reserved name + ┌─ tests/move_2024/expansion/type_hole_as_type_param.move:2:21 + │ +2 │ public struct S<_>() + │ ^ Invalid type parameter name '_'. '_' is restricted and cannot be used to name a type parameter + error[E03011]: invalid use of reserved name ┌─ tests/move_2024/expansion/type_hole_as_type_param.move:3:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand.move b/external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand.move new file mode 100644 index 00000000000..3c14385d8e8 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand.move @@ -0,0 +1,24 @@ +// emit a warning during code generation for equal operands in binary operations that result +// in a constant value +module a::m; + +fun test_equal_operands_comparison() { + 1 == 1; + {1} == 1; + 1 == {1}; + {1} == {1}; + {{{1}}} == {{{{1}}}}; +} + +fun test_equal_operands_values() { + false == false; + 0u8 == 0u8; + 1u16 == 1u16; + 2u32 == 2u32; + 3u64 == 3u64; + 4u128 == 4u128; + 5u256 == 5u256; + @a == @a; + vector>[] == vector[]; + vector[1] == vector[1]; +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand_false_negative.move b/external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand_false_negative.move new file mode 100644 index 00000000000..69ed9bac99e --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/folding/equal_operand_false_negative.move @@ -0,0 +1,26 @@ +// emit a warning during code generation for equal operands in binary operations that result +// in a constant value +// these could produce warnings if the compiler handled these cases a bit better, in particular +// future optimizations could help. +// NOTE: Please move these out of this test once they start producing warnings + +module a::m; + +fun simple(x: u64, b: bool) { + &1 == 1; + (*&1) == 1; + *&x == copy x; + b && b; + b || b; +} + +fun optimizations() { + let x; + loop { + x = 1; + break + }; + let y = if (true) 1 else 1; + x == y; + x == 1; // using x a second time produces a warning +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.exp new file mode 100644 index 00000000000..11213a0f76c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.exp @@ -0,0 +1,8 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/abort_pair.move:4:6 + │ +4 │ (abort 0, abort 0) + │ ^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.move new file mode 100644 index 00000000000..f416443e6b3 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/abort_pair.move @@ -0,0 +1,5 @@ +module 0x42::m; + +public fun test(): (u64, u64) { + (abort 0, abort 0) +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.exp new file mode 100644 index 00000000000..1248676bfbc --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.exp @@ -0,0 +1,10 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/break_outer_loop.move:14:13 + │ +14 │ break 'a 5; + │ ^^^^^^^^^^ Any code after this expression will not be reached +15 │ break 10; + │ -------- Unreachable code. This statement (and any following statements) will not be executed. + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.move new file mode 100644 index 00000000000..16cc0725115 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/break_outer_loop.move @@ -0,0 +1,19 @@ +module 0x42::m; + +fun test0(): u64 { + 'a: loop { + loop { + break 'a 5 + } + } +} + +fun test1(): u64 { + 'a: loop { + let x = loop { + break 'a 5; + break 10; + }; + let _x = x; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_guard.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_guard.exp index 8c389f2236c..dbb8b6824c5 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_guard.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_guard.exp @@ -1,8 +1,10 @@ warning[W09005]: dead or unreachable code - ┌─ tests/move_2024/hlir/dead_code_guard.move:14:30 + ┌─ tests/move_2024/hlir/dead_code_guard.move:14:20 │ 14 │ _ if ({return 0; true}) => 1, - │ ^^^^ Unreachable code. This statement (and any following statements) will not be executed. + │ ^^^^^^^^ ---- Unreachable code. This statement (and any following statements) will not be executed. + │ │ + │ Any code after this expression will not be reached │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.exp new file mode 100644 index 00000000000..d36d22e904c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.exp @@ -0,0 +1,29 @@ +warning[W09002]: unused variable + ┌─ tests/move_2024/hlir/dead_code_nested_block.move:3:11 + │ +3 │ fun test0(cond: bool): u64 { + │ ^^^^ Unused parameter 'cond'. Consider removing or prefixing with an underscore: '_cond' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/dead_code_nested_block.move:5:9 + │ +5 │ return 'a 5; + │ ^^^^^^^^^^^ Any code after this expression will not be reached +6 │ 0 + │ - Unreachable code. This statement (and any following statements) will not be executed. + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/dead_code_nested_block.move:13:13 + │ +13 │ return 'a 5 + │ ^^^^^^^^^^^ Any code after this expression will not be reached +14 │ }; +15 │ 0 + │ - Unreachable code. This statement (and any following statements) will not be executed. + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.move new file mode 100644 index 00000000000..e5c6ca8706b --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/dead_code_nested_block.move @@ -0,0 +1,17 @@ +module 0x42::m; + +fun test0(cond: bool): u64 { + 'a: { + return 'a 5; + 0 + } +} + +fun test1(): u64 { + 'a: { + loop { + return 'a 5 + }; + 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/determine_error.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/determine_error.move new file mode 100644 index 00000000000..3837f8d4c83 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/determine_error.move @@ -0,0 +1,5 @@ +module 0x42::m; + +public fun report_from_value(code: u64) { + if (code < 10) abort 0 else abort 1 +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.exp new file mode 100644 index 00000000000..76ca9448a74 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.exp @@ -0,0 +1,8 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/if_abort_statement.move:4:18 + │ +4 │ let x: u64 = if (true) abort 0 else abort 0; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.move new file mode 100644 index 00000000000..7201d553d36 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/if_abort_statement.move @@ -0,0 +1,6 @@ +module 0x42::m; + +fun test(): u64 { + let x: u64 = if (true) abort 0 else abort 0; + x +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.exp new file mode 100644 index 00000000000..5e7c69c6c07 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.exp @@ -0,0 +1,8 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.move:11:13 + │ +11 │ 1 + 'a: loop { foo() } + 2; + │ ^^^^^^^^^^^^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.move new file mode 100644 index 00000000000..1793dfe2269 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/labeled_control_exp_associativity_unreachable_code.move @@ -0,0 +1,30 @@ +// tests that control structures are right associative when not immediately followed by a block + +// these cases type check, but have dead code + +module 0x42::M { + fun foo() {} + fun bar(): u64 { 0 } + + fun t(): u64 { 'r: { + // loop + 1 + 'a: loop { foo() } + 2; + 1 + 'a: loop foo(); + 1 + loop 'a: { foo() } + 2; + 'a: loop { foo() } + 1; + + // return + return 'r 1 + 2; + return 'r { 1 + 2 }; + return 'r { 1 } && false; + false && return 'r { 1 }; + + // abort + abort 1 + 2; + abort 'a: { 1 + 2 }; + abort 'a: { 1 } && false; + false && abort 'a: { 1 }; + + 0 + } } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort.move new file mode 100644 index 00000000000..13eecec8415 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort.move @@ -0,0 +1,9 @@ +module 0x42::m; + +fun test() { + if (true) { + if (true) abort 0 else abort 0 + } else { + if (true) abort 0 else abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.exp new file mode 100644 index 00000000000..bfba37c67fe --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.exp @@ -0,0 +1,16 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/nested_if_abort_statement.move:5:9 + │ +5 │ if (true) abort 0 else abort 0 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/nested_if_abort_statement.move:7:9 + │ +7 │ if (true) abort 0 else abort 0 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.move new file mode 100644 index 00000000000..112fe2d7381 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_if_abort_statement.move @@ -0,0 +1,10 @@ +module 0x42::m; + +fun test(): u64 { + let x: u64 = if (true) { + if (true) abort 0 else abort 0 + } else { + if (true) abort 0 else abort 0 + }; + x +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_named_block_inner_break.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_named_block_inner_break.move new file mode 100644 index 00000000000..9a4932e5ed0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/nested_named_block_inner_break.move @@ -0,0 +1,9 @@ +module 0x42::m; + +fun test() { + 'l: loop { + 'l: loop { + break 'l + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/no_dead_code_block.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/no_dead_code_block.move new file mode 100644 index 00000000000..b2063e90c71 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/no_dead_code_block.move @@ -0,0 +1,25 @@ +module 0x42::m; + +fun test0(cond: bool): u64 { + 'a: { + if (cond) { return 'a 5 }; + 0 + } +} + +fun test1(cond: bool): u64 { + 'a: { + loop { + if (cond) { return 'a 5 }; + }; + 0 + } +} + +fun test2(cond: bool): u64 { + 'a: loop { + loop { + if (cond) { break 'a 5 }; + } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.exp b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.exp new file mode 100644 index 00000000000..8c8cf5d6c3a --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.exp @@ -0,0 +1,10 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_2024/hlir/return_value.move:4:5 + │ +4 │ return 5; + │ ^^^^^^^^ Any code after this expression will not be reached +5 │ 10 + │ -- Unreachable code. This statement (and any following statements) will not be executed. + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.move new file mode 100644 index 00000000000..7ddbbd22470 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/return_value.move @@ -0,0 +1,15 @@ +module 0x42::m; + +fun t0(): u64 { + return 5; + 10 +} + +fun t1(): u64 { + while (false) { + return 5 + }; + 10 +} + + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/hlir/true_false_nested_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/true_false_nested_abort.move new file mode 100644 index 00000000000..8449e4e069a --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/hlir/true_false_nested_abort.move @@ -0,0 +1,17 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun test(value: bool): u64 { + match (value) { + true => match (value) { true => abort 0, false => abort 0 }, + false => match (value) { true => abort 0, false => 1 }, + } + } + + public fun run() { + assert!(test(false) == 1) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.exp new file mode 100644 index 00000000000..63272320a94 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.exp @@ -0,0 +1,6 @@ +error[E03009]: unbound variable + ┌─ tests/move_2024/ide_mode/chain_lower_case_incomplete.move:5:9 + │ +5 │ b + │ ^ Unbound variable 'b' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide new file mode 100644 index 00000000000..e69de29bb2d diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide.exp new file mode 100644 index 00000000000..b88150e3383 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.ide.exp @@ -0,0 +1,34 @@ +note[I15006]: IDE path autocomplete + ┌─ tests/move_2024/ide_mode/chain_lower_case_incomplete.move:1:1 + │ +1 │ â•­ module 0x42::m1 { +2 │ │ public fun bar() {} +3 │ │ +4 │ │ public fun foo() { +5 │ │ b +6 │ │ } +7 │ │ } + │ ╰─^ Possible in-scope names + │ + = members: 'Option -> std::option::Option', 'bar -> 0x42::m1::bar', or 'foo -> 0x42::m1::foo' + = modules: 'Self -> 0x42::m1', 'option -> std::option', or 'vector -> std::vector' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: + +note[I15006]: IDE path autocomplete + ┌─ tests/move_2024/ide_mode/chain_lower_case_incomplete.move:5:9 + │ +5 │ b + │ ^ Possible in-scope names + │ + = members: 'Option -> std::option::Option', 'bar -> 0x42::m1::bar', or 'foo -> 0x42::m1::foo' + = modules: 'Self -> 0x42::m1', 'option -> std::option', or 'vector -> std::vector' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: + +error[E03009]: unbound variable + ┌─ tests/move_2024/ide_mode/chain_lower_case_incomplete.move:5:9 + │ +5 │ b + │ ^ Unbound variable 'b' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.move b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.move new file mode 100644 index 00000000000..71300a91754 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_lower_case_incomplete.move @@ -0,0 +1,7 @@ +module 0x42::m1 { + public fun bar() {} + + public fun foo() { + b + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.exp new file mode 100644 index 00000000000..53264bfaf9d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.exp @@ -0,0 +1,6 @@ +error[E03006]: unexpected name in this position + ┌─ tests/move_2024/ide_mode/chain_upper_case_incomplete.move:5:9 + │ +5 │ B + │ ^ Expected a type, function, or constant in this position, not an address + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide new file mode 100644 index 00000000000..e69de29bb2d diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide.exp new file mode 100644 index 00000000000..bf32a0a24dd --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.ide.exp @@ -0,0 +1,34 @@ +note[I15006]: IDE path autocomplete + ┌─ tests/move_2024/ide_mode/chain_upper_case_incomplete.move:1:1 + │ +1 │ â•­ module 0x42::m1 { +2 │ │ public fun bar() {} +3 │ │ +4 │ │ public fun foo() { +5 │ │ B +6 │ │ } +7 │ │ } + │ ╰─^ Possible in-scope names + │ + = members: 'Option -> std::option::Option', 'bar -> 0x42::m1::bar', or 'foo -> 0x42::m1::foo' + = modules: 'Self -> 0x42::m1', 'option -> std::option', or 'vector -> std::vector' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: + +note[I15006]: IDE path autocomplete + ┌─ tests/move_2024/ide_mode/chain_upper_case_incomplete.move:5:9 + │ +5 │ B + │ ^ Possible in-scope names + │ + = members: 'Option -> std::option::Option', 'bar -> 0x42::m1::bar', or 'foo -> 0x42::m1::foo' + = modules: 'Self -> 0x42::m1', 'option -> std::option', or 'vector -> std::vector' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: + +error[E03006]: unexpected name in this position + ┌─ tests/move_2024/ide_mode/chain_upper_case_incomplete.move:5:9 + │ +5 │ B + │ ^ Expected a type, function, or constant in this position, not an address + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.move b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.move new file mode 100644 index 00000000000..2e62bfe6e00 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/chain_upper_case_incomplete.move @@ -0,0 +1,7 @@ +module 0x42::m1 { + public fun bar() {} + + public fun foo() { + B + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.exp index 36785ef26fc..193381dcc54 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.exp @@ -31,3 +31,21 @@ error[E01002]: unexpected token │ Unexpected 'let' │ Expected an identifier or a decimal number +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:18:9 + │ +18 │ let _tmp5 = _s. // incomplete without `;` (unexpected `}`) + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected an identifier or a decimal number + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:19:5 + │ +19 │ } + │ ^ + │ │ + │ Unexpected '}' + │ Expected an identifier or a decimal number + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.ide.exp index 56ddd626b81..7c0c6657769 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/dot_incomplete.ide.exp @@ -13,6 +13,12 @@ error[E01002]: unexpected token │ Unexpected ';' │ Expected an identifier or a decimal number +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:15:23 + │ +15 │ let _tmp2 = _s.a.; // incomplete with `;` (next line should parse) + │ ^ Possible dot names: 'a' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/dot_incomplete.move:15:24 │ @@ -34,6 +40,12 @@ error[E01002]: unexpected token │ Unexpected ';' │ Expected an identifier or a decimal number +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:16:23 + │ +16 │ let _tmp3 = _s.a. // incomplete without `;` (unexpected `let`) + │ ^ Possible dot names: 'a' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/dot_incomplete.move:16:24 │ @@ -55,3 +67,33 @@ error[E01002]: unexpected token │ Unexpected 'let' │ Expected an identifier or a decimal number +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:17:23 + │ +17 │ let _tmp4 = _s. + │ ^ Possible dot names: 'a' + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:18:9 + │ +18 │ let _tmp5 = _s. // incomplete without `;` (unexpected `}`) + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected an identifier or a decimal number + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:18:23 + │ +18 │ let _tmp5 = _s. // incomplete without `;` (unexpected `}`) + │ ^ Possible dot names: 'a' + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/dot_incomplete.move:19:5 + │ +19 │ } + │ ^ + │ │ + │ Unexpected '}' + │ Expected an identifier or a decimal number + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_and_field_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_and_field_autocomplete.ide.exp index 6f487bfc650..e7a86a0d5db 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_and_field_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_and_field_autocomplete.ide.exp @@ -6,54 +6,108 @@ warning[W09009]: unused struct field │ = This warning can be suppressed with '#[allow(unused_field)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:16:20 + │ +16 │ let _ = &in.0.0; + │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:16:21 │ 16 │ let _ = &in.0.0; │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:16:22 + │ +16 │ let _ = &in.0.0; + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:16:23 │ 16 │ let _ = &in.0.0; │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:20:20 + │ +20 │ let _ = &in.0.0.0 ; + │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:20:21 │ 20 │ let _ = &in.0.0.0 ; │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:20:22 + │ +20 │ let _ = &in.0.0.0 ; + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:20:23 │ 20 │ let _ = &in.0.0.0 ; │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:20:24 + │ +20 │ let _ = &in.0.0.0 ; + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:20:25 │ 20 │ let _ = &in.0.0.0 ; │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:20 + │ +24 │ let _ = &in.0.0.0.d ; + │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:21 │ 24 │ let _ = &in.0.0.0.d ; │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:22 + │ +24 │ let _ = &in.0.0.0.d ; + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:23 │ 24 │ let _ = &in.0.0.0.d ; │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:24 + │ +24 │ let _ = &in.0.0.0.d ; + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:25 │ 24 │ let _ = &in.0.0.0.d ; │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:26 + │ +24 │ let _ = &in.0.0.0.d ; + │ ^ Possible dot names: 'a::m::for_c_0', 'a::m::for_c_1', 'c', or 'd' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_and_field_autocomplete.move:24:27 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_autocomplete.ide.exp index b8ffa865893..7e4a864e94f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/method_autocomplete.ide.exp @@ -14,42 +14,84 @@ warning[W09009]: unused struct field │ = This warning can be suppressed with '#[allow(unused_field)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:16:11 + │ +16 │ in.for_b_0() + │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:16:12 │ 16 │ in.for_b_0() │ ^^^^^^^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:20:11 + │ +20 │ in.0.for_a_0(); + │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:20:12 │ 20 │ in.0.for_a_0(); │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:20:13 + │ +20 │ in.0.for_a_0(); + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:20:14 │ 20 │ in.0.for_a_0(); │ ^^^^^^^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:11 + │ +24 │ in.0.0.0.for_c_0(); + │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:12 │ 24 │ in.0.0.0.for_c_0(); │ ^ Possible dot names: 'a::m::for_b_0', 'a::m::for_b_1', 'a::m::test0', 'a::m::test1', 'a::m::test2', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:13 + │ +24 │ in.0.0.0.for_c_0(); + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:14 │ 24 │ in.0.0.0.for_c_0(); │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:15 + │ +24 │ in.0.0.0.for_c_0(); + │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:16 │ 24 │ in.0.0.0.for_c_0(); │ ^ Possible dot names: 'a::m::for_a_0', 'a::m::for_a_1', or '0' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:17 + │ +24 │ in.0.0.0.for_c_0(); + │ ^ Possible dot names: 'a::m::for_c_0', 'a::m::for_c_1', 'c', or 'd' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/method_autocomplete.move:24:18 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_autocomplete.ide.exp index 32142840025..53e71a6b31f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_autocomplete.ide.exp @@ -13,6 +13,12 @@ error[E01002]: unexpected token │ Unexpected ';' │ Expected an identifier or a decimal number +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/named_struct_autocomplete.move:15:23 + │ +15 │ let _tmp2 = _s.a.; + │ ^ Possible dot names: 'a' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/named_struct_autocomplete.move:15:24 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_middle_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_middle_autocomplete.ide.exp index 9efccbe1276..04484c1f181 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_middle_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/named_struct_middle_autocomplete.ide.exp @@ -4,6 +4,12 @@ error[E03010]: unbound field 14 │ let _tmp2 = _s.b.x; │ ^^^^ Unbound field 'b' in 'a::m::B' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/named_struct_middle_autocomplete.move:14:23 + │ +14 │ let _tmp2 = _s.b.x; + │ ^ Possible dot names: 'a' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/named_struct_middle_autocomplete.move:14:24 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.exp new file mode 100644 index 00000000000..d7a3330d712 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.exp @@ -0,0 +1,15 @@ +warning[W10007]: issue with attribute value + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:1:9 + │ +1 │ #[allow(ide_path_autocomplete)] + │ ^^^^^^^^^^^^^^^^^^^^^ Unknown warning filter 'ide_path_autocomplete' + +error[E04023]: invalid method call + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:9 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^^^^^^^^^ + │ │ │ + │ │ No local 'use fun' alias was found for 'a::m::A.b', and no function 'b' was found in the defining module 'a::m' + │ Invalid method call. No known method 'b' on type 'a::m::A' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide new file mode 100644 index 00000000000..e69de29bb2d diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide.exp new file mode 100644 index 00000000000..928a987e3a9 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.ide.exp @@ -0,0 +1,105 @@ +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:21:10 + │ +21 │ c.b.a; // two dots that should trigger auto-completion + │ ^ Possible dot names: 'b' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:21:11 + │ +21 │ c.b.a; // two dots that should trigger auto-completion + │ ^ Possible dot names: 'b' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:21:12 + │ +21 │ c.b.a; // two dots that should trigger auto-completion + │ ^ Possible dot names: 'a' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:21:13 + │ +21 │ c.b.a; // two dots that should trigger auto-completion + │ ^ Possible dot names: 'a' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:22:10 + │ +22 │ c.b.a.bar(); // resolved method name + │ ^ Possible dot names: 'b' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:22:11 + │ +22 │ c.b.a.bar(); // resolved method name + │ ^ Possible dot names: 'b' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:22:12 + │ +22 │ c.b.a.bar(); // resolved method name + │ ^ Possible dot names: 'a' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:22:13 + │ +22 │ c.b.a.bar(); // resolved method name + │ ^ Possible dot names: 'a' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:22:14 + │ +22 │ c.b.a.bar(); // resolved method name + │ ^ Possible dot names: 'a::m::bar' or 'x' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:22:15 + │ +22 │ c.b.a.bar(); // resolved method name + │ ^^^ Possible dot names: 'a::m::bar' or 'x' + +error[E04023]: invalid method call + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:9 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^^^^^^^^^ + │ │ │ + │ │ No local 'use fun' alias was found for 'a::m::A.b', and no function 'b' was found in the defining module 'a::m' + │ Invalid method call. No known method 'b' on type 'a::m::A' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:10 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^ Possible dot names: 'b' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:11 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^ Possible dot names: 'b' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:12 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^ Possible dot names: 'a' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:13 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^ Possible dot names: 'a' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:14 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^ Possible dot names: 'a::m::bar' or 'x' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/on_dot_autocomplete.move:23:15 + │ +23 │ c.b.a.b(); // unresolved method name + │ ^ Possible dot names: 'a::m::bar' or 'x' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.move b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.move new file mode 100644 index 00000000000..f6c41714cf0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/on_dot_autocomplete.move @@ -0,0 +1,25 @@ +#[allow(ide_path_autocomplete)] +module a::m { + + public struct A has copy, drop { + x: u64 + } + + public struct B has copy, drop { + a: A + } + + public struct C has copy, drop { + b: B + } + + public fun bar(_a: A) {} + + public fun foo() { + let b = B { a: A { x: 0 } }; + let c = C { b: b }; + c.b.a; // two dots that should trigger auto-completion + c.b.a.bar(); // resolved method name + c.b.a.b(); // unresolved method name + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/positional_struct_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/positional_struct_autocomplete.ide.exp index 9a0b8f3f406..0c449a5f66c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/positional_struct_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/positional_struct_autocomplete.ide.exp @@ -13,6 +13,12 @@ error[E01002]: unexpected token │ Unexpected ';' │ Expected an identifier or a decimal number +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/positional_struct_autocomplete.move:11:23 + │ +11 │ let _tmp2 = _s.0.; + │ ^ Possible dot names: '0' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/positional_struct_autocomplete.move:11:24 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.exp new file mode 100644 index 00000000000..232578fc7da --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.exp @@ -0,0 +1,75 @@ +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:7:9 + │ +7 │ let _tmp1 = 42; + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected a variable or struct name + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:13:9 + │ +13 │ let _tmp1 = 42; + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected ';' + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:19:9 + │ +19 │ let _tmp1 = 42; + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected an expression term + +error[E03009]: unbound variable + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:24:9 + │ +24 │ f // parses correctly but without semicolon + │ ^ Unbound variable 'f' + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:25:9 + │ +25 │ let _tmp1 = 42; + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected ';' + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:31:9 + │ +31 │ let _tmp1 = 42; + │ ^^^ + │ │ + │ Unexpected 'let' + │ Expected an expression term + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:41:9 + │ +41 │ foo(param) // returned value should still be correct if foo invocation parses correctly + │ ^^^ + │ │ + │ Unexpected 'foo' + │ Expected ';' + +error[E03010]: unbound field + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:52:9 + │ +52 │ param.bar // parses correctly + │ ^^^^^^^^^ Unbound field 'bar' in 'a::m::SomeStruct' + +error[E01002]: unexpected token + ┌─ tests/move_2024/ide_mode/seq_item_after_incomplete.move:53:9 + │ +53 │ param.bar() // returned value should still be correct if foo invocation parses correctly + │ ^^^^^ + │ │ + │ Unexpected 'param' + │ Expected ';' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.move b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.move new file mode 100644 index 00000000000..3bb091bc351 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/seq_item_after_incomplete.move @@ -0,0 +1,56 @@ +// tests if a sequence item is valid despite +// parsing error preceding it in various scenarios +module a::m { + + public fun test1(param: u64): u64 { + let // does not parse correctly + let _tmp1 = 42; + _tmp1 + param + } + + public fun test2(param: u64): u64 { + let _v // parses correctly but without semicolon + let _tmp1 = 42; + _tmp1 + param + } + + public fun test3(param: u64): u64 { + let _v = // does not parse correctly + let _tmp1 = 42; + _tmp1 + param + } + + public fun test4(param: u64): u64 { + f // parses correctly but without semicolon + let _tmp1 = 42; + _tmp1 + param + } + + public fun test5(mut param: u64): u64 { + param = // does not parse correctly + let _tmp1 = 42; + _tmp1 + param + } + + public fun foo(num: u64):u64 { + num + } + + public fun test6(param: u64): u64 { + let _v // parses correctly but without semicolon + foo(param) // returned value should still be correct if foo invocation parses correctly + } + + + public struct SomeStruct has drop, copy {} + + public fun bar(param: SomeStruct): SomeStruct { + param + } + + public fun test7(param: SomeStruct): SomeStruct { + param.bar // parses correctly + param.bar() // returned value should still be correct if foo invocation parses correctly + } + +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/struct_method_invalid_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/struct_method_invalid_autocomplete.ide.exp index ad1bed3a378..4e1ddff4ae4 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/struct_method_invalid_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/struct_method_invalid_autocomplete.ide.exp @@ -7,6 +7,12 @@ error[E04023]: invalid method call │ │ No local 'use fun' alias was found for 'a::m::A.t7', and no function 't7' was found in the defining module 'a::m' │ Invalid method call. No known method 't7' on type 'a::m::A' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/struct_method_invalid_autocomplete.move:20:23 + │ +20 │ let _tmp1 = _a.t7(); + │ ^ Possible dot names: 'a::m::t0', 'a::m::t1', or 'a::m::t2' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/struct_method_invalid_autocomplete.move:20:24 │ @@ -22,6 +28,12 @@ error[E04023]: invalid method call │ │ No local 'use fun' alias was found for 'a::m::B.t8', and no function 't8' was found in the defining module 'a::m' │ Invalid method call. No known method 't8' on type 'a::m::B' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/struct_method_invalid_autocomplete.move:21:23 + │ +21 │ let _tmp2 = _b.t8(); + │ ^ Possible dot names: 'a::m::t3', 'a::m::t4', or 'a::m::t5' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/struct_method_invalid_autocomplete.move:21:24 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_autocomplete.ide.exp index 0f00efe3449..c80cb002c1a 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_autocomplete.ide.exp @@ -59,6 +59,17 @@ note[I15006]: IDE path autocomplete = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' = type params: 'T' +note[I15006]: IDE path autocomplete + ┌─ tests/move_2024/ide_mode/type_param_autocomplete.move:6:10 + │ +6 │ &mut action.inner.bar + │ ^^^^^^ Possible in-scope names + │ + = members: 'Action -> 0x42::m::Action', 'Option -> std::option::Option', or 'make_action_ref -> 0x42::m::make_action_ref' + = modules: 'Self -> 0x42::m', 'option -> std::option', or 'vector -> std::vector' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: 'T' + error[E04009]: expected specific type ┌─ tests/move_2024/ide_mode/type_param_autocomplete.move:6:10 │ @@ -67,6 +78,12 @@ error[E04009]: expected specific type 6 │ &mut action.inner.bar │ ^^^^^^^^^^^^^^^^ Unbound field 'bar' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/type_param_autocomplete.move:6:16 + │ +6 │ &mut action.inner.bar + │ ^ Possible dot names: '0x42::m::make_action_ref' or 'inner' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/type_param_autocomplete.move:6:17 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_no_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_no_autocomplete.ide.exp index 83309b4946d..907112727c8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_no_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/type_param_no_autocomplete.ide.exp @@ -59,6 +59,23 @@ note[I15006]: IDE path autocomplete = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' = type params: 'T' +note[I15006]: IDE path autocomplete + ┌─ tests/move_2024/ide_mode/type_param_no_autocomplete.move:6:10 + │ +6 │ &mut action.inner + │ ^^^^^^ Possible in-scope names + │ + = members: 'Action -> 0x42::m::Action', 'Option -> std::option::Option', or 'make_action_ref -> 0x42::m::make_action_ref' + = modules: 'Self -> 0x42::m', 'option -> std::option', or 'vector -> std::vector' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: 'T' + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/type_param_no_autocomplete.move:6:16 + │ +6 │ &mut action.inner + │ ^ Possible dot names: '0x42::m::make_action_ref' or 'inner' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/type_param_no_autocomplete.move:6:17 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/use_fun_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/use_fun_autocomplete.ide.exp index 3d2a42795af..7fa6e5ced59 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/use_fun_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/ide_mode/use_fun_autocomplete.ide.exp @@ -1,9 +1,21 @@ +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/use_fun_autocomplete.move:12:10 + │ +12 │ s.bak(); // autocompletion to `bak` and `foo` + │ ^ Possible dot names: '0x42::m1::bak', '0x42::m1::foo', '0x42::m1::test1', or '0x42::m1::test2' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/use_fun_autocomplete.move:12:11 │ 12 │ s.bak(); // autocompletion to `bak` and `foo` │ ^^^ Possible dot names: '0x42::m1::bak', '0x42::m1::foo', '0x42::m1::test1', or '0x42::m1::test2' +note[I15001]: IDE dot autocomplete + ┌─ tests/move_2024/ide_mode/use_fun_autocomplete.move:17:10 + │ +17 │ s.bar(); // auto-completion to only one (shadowed) `bar` + │ ^ Possible dot names: '0x42::m1::bar', '0x42::m1::test1', or '0x42::m1::test2' + note[I15001]: IDE dot autocomplete ┌─ tests/move_2024/ide_mode/use_fun_autocomplete.move:17:11 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.exp new file mode 100644 index 00000000000..8757b3e87a6 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.exp @@ -0,0 +1,12 @@ +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.move:14:13 + │ + 3 │ public enum ABC { + │ --- To satisfy the constraint, the 'drop' ability would need to be added here + · +10 │ match (ABC::C(0)) { + │ --------- The type '0x42::m::ABC' does not have the ability 'drop' + · +14 │ _ => 1, + │ ^ Cannot ignore values without the 'drop' ability. '_' patterns discard their values + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.move new file mode 100644 index 00000000000..aa3084d6957 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/abc_match_no_drop_exhaustive_invalid.move @@ -0,0 +1,18 @@ +module 0x42::m { + + public enum ABC { + A(T), + B, + C(T) + } + + fun t0(): u64 { + match (ABC::C(0)) { + ABC::C(x) => x, + ABC::A(x) => x, + ABC::B => 0, + _ => 1, + } + } + +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/generated_0.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/generated_0.move new file mode 100644 index 00000000000..7afb2321d80 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/generated_0.move @@ -0,0 +1,418 @@ +module 0x42::m; + +public enum Option has drop { + None, + Some(T) +} + +fun t1(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::None => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t2(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + _ if (_value) => 0u64, + Option::None => 0u64, + Option::Some(val) if (_value) => val, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t3(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + _ => 0u64, + _ => 0u64, + Option::None => 0u64, + _ if (true) => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t4(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + _ => 0u64, + Option::Some(val) if (val == 0) => val, + Option::None => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t5(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::None => 0u64, + Option::Some(val) => val, + _ => 0u64, + Option::None => 0u64, + _ => 0u64, + _ if (_value) => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t6(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) => val, + Option::None => 0u64, + Option::Some(val) if (_value) => val, + Option::Some(val) => val, + Option::Some(val) if (*val < 100 && val != 42) => val, + _ if (_value) => 0u64, + _ if (_value) => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t7(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + _ => 0u64, + _ => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + _ if (_value) => 0u64, + _ => 0u64, + _ if (_value) => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t8(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) if (true) => val, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::None => 0u64, + Option::Some(val) if (*val > 50) => val, + Option::Some(val) if (val == 0) => val, + Option::Some(val) if (_value) => val, + _ if (true) => 0u64, + Option::None => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t9(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) if (*val < 100 && val != 42) => val, + _ if (_value) => 0u64, + Option::None => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + Option::None => 0u64, + _ if (_value) => 0u64, + Option::None => 0u64, + _ if (true) => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t10(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::Some(val) => val, + Option::None => 0u64, + _ if (true) => 0u64, + _ => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + _ => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t11(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) if (_value) => val, + _ if (true) => 0u64, + _ => 0u64, + Option::None => 0u64, + _ if (_value) => 0u64, + Option::None => 0u64, + _ => 0u64, + Option::None => 0u64, + _ if (_value) => 0u64, + Option::None => 0u64, + _ => 0u64, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t12(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::None => 0u64, + _ => 0u64, + _ => 0u64, + Option::None => 0u64, + Option::None => 0u64, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) if (*val > 50) => val, + Option::Some(val) if (*val > 50) => val, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) => val, + _ => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t13(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::None => 0u64, + Option::None => 0u64, + _ if (_value) => 0u64, + Option::Some(val) => val, + _ => 0u64, + _ if (true) => 0u64, + _ => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + Option::Some(val) => val, + _ => 0u64, + _ => 0u64, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t14(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) if (val == 0) => val, + Option::Some(val) if (*val > 50) => val, + Option::None => 0u64, + Option::Some(val) => val, + _ => 0u64, + Option::Some(val) if (*val > 50) => val, + _ => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + _ if (true) => 0u64, + _ => 0u64, + Option::Some(val) if (val == 0) => val, + Option::Some(val) if (*val > 50) => val, + Option::Some(val) if (*val > 50) => val, + _ => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t15(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::None => 0u64, + _ if (_value) => 0u64, + _ if (_value) => 0u64, + Option::None => 0u64, + _ => 0u64, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::None => 0u64, + Option::None => 0u64, + Option::None => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + Option::Some(val) if (*val > 50) => val, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t16(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) if (val == 0) => val, + _ => 0u64, + _ if (_value) => 0u64, + _ if (true) => 0u64, + Option::None => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + _ => 0u64, + _ if (_value) => 0u64, + Option::Some(val) if (val == 0) => val, + Option::Some(val) if (_value) => val, + _ => 0u64, + _ => 0u64, + _ => 0u64, + Option::Some(val) => val, + _ => 0u64, + Option::None => 0u64, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t17(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::None => 0u64, + Option::Some(val) if (_value) => val, + _ if (true) => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + _ => 0u64, + Option::Some(val) if (_value) => val, + Option::None => 0u64, + Option::None => 0u64, + Option::None => 0u64, + _ => 0u64, + _ => 0u64, + Option::None => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + _ => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::Some(val) if (_value) => val, + Option::Some(val) if (*val > 50) => val, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t18(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) => val, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + Option::Some(val) if (*val > 50) => val, + Option::Some(val) if (val == 0) => val, + Option::Some(val) => val, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) if (true) => val, + _ => 0u64, + _ => 0u64, + Option::None => 0u64, + _ if (_value) => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + Option::Some(val) => val, + Option::Some(val) => val, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t19(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + Option::Some(val) => val, + Option::None => 0u64, + _ if (true) => 0u64, + Option::Some(val) => val, + Option::Some(val) if (*val < 100 && val != 42) => val, + _ => 0u64, + Option::Some(val) if (val == 0) => val, + Option::Some(val) if (*val > 50) => val, + Option::Some(val) if (_value) => val, + Option::None => 0u64, + Option::None => 0u64, + Option::Some(val) => val, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + _ if (true) => 0u64, + Option::None => 0u64, + _ => 0u64, + Option::Some(val) if (val == 0) => val, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + +fun t20(): u64 { + let _value = false; + let o: Option = Option::None; + match (o) { + _ if (true) => 0u64, + _ if (_value) => 0u64, + Option::Some(val) => val, + Option::Some(val) if (val == 0) => val, + Option::None => 0u64, + _ if (_value) => 0u64, + _ => 0u64, + Option::Some(val) => val, + Option::Some(val) if (_value) => val, + Option::None => 0u64, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::Some(val) if (*val < 100 && val != 42) => val, + Option::Some(val) => val, + _ if (true) => 0u64, + Option::Some(val) if (val == 0) => val, + _ => 0u64, + Option::None => 0u64, + Option::None => 0u64, + Option::Some(val) if (_value) => val, + _ => 0u64, + Option::None => 0u64, + Option::None => 2, + Option::Some(_) => 3, + } +} + + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/go_match.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/go_match.move new file mode 100644 index 00000000000..3b03be9233c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/go_match.move @@ -0,0 +1,15 @@ +module 0x42::go; + +public enum Color has copy, store, drop { + Empty, + Black, + White, +} + +public fun from_index(color: Color): u64 { + match (color) { + Color::White => 0, + Color::Black => 1, + _ => abort 0, + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/go_repro.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/go_repro.move new file mode 100644 index 00000000000..3cc3ea8db13 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/go_repro.move @@ -0,0 +1,16 @@ +module 0x42::go; + +public enum Colour has copy, store, drop { + Empty, + Black, + White, +} + +public fun from_index(index: u64): Colour { + match (index) { + 0 => Colour::Empty, + 1 => Colour::Black, + 2 => Colour::White, + _ => abort 0, + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.exp index d3a6cb34dbd..90e4b09fa58 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.exp @@ -1,18 +1,18 @@ error[E01002]: unexpected token - ┌─ tests/move_2024/matching/guard_invalid_copy.move:17:32 + ┌─ tests/move_2024/matching/guard_invalid_copy.move:17:28 │ -17 │ Option::Some(n) if check_s(n) => n, - │ ^^^^^^^ - │ │ - │ Unexpected 'check_s' - │ Expected '(' +17 │ Option::Some(n) if check_s(n) => n, + │ ^^^^^^^ + │ │ + │ Unexpected 'check_s' + │ Expected '(' error[E01002]: unexpected token - ┌─ tests/move_2024/matching/guard_invalid_copy.move:26:32 + ┌─ tests/move_2024/matching/guard_invalid_copy.move:26:28 │ -26 │ Option::Some(n) if check_s(copy n) => n, - │ ^^^^^^^ - │ │ - │ Unexpected 'check_s' - │ Expected '(' +26 │ Option::Some(n) if check_s(copy n) => n, + │ ^^^^^^^ + │ │ + │ Unexpected 'check_s' + │ Expected '(' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.move index 209f54b627d..0be603bd590 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_invalid_copy.move @@ -1,32 +1,30 @@ -module 0x42::m { +module 0x42::m; - public enum Option has drop { - None, - Some(T) - } +public enum Option has drop { + None, + Some(T) +} - public struct S has drop {} +public struct S has drop {} - fun check_s(_s: S): bool { - false - } +fun check_s(_s: S): bool { + false +} - fun t0(): S { - let o: Option = Option::None; - match (o) { - Option::Some(n) if check_s(n) => n, - Option::Some(y) => y, - Option::None => S {}, - } +fun t0(): S { + let o: Option = Option::None; + match (o) { + Option::Some(n) if check_s(n) => n, + Option::Some(y) => y, + Option::None => S {}, } +} - fun t1(): S { - let o: Option = Option::None; - match (o) { - Option::Some(n) if check_s(copy n) => n, - Option::Some(y) => y, - Option::None => S {}, - } +fun t1(): S { + let o: Option = Option::None; + match (o) { + Option::Some(n) if check_s(copy n) => n, + Option::Some(y) => y, + Option::None => S {}, } - } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild.move new file mode 100644 index 00000000000..97e7246275f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild.move @@ -0,0 +1,13 @@ +module 0x0::repro; + +public enum Tile has store, drop { + Empty, + Unwalkable, +} + +public fun failure(tile: &Tile, value: bool): u64 { + match (tile) { + _ if (value) => 0, + _ => 1, + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.exp new file mode 100644 index 00000000000..22bdd8195ad --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.exp @@ -0,0 +1,8 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/move_2024/matching/guard_wild_inexhaustive.move:9:12 + │ +9 │ match (tile) { + │ ^^^^ Pattern 'Tile::Unwalkable' not covered + │ + = Match arms with guards are not considered for coverage. + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.move new file mode 100644 index 00000000000..d146eba8b9e --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_inexhaustive.move @@ -0,0 +1,13 @@ +module 0x0::repro; + +public enum Tile has store, drop { + Empty, + Unwalkable, +} + +public fun failure(tile: &Tile, value: bool): u64 { + match (tile) { + _ if (value) => 0, + Tile::Empty => 1, + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_initial.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_initial.move new file mode 100644 index 00000000000..bff143a042b --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/guard_wild_initial.move @@ -0,0 +1,14 @@ +module 0x0::repro; + +public enum Tile has store, drop { + Empty, + Unwalkable, +} + +public fun failure(tile: &Tile, value: bool): u64 { + match (tile) { + _ if (value) => 0, + Tile::Empty => 1, + Tile::Unwalkable => 2, + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/if_compilation.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/if_compilation.move new file mode 100644 index 00000000000..1b326d6e432 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/if_compilation.move @@ -0,0 +1,9 @@ +module 0x42::m; + +fun test(): u64 { + if (true) { + 5 + } else { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_complex.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_complex.move new file mode 100644 index 00000000000..e27a87cda2d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_complex.move @@ -0,0 +1,14 @@ +module a::m; + +fun t0() { + let x = 2 + 5; + match (x) { _ => {} } +} + +fun t1() { + match ({ 2 + 3 + 4}) { _ => {} } +} + +fun t2() { + match ({ let x = 2 + 3; x + 4}) { _ => {} } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_mut_ref_type.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_mut_ref_type.move new file mode 100644 index 00000000000..7294975f791 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_mut_ref_type.move @@ -0,0 +1,5 @@ +module a::m; + +fun t() { + match (&mut 10) { _ => {} } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_ref_type.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_ref_type.move new file mode 100644 index 00000000000..a3a0eca9c2b --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_ref_type.move @@ -0,0 +1,5 @@ +module a::m; + +fun t() { + match (&10) { _ => {} } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_subject.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_subject.move new file mode 100644 index 00000000000..015242e02bc --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/inferred_int_subject.move @@ -0,0 +1,5 @@ +module a::m; + +fun t() { + match (10) { _ => {} } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.exp new file mode 100644 index 00000000000..b56d2d65de9 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.exp @@ -0,0 +1,17 @@ +warning[W09002]: unused variable + ┌─ tests/move_2024/matching/invalid_match_lhs.move:8:10 + │ +8 │ fun test(z: &mut Maybe) { + │ ^ Unused parameter 'z'. Consider removing or prefixing with an underscore: '_z' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E01002]: unexpected token + ┌─ tests/move_2024/matching/invalid_match_lhs.move:9:9 + │ +9 │ let { match (z) { Maybe::Just(n) => n, Maybe::Nothing => abort 0 } } = 5; + │ ^ + │ │ + │ Unexpected '{' + │ Expected a variable or struct name + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.move new file mode 100644 index 00000000000..959cab9feb1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_lhs.move @@ -0,0 +1,12 @@ +module 0x42::m; + +public enum Maybe { + Just(T), + Nothing +} + +fun test(z: &mut Maybe) { + let { match (z) { Maybe::Just(n) => n, Maybe::Nothing => abort 0 } } = 5; +} + + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_tuple.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_tuple.exp index 76b4f0f35ae..3ae3051767d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_tuple.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_match_tuple.exp @@ -7,12 +7,6 @@ error[E04005]: expected a single type 6 │ match (x()) { │ ^^^ Invalid 'match' subject -error[E04036]: non-exhaustive pattern - ┌─ tests/move_2024/matching/invalid_match_tuple.move:6:16 - │ -6 │ match (x()) { - │ ^^^ Pattern '_' not covered - error[E01002]: unexpected token ┌─ tests/move_2024/matching/invalid_match_tuple.move:7:15 │ @@ -22,6 +16,23 @@ error[E01002]: unexpected token │ Unexpected ',' │ Expected ')' +warning[W09002]: unused variable + ┌─ tests/move_2024/matching/invalid_match_tuple.move:7:17 + │ +7 │ (x, y) => () + │ ^ Unused local variable 'y'. Consider removing or prefixing with an underscore: '_y' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E04005]: expected a single type + ┌─ tests/move_2024/matching/invalid_match_tuple.move:7:17 + │ +3 │ fun x(): (u64, u64) { (0, 42) } + │ ---------- Expected a single type, but found expression list type: '(u64, u64)' + · +7 │ (x, y) => () + │ ^ Invalid type for pattern + error[E01002]: unexpected token ┌─ tests/move_2024/matching/invalid_match_tuple.move:7:18 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_mut.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_mut.exp index 3161d1afd56..63b459824bd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_mut.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_mut.exp @@ -6,21 +6,21 @@ error[E02010]: invalid name │ │ │ 'mut' can only be used with variable bindings in patterns -error[E02010]: invalid name +warning[W09002]: unused variable ┌─ tests/move_2024/matching/invalid_mut.move:11:17 │ 11 │ mut x => (), - │ ^ Invalid type arguments on a pattern variable + │ ^ Unused local variable 'x'. Consider removing or prefixing with an underscore: '_x' │ - = Type arguments cannot appear on pattern variables + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09002]: unused variable +error[E02010]: invalid name ┌─ tests/move_2024/matching/invalid_mut.move:11:17 │ 11 │ mut x => (), - │ ^ Unused local variable 'x'. Consider removing or prefixing with an underscore: '_x' + │ ^ Invalid type arguments on a pattern variable │ - = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + = Type arguments cannot appear on pattern variables error[E01002]: unexpected token ┌─ tests/move_2024/matching/invalid_mut.move:12:13 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_named_match_2.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_named_match_2.exp index cf2d14bbc94..aa2da55f42d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_named_match_2.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_named_match_2.exp @@ -9,17 +9,17 @@ error[E03013]: positional call mismatch │ = Named patterns take arguments using '{ }' -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/matching/invalid_named_match_2.move:9:13 │ 9 │ Entry::One(x) => () - │ ^^^^^^^^^^^^^ Missing pattern for field 'x' in '0x42::m::Entry::One' + │ ^^^^^^^^^^^^^ Unbound field '0' in '0x42::m::Entry::One' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/matching/invalid_named_match_2.move:9:13 │ 9 │ Entry::One(x) => () - │ ^^^^^^^^^^^^^ Unbound field '0' in '0x42::m::Entry::One' + │ ^^^^^^^^^^^^^ Missing pattern for field 'x' in '0x42::m::Entry::One' warning[W09002]: unused variable ┌─ tests/move_2024/matching/invalid_named_match_2.move:9:24 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_2.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_2.exp index fa428e401c5..c19603e07ba 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_2.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_2.exp @@ -1,3 +1,11 @@ +warning[W09002]: unused variable + ┌─ tests/move_2024/matching/invalid_or_binding_2.move:9:53 + │ +9 │ Three::Tuple(x, _, _) | Three::Tuple(_, y, _) | Three::Tuple(_, _, x) => { let _y = x; }, + │ ^ Unused local variable 'y'. Consider removing or prefixing with an underscore: '_y' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E03019]: invalid pattern ┌─ tests/move_2024/matching/invalid_or_binding_2.move:9:53 │ @@ -18,14 +26,6 @@ error[E03019]: invalid pattern │ = Both sides of an or-pattern must bind the same variables. -warning[W09002]: unused variable - ┌─ tests/move_2024/matching/invalid_or_binding_2.move:9:53 - │ -9 │ Three::Tuple(x, _, _) | Three::Tuple(_, y, _) | Three::Tuple(_, _, x) => { let _y = x; }, - │ ^ Unused local variable 'y'. Consider removing or prefixing with an underscore: '_y' - │ - = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - error[E03019]: invalid pattern ┌─ tests/move_2024/matching/invalid_or_binding_2.move:9:80 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.exp new file mode 100644 index 00000000000..ae3ad49d773 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.exp @@ -0,0 +1,12 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/move_2024/matching/invalid_or_binding_3.move:9:12 + │ +9 │ match (e) { + │ ^ Pattern 'E::Y { y: _ }' not covered + +error[E03010]: unbound field + ┌─ tests/move_2024/matching/invalid_or_binding_3.move:10:22 + │ +10 │ E::X { x } | E::Y { y: _, x } => *x + │ ^^^^^^^^^^^^^^^^ Unbound field 'x' in '0x42::m::E::Y' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.move new file mode 100644 index 00000000000..aeccf3f59cc --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_3.move @@ -0,0 +1,12 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y { y: u64 } +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x } | E::Y { y: _, x } => *x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.exp new file mode 100644 index 00000000000..83419491bee --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.exp @@ -0,0 +1,28 @@ +warning[W09002]: unused variable + ┌─ tests/move_2024/matching/invalid_or_binding_4.move:11:19 + │ +11 │ E::X { x: y } | E::Y(x) | E::Z { z: x } => *x + │ ^ Unused local variable 'y'. Consider removing or prefixing with an underscore: '_y' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E03019]: invalid pattern + ┌─ tests/move_2024/matching/invalid_or_binding_4.move:11:19 + │ +11 │ E::X { x: y } | E::Y(x) | E::Z { z: x } => *x + │ ^ ----------------------- right or-pattern does not + │ │ + │ left or-pattern binds variable y + │ + = Both sides of an or-pattern must bind the same variables. + +error[E03019]: invalid pattern + ┌─ tests/move_2024/matching/invalid_or_binding_4.move:11:30 + │ +11 │ E::X { x: y } | E::Y(x) | E::Z { z: x } => *x + │ ------------- ^ right or-pattern binds variable x + │ │ + │ left or-pattern does not + │ + = Both sides of an or-pattern must bind the same variables. + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.move new file mode 100644 index 00000000000..5598703049c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_binding_4.move @@ -0,0 +1,13 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y(u64), + Z { z: u64 } +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x: y } | E::Y(x) | E::Z { z: x } => *x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.exp new file mode 100644 index 00000000000..1842f8ab05e --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.exp @@ -0,0 +1,17 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/move_2024/matching/invalid_or_pattern.move:9:12 + │ +9 │ match (e) { + │ ^ Pattern 'E::Y' not covered + +error[E03013]: positional call mismatch + ┌─ tests/move_2024/matching/invalid_or_pattern.move:10:22 + │ + 5 │ Y + │ - 'Y' is declared here + · +10 │ E::X { x } | E::Y { y: _, x } => *x + │ ^^^^^^^^^^^^^^^^ Invalid variant pattern. Empty variant declarations require empty patterns + │ + = Remove '{ }' arguments from this pattern + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.move new file mode 100644 index 00000000000..4ccd310b2ef --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_pattern.move @@ -0,0 +1,12 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x } | E::Y { y: _, x } => *x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.exp new file mode 100644 index 00000000000..2dba4ccee21 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.exp @@ -0,0 +1,11 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/matching/invalid_or_types.move:10:24 + │ + 4 │ X(u64), + │ --- Given: 'u64' + 5 │ Y(u32) + │ --- Expected: 'u32' + · +10 │ E::X(x) | E::Y(x) => *x + │ ^ Invalid pattern field type + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.move new file mode 100644 index 00000000000..19aa0990a54 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types.move @@ -0,0 +1,12 @@ +module 0x42::m; + +public enum E { + X(u64), + Y(u32) +} + +public fun test(e: &E): u64 { + match (e) { + E::X(x) | E::Y(x) => *x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.exp new file mode 100644 index 00000000000..07790fd3e54 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.exp @@ -0,0 +1,11 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/matching/invalid_or_types_2.move:10:35 + │ + 4 │ X { x: u64 }, + │ --- Given: 'u64' + 5 │ Y { y: u64, x: u32 } + │ --- Expected: 'u32' + · +10 │ E::X { x } | E::Y { y: _, x } => *x + │ ^ Invalid pattern field type + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.move new file mode 100644 index 00000000000..3a30f1051ad --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_2.move @@ -0,0 +1,12 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y { y: u64, x: u32 } +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x } | E::Y { y: _, x } => *x + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.exp new file mode 100644 index 00000000000..d19b356a5b4 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.exp @@ -0,0 +1,11 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/matching/invalid_or_types_3.move:10:30 + │ + 4 │ X { x: u64 }, + │ --- Given: 'u64' + 5 │ Y(u32) + │ --- Expected: 'u32' + · +10 │ E::X { x: y } | E::Y(y) => *y + │ ^ Invalid pattern field type + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.move new file mode 100644 index 00000000000..c8e2ecfe5c6 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_3.move @@ -0,0 +1,12 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y(u32) +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x: y } | E::Y(y) => *y + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.exp new file mode 100644 index 00000000000..055b1ca7d7f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.exp @@ -0,0 +1,11 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/matching/invalid_or_types_4.move:11:30 + │ + 4 │ X { x: u64 }, + │ --- Given: 'u64' + 5 │ Y(u32), + │ --- Expected: 'u32' + · +11 │ E::X { x: y } | E::Y(y) | E::Z { z: y } => *y + │ ^ Invalid pattern field type + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.move new file mode 100644 index 00000000000..f4a44a3d3e9 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_or_types_4.move @@ -0,0 +1,13 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y(u32), + Z { z: u64 } +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x: y } | E::Y(y) | E::Z { z: y } => *y + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_ctor.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_ctor.exp index 545f93acffd..6531322b6e0 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_ctor.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_ctor.exp @@ -26,15 +26,15 @@ error[E03013]: positional call mismatch │ = Positional instantiations take arguments using '()' -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/matching/invalid_positional_ctor.move:9:18 │ 9 │ let _x = Entry::E { x: 32 }; - │ ^^^^^^^^^^^^^^^^^^ Missing argument for field '0' in '0x42::m::Entry::E' + │ ^^^^^^^^^^^^^^^^^^ Unbound field 'x' in '0x42::m::Entry::E' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/matching/invalid_positional_ctor.move:9:18 │ 9 │ let _x = Entry::E { x: 32 }; - │ ^^^^^^^^^^^^^^^^^^ Unbound field 'x' in '0x42::m::Entry::E' + │ ^^^^^^^^^^^^^^^^^^ Missing argument for field '0' in '0x42::m::Entry::E' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_match_2.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_match_2.exp index cabf15ff4c2..f889ea1534a 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_match_2.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_positional_match_2.exp @@ -9,17 +9,17 @@ error[E03013]: positional call mismatch │ = Positional patterns take arguments using '()' -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/matching/invalid_positional_match_2.move:9:13 │ 9 │ Entry::One { x } => () - │ ^^^^^^^^^^^^^^^^ Missing pattern for field '0' in '0x42::m::Entry::One' + │ ^^^^^^^^^^^^^^^^ Unbound field 'x' in '0x42::m::Entry::One' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/matching/invalid_positional_match_2.move:9:13 │ 9 │ Entry::One { x } => () - │ ^^^^^^^^^^^^^^^^ Unbound field 'x' in '0x42::m::Entry::One' + │ ^^^^^^^^^^^^^^^^ Missing pattern for field '0' in '0x42::m::Entry::One' warning[W09002]: unused variable ┌─ tests/move_2024/matching/invalid_positional_match_2.move:9:26 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.exp new file mode 100644 index 00000000000..3d913a1831e --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.exp @@ -0,0 +1,33 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/move_2024/matching/invalid_raw_variant_name.move:10:12 + │ +10 │ match (e) { + │ ^ Pattern 'E::Z { z: _ }' not covered + +error[E03019]: invalid pattern + ┌─ tests/move_2024/matching/invalid_raw_variant_name.move:11:30 + │ +11 │ E::X { x: y } | E::Y(y) | Z { z: y } => *y + │ ^ ---------- right or-pattern does not + │ │ + │ left or-pattern binds variable y + │ + = Both sides of an or-pattern must bind the same variables. + +error[E04007]: incompatible types + ┌─ tests/move_2024/matching/invalid_raw_variant_name.move:11:30 + │ + 4 │ X { x: u64 }, + │ --- Given: 'u64' + 5 │ Y(u32), + │ --- Expected: 'u32' + · +11 │ E::X { x: y } | E::Y(y) | Z { z: y } => *y + │ ^ Invalid pattern field type + +error[E01002]: unexpected token + ┌─ tests/move_2024/matching/invalid_raw_variant_name.move:11:35 + │ +11 │ E::X { x: y } | E::Y(y) | Z { z: y } => *y + │ ^ Unexpected name access. Expected a valid 'enum' variant, 'struct', or 'const'. + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.move new file mode 100644 index 00000000000..ccd9f43aedf --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_raw_variant_name.move @@ -0,0 +1,13 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y(u32), + Z { z: u64 } +} + +public fun test(e: &E): u64 { + match (e) { + E::X { x: y } | E::Y(y) | Z { z: y } => *y + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_struct_form.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_struct_form.exp index f3d65a542f4..fa63db90cbf 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_struct_form.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/invalid_struct_form.exp @@ -7,17 +7,17 @@ error[E03013]: positional call mismatch 9 │ P { x } => x, │ ^^^^^^^ Invalid struct pattern. Positional struct declarations require positional patterns -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/matching/invalid_struct_form.move:9:13 │ 9 │ P { x } => x, - │ ^^^^^^^ Missing pattern for field '0' in 'a::m::P' + │ ^^^^^^^ Unbound field 'x' in 'a::m::P' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/matching/invalid_struct_form.move:9:13 │ 9 │ P { x } => x, - │ ^^^^^^^ Unbound field 'x' in 'a::m::P' + │ ^^^^^^^ Missing pattern for field '0' in 'a::m::P' error[E03013]: positional call mismatch ┌─ tests/move_2024/matching/invalid_struct_form.move:12:13 @@ -28,15 +28,15 @@ error[E03013]: positional call mismatch 12 │ N(x) => x, │ ^^^^ Invalid struct pattern. Named struct declarations require named patterns -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/matching/invalid_struct_form.move:12:13 │ 12 │ N(x) => x, - │ ^^^^ Missing pattern for field 'x' in 'a::m::N' + │ ^^^^ Unbound field '0' in 'a::m::N' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/matching/invalid_struct_form.move:12:13 │ 12 │ N(x) => x, - │ ^^^^ Unbound field '0' in 'a::m::N' + │ ^^^^ Missing pattern for field 'x' in 'a::m::N' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/lit_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/lit_abort.move new file mode 100644 index 00000000000..111d0963957 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/lit_abort.move @@ -0,0 +1,19 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun from_index(index: u64): u64 { + match (index) { + 0 => 1, + 1 => 2, + 2 => 3, + _ => abort 0, + } + } + + public fun run() { + assert!(from_index(2) == 3) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/matching_everywhere.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/matching_everywhere.move new file mode 100644 index 00000000000..6c5365e1250 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/matching_everywhere.move @@ -0,0 +1,51 @@ +module 0x42::m; + +public enum Maybe { + Just(T), + Nothing +} + + +fun helper(_x: u64) { abort 0 } + +fun test(x: &Maybe, y: Maybe): u64 { + helper(match (y) { Maybe::Just(n) => n, Maybe::Nothing => 0 }); + + let a: u64 = match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 }; + + let b: u64 = loop { + break match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 } + }; + + let c: u64 = 'a: { + return 'a match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 } + }; + + let d: u64 = 'a: { + while (true) { + return 'a match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 } + }; + 0 + }; + + while (match (x) { Maybe::Just(_) => true, Maybe::Nothing => false }) { + break + }; + + let e = if (match (x) { Maybe::Just(_) => true, Maybe::Nothing => false, }) return 5 else 0; + + let (f, g) = ( + match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 }, + match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 } + ); + + let h = match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 } + 1; + + let i = 1 + match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 }; + + let j = match (x) { Maybe::Just(n) => match (x) { Maybe::Just(m) => *n + *m, Maybe::Nothing => 0 }, Maybe::Nothing => 0 }; + + let _q = a + b + c + d + e + f + g + h + i + j; + + return match (x) { Maybe::Just(n) => *n, Maybe::Nothing => 0 } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias.move new file mode 100644 index 00000000000..73068022ec2 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias.move @@ -0,0 +1,17 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y { y: u64 } +} + +public fun test() { + let e = E::Y { y: 1 }; + let value = match (e) { + E::X { mut x } | E::Y { y: mut x } => { + x = x + 1; + x + } + }; + assert!(value == 2); +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias_2.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias_2.move new file mode 100644 index 00000000000..73068022ec2 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/mut_field_alias_2.move @@ -0,0 +1,17 @@ +module 0x42::m; + +public enum E { + X { x: u64 }, + Y { y: u64 } +} + +public fun test() { + let e = E::Y { y: 1 }; + let value = match (e) { + E::X { mut x } | E::Y { y: mut x } => { + x = x + 1; + x + } + }; + assert!(value == 2); +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_label.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_label.move new file mode 100644 index 00000000000..9b63bd09c74 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_label.move @@ -0,0 +1,49 @@ +module 0x42::TestLoopLabelShadowing; + +public enum Action has drop { + Stop, + MoveTo { x: u64, y: u64 }, + ChangeSpeed(u64), +} + +public fun test() { + // Define a list of actions + let actions: vector = vector[ + Action::MoveTo { x: 10, y: 20 }, + Action::ChangeSpeed(40), + Action::MoveTo { x: 10, y: 20 }, + Action::Stop + ]; + + let mut total_moves = 0; + + 'loop_label: loop { + let mut i = 0; + while (i < actions.length()) { + let action = &actions[i]; + + match (action) { + Action::MoveTo { x, y } => { + 'loop_label: loop { + total_moves = total_moves + *x + *y; + break 'loop_label + }; + }, + Action::ChangeSpeed(_) => { + 'loop_label: loop { + break 'loop_label + }; + }, + Action::Stop => { + break 'loop_label + }, + _ => {}, + }; + i = i + 1; + }; + }; + + actions.destroy_empty(); + + assert!(total_moves == 60); +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_with_or.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_with_or.move new file mode 100644 index 00000000000..1fd0a00daa5 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/rhs_shadow_loop_with_or.move @@ -0,0 +1,44 @@ +module 0x42::TestLoopLabelShadowing; + +public enum Action has drop { + Stop, + MoveTo { x: u64, y: u64 }, + ChangeSpeed(u64), +} + +public fun test() { + // Define a list of actions + let actions: vector = vector[ + Action::MoveTo { x: 10, y: 20 }, + Action::ChangeSpeed(20), + Action::MoveTo { x: 10, y: 20 }, + Action::Stop + ]; + + let mut total_moves = 0; + + 'loop_label: loop { + let mut i = 0; + while (i < actions.length()) { + let action = &actions[i]; + + match (action) { + Action::MoveTo { x: speed, y: _ } | Action::ChangeSpeed(speed) => { + 'loop_label: loop { + total_moves = total_moves + *speed; + break 'loop_label + }; + }, + Action::Stop => { + break 'loop_label + }, + _ => {}, + }; + i = i + 1; + }; + }; + + actions.destroy_empty(); + + assert!(total_moves == 40); +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp.move new file mode 100644 index 00000000000..c20fe05d04b --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp.move @@ -0,0 +1,117 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Op has drop { + LoopOpen, + BreakIfEven(u64), // encodes jump PC + Return, + Push(u64), + Add, + LoopClose, + } + + fun interp(ops: vector): u64 { + let mut stack = vector[]; + let mut loop_pcs = vector[]; + let mut cur_pc = 0; + + 'exit: { + 'interp: loop { + match (&ops[cur_pc]) { + Op::LoopOpen => { + loop_pcs.push_back(cur_pc + 1); + }, + Op::BreakIfEven(new_pc) => { + let top = stack[stack.length() - 1]; + if (top % 2 == 0) { + loop_pcs.pop_back(); + cur_pc = *new_pc; + continue 'interp + } + }, + Op::Return => { + return 'exit + }, + Op::Push(value) => { + stack.push_back(*value); + }, + Op::Add => { + let n0 = stack.pop_back(); + let n1 = stack.pop_back(); + stack.push_back(n0 + n1); + }, + Op::LoopClose => { + cur_pc = loop_pcs[loop_pcs.length() - 1]; + continue 'interp + } + }; + cur_pc = cur_pc + 1; + } + }; + + stack.pop_back() + } + + fun test() { + + let push = vector[ + Op::Push(1), + Op::Return, + ]; + + assert!(interp(push) == 1); + + let add = vector[ + Op::Push(1), + Op::Push(1), + Op::Add, + Op::Return, + ]; + + assert!(interp(add) == 2); + + let early_break = vector[ + Op::Push(1), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp(early_break) == 100); + + let exiting = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp(exiting) == 1); + + let loop_and_break = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(6), + Op::LoopClose, + Op::Return, + ]; + + assert!(interp(loop_and_break) == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp_macro.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp_macro.move new file mode 100644 index 00000000000..d7671fb22fe --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/stack_interp_macro.move @@ -0,0 +1,118 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + + public enum Op has drop { + LoopOpen, + BreakIfEven(u64), // encodes jump PC + Return, + Push(u64), + Add, + LoopClose, + } + + macro fun interp($ops: vector): u64 { + let ops = $ops; + let mut stack = vector[]; + let mut loop_pcs = vector[]; + let mut cur_pc = 0; + + 'exit: { + 'interp: loop { + match (&ops[cur_pc]) { + Op::LoopOpen => { + loop_pcs.push_back(cur_pc + 1); + }, + Op::BreakIfEven(new_pc) => { + let top = stack[stack.length() - 1]; + if (top % 2 == 0) { + loop_pcs.pop_back(); + cur_pc = *new_pc; + continue 'interp + } + }, + Op::Return => { + return 'exit + }, + Op::Push(value) => { + stack.push_back(*value); + }, + Op::Add => { + let n0 = stack.pop_back(); + let n1 = stack.pop_back(); + stack.push_back(n0 + n1); + }, + Op::LoopClose => { + cur_pc = loop_pcs[loop_pcs.length() - 1]; + continue 'interp + } + }; + cur_pc = cur_pc + 1; + } + }; + + stack.pop_back() + } + + fun test() { + + let push = vector[ + Op::Push(1), + Op::Return, + ]; + + assert!(interp!(push) == 1); + + let add = vector[ + Op::Push(1), + Op::Push(1), + Op::Add, + Op::Return, + ]; + + assert!(interp!(add) == 2); + + let early_break = vector[ + Op::Push(1), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp!(early_break) == 100); + + let exiting = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(7), + Op::Return, + Op::LoopClose, + Op::Push(100), + Op::Return, + ]; + + assert!(interp!(exiting) == 1); + + let loop_and_break = vector[ + Op::Push(0), + Op::LoopOpen, + Op::Push(1), + Op::Add, + Op::BreakIfEven(6), + Op::LoopClose, + Op::Return, + ]; + + assert!(interp!(loop_and_break) == 2); + } +} + +//# run 0x42::m::test diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/struct_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/struct_abort.move new file mode 100644 index 00000000000..c3d9bf35fa1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/struct_abort.move @@ -0,0 +1,19 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public struct S has drop { x: u64 } + + public fun from_index(s: S): u64 { + match (s) { + S { x: 0} => 1, + _ => abort 0, + } + } + + public fun run() { + assert!(from_index(S { x: 0 }) == 1) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_abort.move new file mode 100644 index 00000000000..58a37086695 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_abort.move @@ -0,0 +1,17 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun test(value: bool): u64 { + match (value) { + true => abort 0, + false => 0, + } + } + + public fun run() { + assert!(test(false) == 0) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_nested_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_nested_abort.move new file mode 100644 index 00000000000..8449e4e069a --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/true_false_nested_abort.move @@ -0,0 +1,17 @@ +//# init --edition 2024.beta + +//# publish +module 0x42::m { + public fun test(value: bool): u64 { + match (value) { + true => match (value) { true => abort 0, false => abort 0 }, + false => match (value) { true => abort 0, false => 1 }, + } + } + + public fun run() { + assert!(test(false) == 1) + } +} + +//# run 0x42::m::run diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp index fff63a63a63..12661eefc48 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp @@ -10,7 +10,7 @@ error[E01002]: unexpected token ┌─ tests/move_2024/migration/match_okay.move:3:20 │ 3 │ fun t1(t: u64, match: u64): bool { - │ ^ Expected a function parameter + │ ^ Unexpected 'match'. Expected a function parameter error[E01002]: unexpected token ┌─ tests/move_2024/migration/match_okay.move:5:5 @@ -33,7 +33,7 @@ error[E01002]: unexpected token ┌─ tests/move_2024/migration/match_okay.move:7:20 │ 7 │ fun t2(t: u64, match: u64): bool { - │ ^ Expected a function parameter + │ ^ Unexpected 'match'. Expected a function parameter error[E01002]: unexpected token ┌─ tests/move_2024/migration/match_okay.move:8:23 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/lambda_shadows_function.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/lambda_shadows_function.exp index cb8dbd6f526..23263198999 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/lambda_shadows_function.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/lambda_shadows_function.exp @@ -1,18 +1,18 @@ -error[E02010]: invalid name +warning[W09002]: unused variable ┌─ tests/move_2024/naming/lambda_shadows_function.move:4:22 │ 4 │ macro fun do<$T>(f: || -> $T): $T { - │ ----- ^ Invalid parameter name 'f'. 'macro' parameter names must start with '$' (or must be '_') - │ │ - │ Declared 'macro' here + │ ^ Unused parameter 'f'. Consider removing or prefixing with an underscore: '_f' │ - = 'macro' parameters start with '$' to indicate that their arguments are not evaluated before the macro is expanded, meaning the entire expression is substituted. This is different from regular function parameters that are evaluated before the function is called. + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09002]: unused variable +error[E02010]: invalid name ┌─ tests/move_2024/naming/lambda_shadows_function.move:4:22 │ 4 │ macro fun do<$T>(f: || -> $T): $T { - │ ^ Unused parameter 'f'. Consider removing or prefixing with an underscore: '_f' + │ ----- ^ Invalid parameter name 'f'. 'macro' parameter names must start with '$' (or must be '_') + │ │ + │ Declared 'macro' here │ - = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + = 'macro' parameters start with '$' to indicate that their arguments are not evaluated before the macro is expanded, meaning the entire expression is substituted. This is different from regular function parameters that are evaluated before the function is called. diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/pattern_ellipsis_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/pattern_ellipsis_invalid.exp index f63799601e2..4aaa9fe55af 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/pattern_ellipsis_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/pattern_ellipsis_invalid.exp @@ -31,12 +31,6 @@ error[E03013]: positional call mismatch │ = Remove '()' arguments from this pattern -error[E04017]: too many arguments - ┌─ tests/move_2024/naming/pattern_ellipsis_invalid.move:18:13 - │ -18 │ Y::D(x, ..) => 0, - │ ^^^^^^^^^^^ Invalid usage for empty variant '0x42::m::Y::D'. Empty variants do not take any arguments. - warning[W09002]: unused variable ┌─ tests/move_2024/naming/pattern_ellipsis_invalid.move:18:18 │ @@ -56,12 +50,6 @@ error[E03013]: positional call mismatch │ = Remove '{ }' arguments from this pattern -error[E04017]: too many arguments - ┌─ tests/move_2024/naming/pattern_ellipsis_invalid.move:19:13 - │ -19 │ Y::D{x, ..} => 0, - │ ^^^^^^^^^^^ Invalid usage for empty variant '0x42::m::Y::D'. Empty variants do not take any arguments. - warning[W09002]: unused variable ┌─ tests/move_2024/naming/pattern_ellipsis_invalid.move:19:18 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_pack_of_non_positional_struct.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_pack_of_non_positional_struct.exp index 56e0c33b318..6550c3d64f8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_pack_of_non_positional_struct.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_pack_of_non_positional_struct.exp @@ -7,15 +7,15 @@ error[E03013]: positional call mismatch 6 │ let _x = Foo(0); │ ^^^^^^ Invalid struct instantiation. Named struct declarations require named instantiations -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_pack_of_non_positional_struct.move:6:18 │ 6 │ let _x = Foo(0); - │ ^^^^^^ Missing argument for field 'field' in '0x42::M::Foo' + │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_pack_of_non_positional_struct.move:6:18 │ 6 │ let _x = Foo(0); - │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' + │ ^^^^^^ Missing argument for field 'field' in '0x42::M::Foo' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_lhs_unpack.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_lhs_unpack.exp index 2551a77ff19..fac85060f3e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_lhs_unpack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_lhs_unpack.exp @@ -28,29 +28,29 @@ error[E04007]: incompatible types │ Invalid deconstruction assignment │ Given: '0x42::M::Bar' -error[E04007]: incompatible types +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:9:9 │ -5 │ fun f(x: Foo) { - │ --- Expected: '0x42::M::Foo' - · 9 │ Bar(_, _) = x; - │ ^^^^^^^^^ - │ │ - │ Invalid deconstruction assignment - │ Given: '0x42::M::Bar' + │ ^^^^^^^^^ Unbound field '0' in '0x42::M::Bar' error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:9:9 │ 9 │ Bar(_, _) = x; - │ ^^^^^^^^^ Unbound field '0' in '0x42::M::Bar' + │ ^^^^^^^^^ Unbound field '1' in '0x42::M::Bar' -error[E03010]: unbound field +error[E04007]: incompatible types ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:9:9 │ +5 │ fun f(x: Foo) { + │ --- Expected: '0x42::M::Foo' + · 9 │ Bar(_, _) = x; - │ ^^^^^^^^^ Unbound field '1' in '0x42::M::Bar' + │ ^^^^^^^^^ + │ │ + │ Invalid deconstruction assignment + │ Given: '0x42::M::Bar' error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:13:13 @@ -76,29 +76,29 @@ error[E04007]: incompatible types │ Invalid deconstruction binding │ Given: '0x42::M::Bar' -error[E04007]: incompatible types +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:15:13 │ -12 │ fun g(x: Foo) { - │ --- Expected: '0x42::M::Foo' - · 15 │ let Bar(c, d) = x; - │ ^^^^^^^^^ - │ │ - │ Invalid deconstruction binding - │ Given: '0x42::M::Bar' + │ ^^^^^^^^^ Unbound field '0' in '0x42::M::Bar' error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:15:13 │ 15 │ let Bar(c, d) = x; - │ ^^^^^^^^^ Unbound field '0' in '0x42::M::Bar' + │ ^^^^^^^^^ Unbound field '1' in '0x42::M::Bar' -error[E03010]: unbound field +error[E04007]: incompatible types ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:15:13 │ +12 │ fun g(x: Foo) { + │ --- Expected: '0x42::M::Foo' + · 15 │ let Bar(c, d) = x; - │ ^^^^^^^^^ Unbound field '1' in '0x42::M::Bar' + │ ^^^^^^^^^ + │ │ + │ Invalid deconstruction binding + │ Given: '0x42::M::Bar' warning[W09002]: unused variable ┌─ tests/move_2024/naming/positional_struct_lhs_unpack.move:15:17 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_pack.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_pack.exp index c7bcac72ba9..b674e1a74de 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_pack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_pack.exp @@ -7,15 +7,15 @@ error[E03013]: positional call mismatch 6 │ let _x = Foo { pos0: 0 }; │ ^^^^^^^^^^^^^^^ Invalid struct instantiation. Positional struct declarations require positional instantiations -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_non_positional_pack.move:6:18 │ 6 │ let _x = Foo { pos0: 0 }; - │ ^^^^^^^^^^^^^^^ Missing argument for field '0' in '0x42::M::Foo' + │ ^^^^^^^^^^^^^^^ Unbound field 'pos0' in '0x42::M::Foo' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_struct_non_positional_pack.move:6:18 │ 6 │ let _x = Foo { pos0: 0 }; - │ ^^^^^^^^^^^^^^^ Unbound field 'pos0' in '0x42::M::Foo' + │ ^^^^^^^^^^^^^^^ Missing argument for field '0' in '0x42::M::Foo' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_unpack.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_unpack.exp index b8b49cf7b19..a0e605a96af 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_unpack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_struct_non_positional_unpack.exp @@ -15,17 +15,17 @@ error[E03013]: positional call mismatch 7 │ let Foo { y: _ } = Foo(0); │ ^^^^^^^^^^^^ Invalid struct deconstruction. Positional struct declarations require positional deconstructions -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_non_positional_unpack.move:7:13 │ 7 │ let Foo { y: _ } = Foo(0); - │ ^^^^^^^^^^^^ Missing binding for field '0' in '0x42::M::Foo' + │ ^^^^^^^^^^^^ Unbound field 'y' in '0x42::M::Foo' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_struct_non_positional_unpack.move:7:13 │ 7 │ let Foo { y: _ } = Foo(0); - │ ^^^^^^^^^^^^ Unbound field 'y' in '0x42::M::Foo' + │ ^^^^^^^^^^^^ Missing binding for field '0' in '0x42::M::Foo' warning[W09002]: unused variable ┌─ tests/move_2024/naming/positional_struct_non_positional_unpack.move:12:13 @@ -44,15 +44,15 @@ error[E03013]: positional call mismatch 14 │ Foo { y: _ } = Foo(0); │ ^^^^^^^^^^^^ Invalid struct deconstruction. Positional struct declarations require positional deconstructions -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_struct_non_positional_unpack.move:14:9 │ 14 │ Foo { y: _ } = Foo(0); - │ ^^^^^^^^^^^^ Missing assignment for field '0' in '0x42::M::Foo' + │ ^^^^^^^^^^^^ Unbound field 'y' in '0x42::M::Foo' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_struct_non_positional_unpack.move:14:9 │ 14 │ Foo { y: _ } = Foo(0); - │ ^^^^^^^^^^^^ Unbound field 'y' in '0x42::M::Foo' + │ ^^^^^^^^^^^^ Missing assignment for field '0' in '0x42::M::Foo' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_unpack_of_non_positional_struct.exp b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_unpack_of_non_positional_struct.exp index df872c5e3b3..997a6cd4cb9 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_unpack_of_non_positional_struct.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/naming/positional_unpack_of_non_positional_struct.exp @@ -7,17 +7,17 @@ error[E03013]: positional call mismatch 7 │ let Foo(_) = x; │ ^^^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_unpack_of_non_positional_struct.move:7:13 │ 7 │ let Foo(_) = x; - │ ^^^^^^ Missing binding for field 'field' in '0x42::M::Foo' + │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_unpack_of_non_positional_struct.move:7:13 │ 7 │ let Foo(_) = x; - │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' + │ ^^^^^^ Missing binding for field 'field' in '0x42::M::Foo' error[E03013]: positional call mismatch ┌─ tests/move_2024/naming/positional_unpack_of_non_positional_struct.move:14:9 @@ -28,15 +28,15 @@ error[E03013]: positional call mismatch 14 │ Foo(_) = x; │ ^^^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/naming/positional_unpack_of_non_positional_struct.move:14:9 │ 14 │ Foo(_) = x; - │ ^^^^^^ Missing assignment for field 'field' in '0x42::M::Foo' + │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/naming/positional_unpack_of_non_positional_struct.move:14:9 │ 14 │ Foo(_) = x; - │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' + │ ^^^^^^ Missing assignment for field 'field' in '0x42::M::Foo' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/dot_incomplete.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/dot_incomplete.exp index 79d974563b3..0668e65aaf1 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/dot_incomplete.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/dot_incomplete.exp @@ -1,11 +1,3 @@ -warning[W09002]: unused variable - ┌─ tests/move_2024/parser/dot_incomplete.move:11:13 - │ -11 │ fun foo(s: AnotherStruct) { - │ ^ Unused parameter 's'. Consider removing or prefixing with an underscore: '_s' - │ - = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - error[E01002]: unexpected token ┌─ tests/move_2024/parser/dot_incomplete.move:12:23 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.exp index 3565b482bc8..5e5bfec29dd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.exp @@ -7,17 +7,17 @@ error[E03013]: positional call mismatch 26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions -error[E04016]: too few arguments +error[E03010]: unbound field ┌─ tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.move:26:13 │ 26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Missing binding for field 'f' in '0x42::M::Bar' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unbound field '0' in '0x42::M::Bar' -error[E03010]: unbound field +error[E04016]: too few arguments ┌─ tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.move:26:13 │ 26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unbound field '0' in '0x42::M::Bar' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Missing binding for field 'f' in '0x42::M::Bar' error[E03013]: positional call mismatch ┌─ tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.move:26:21 @@ -28,12 +28,6 @@ error[E03013]: positional call mismatch 26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; │ ^^^^^^^^^^^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions -error[E04016]: too few arguments - ┌─ tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.move:26:21 - │ -26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; - │ ^^^^^^^^^^^^^^ Missing binding for field 'f' in '0x42::M::Bar' - error[E03010]: unbound field ┌─ tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.move:26:21 │ @@ -46,3 +40,9 @@ error[E04010]: cannot infer type 26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; │ ^^^^^^^^^^^^^^ Could not infer this type. Try adding an annotation +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/invalid_positional_struct_unpack_deeply_nested.move:26:21 + │ +26 │ let Bar(Foo(Bar(Foo(x, y)), z)) = y; + │ ^^^^^^^^^^^^^^ Missing binding for field 'f' in '0x42::M::Bar' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity.move index 795e1d4a164..dd4553b23a5 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity.move @@ -3,8 +3,8 @@ module 0x42::M { fun t(cond: bool) { let _: u64 = 1 + if (cond) 0 else 10 + 10; - let _: bool = true || if (cond) false else 10 == 10; - let _: bool = if (cond) 10 else 'a: { 10 } == 10; + let _: bool = true || if (cond) false else 11 == 10; + let _: bool = if (cond) 10 else 'a: { 11 } == 10; let _: u64 = if (cond) 0 else 'a: { 10 } + 1; } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp index a155e9d7487..6132dd17b75 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp @@ -1,12 +1,30 @@ +error[E04005]: expected a single type + ┌─ tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.move:13:9 + │ +13 │ if (cond) 'a: { s1 }.f else s2.f + │ ^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Invalid dot access + │ Expected a single type, but found expression list type: '()' + error[E04007]: incompatible types ┌─ tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.move:13:9 │ 13 │ if (cond) 'a: { s1 }.f else s2.f │ ^^^^^^^^^^^^^^^^^^^^ │ │ │ - │ │ Found: '0x42::M::S'. It is not compatible with the other type. - │ Incompatible branches - │ Found: '()'. It is not compatible with the other type. + │ │ Given: '0x42::M::S' + │ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ Expected: '()' + +error[E04009]: expected specific type + ┌─ tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.move:13:9 + │ +13 │ if (cond) 'a: { s1 }.f else s2.f + │ ^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Unbound field 'f' + │ Expected a struct type in the current module but got: '()' error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.move:13:32 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_typing_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_typing_invalid.exp index c89ea5aa9da..c97e1001347 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_typing_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_typing_invalid.exp @@ -2,13 +2,13 @@ error[E04007]: incompatible types ┌─ tests/move_2024/parser/labeled_control_exp_associativity_typing_invalid.move:12:9 │ 7 │ fun bar(): u64 { 0 } - │ --- Found: 'u64'. It is not compatible with the other type. + │ --- Given: 'u64' · 12 │ if (cond) bar() + 1; │ ^^^^^^^^^^^^^^^^^^^ │ │ - │ Incompatible branches - │ Found: '()'. It is not compatible with the other type. + │ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ Expected: '()' error[E04003]: built-in operation not supported ┌─ tests/move_2024/parser/labeled_control_exp_associativity_typing_invalid.move:15:9 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_unreachable_code.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_unreachable_code.exp index 30ba7a8a34d..cfa3dece29e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_unreachable_code.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_unreachable_code.exp @@ -6,11 +6,3 @@ warning[W09005]: dead or unreachable code │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09005]: dead or unreachable code - ┌─ tests/move_2024/parser/labeled_control_exp_associativity_unreachable_code.move:12:9 - │ -12 │ 1 + 'a: loop foo(); - │ ^^^^^^^^^^^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp index 26fd1761d6a..912691a866f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp @@ -8,5 +8,5 @@ error[E01002]: unexpected token ┌─ tests/move_2024/parser/mut_field_pun_invalid_assign.move:6:13 │ 6 │ S { mut f } = s; - │ ^ Expected a field expression + │ ^ Unexpected 'mut'. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp index be224056bef..3e0386ef289 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp @@ -8,5 +8,5 @@ error[E01002]: unexpected token ┌─ tests/move_2024/parser/mut_field_pun_invalid_pack.move:6:13 │ 6 │ S { mut f } - │ ^ Expected a field expression + │ ^ Unexpected 'mut'. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/pattern_ellipsis_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/pattern_ellipsis_invalid.exp index e8ca2956b17..0de9d7dae4c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/pattern_ellipsis_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/pattern_ellipsis_invalid.exp @@ -8,5 +8,5 @@ error[E01002]: unexpected token ┌─ tests/move_2024/parser/pattern_ellipsis_invalid.move:10:13 │ 10 │ .. - │ ^ Expected a call argument expression + │ ^ Unexpected '..'. Expected a call argument expression diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp index 02bd5b07c61..13a9cbb0c80 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp @@ -2,7 +2,7 @@ error[E01002]: unexpected token ┌─ tests/move_2024/parser/positional_struct_fields_keyword_field.move:3:23 │ 3 │ public struct Foo(fun) - │ ^ Expected a type + │ ^ Unexpected 'fun'. Expected a type error[E01002]: unexpected token ┌─ tests/move_2024/parser/positional_struct_fields_keyword_field.move:3:26 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parsing/clever_errors_raw_abort.move b/external-crates/move/crates/move-compiler/tests/move_2024/parsing/clever_errors_raw_abort.move new file mode 100644 index 00000000000..b12ba9f501c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parsing/clever_errors_raw_abort.move @@ -0,0 +1,40 @@ +#[allow(dead_code)] +module 0x42::a; + +fun f() { + abort +} + +fun f1(): u64 { + abort; + 1 + 1 +} + +fun f2(): u64 { + 1 + 2; + abort; + 1 + 1 +} + +fun f3(): u64 { + 1 + abort; + 1 + 1 +} + +fun f4(): u64 { + abort abort; + 1 + 1 +} + +#[allow(unused_trailing_semi)] +fun f5() { + abort; +} + +fun f6() { + assert!(abort); +} + +fun f7(v: u64) { + if (v > 100) abort +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parsing/expr_abort_missing_value.move b/external-crates/move/crates/move-compiler/tests/move_2024/parsing/expr_abort_missing_value.move new file mode 100644 index 00000000000..3edcf78e1e9 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parsing/expr_abort_missing_value.move @@ -0,0 +1,5 @@ +module 0x42::M { + fun f(v: u64) { + if (v > 100) abort + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/eq_refs_struct_invalid_no_drop.exp b/external-crates/move/crates/move-compiler/tests/move_2024/typing/eq_refs_struct_invalid_no_drop.exp index 3983077c574..4935e9b839d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/typing/eq_refs_struct_invalid_no_drop.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/eq_refs_struct_invalid_no_drop.exp @@ -83,77 +83,77 @@ error[E05001]: ability constraint not satisfied 26 │ a == b && b == c && a == c │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:14 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 25 │ public fun test_9(a: S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'a' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 26 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:19 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 25 │ public fun test_9(a: S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'b' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 26 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:24 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 25 │ public fun test_9(a: S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'c' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 26 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:14 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 25 │ public fun test_9(a: S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'a' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 26 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:19 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 25 │ public fun test_9(a: S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'b' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 26 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:24 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 25 │ public fun test_9(a: S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'c' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 26 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E05001]: ability constraint not satisfied ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:26:29 @@ -188,19 +188,8 @@ error[E05001]: ability constraint not satisfied 30 │ a == b && b == c && a == c │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:30:14 - │ - 3 │ public struct S has copy {} - │ - To satisfy the constraint, the 'drop' ability would need to be added here - · -29 │ public fun test_10(a: S, b: S, c: &S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' -30 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' - error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:30:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:30:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -210,10 +199,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 30 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:30:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:30:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -223,32 +212,32 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'b' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 30 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:9 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:30:14 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · -33 │ public fun test_11(a: S, b: S, c: &mut S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' -34 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' +29 │ public fun test_10(a: S, b: S, c: &S): bool { + │ - The type '0x42::a::S' does not have the ability 'drop' +30 │ a == b && b == c && a == c + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:14 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 33 │ public fun test_11(a: S, b: S, c: &mut S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - The type '0x42::a::S' does not have the ability 'drop' 34 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -258,10 +247,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 34 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -271,10 +260,21 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'b' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 34 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return + +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:34:14 + │ + 3 │ public struct S has copy {} + │ - To satisfy the constraint, the 'drop' ability would need to be added here + · +33 │ public fun test_11(a: S, b: S, c: &mut S): bool { + │ - The type '0x42::a::S' does not have the ability 'drop' +34 │ a == b && b == c && a == c + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:38:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:38:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -284,10 +284,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 38 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:38:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:38:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -297,7 +297,7 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'c' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 38 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E05001]: ability constraint not satisfied ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:38:29 @@ -322,7 +322,7 @@ error[E05001]: ability constraint not satisfied │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:42:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:42:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -332,10 +332,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 42 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:46:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:46:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -345,10 +345,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 46 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:50:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:50:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -358,10 +358,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 50 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:50:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:50:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -371,7 +371,7 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'c' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 50 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E05001]: ability constraint not satisfied ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:50:29 @@ -396,7 +396,7 @@ error[E05001]: ability constraint not satisfied │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:54:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:54:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -406,10 +406,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 54 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:58:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:58:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -419,58 +419,58 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'a' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 58 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:19 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 61 │ public fun test_18(a: &S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'b' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 62 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:24 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 61 │ public fun test_18(a: &S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 62 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:19 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 61 │ public fun test_18(a: &S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'b' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 62 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:62:24 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 61 │ public fun test_18(a: &S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 62 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:66:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:66:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -480,10 +480,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'b' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 66 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:70:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:70:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -493,10 +493,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'b' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 70 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:74:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:74:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -506,10 +506,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 74 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:78:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:78:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -519,58 +519,58 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 78 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:19 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 81 │ public fun test_27(a: &mut S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'b' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns 82 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E05001]: ability constraint not satisfied - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:24 +error[E06001]: unused value without 'drop' + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 81 │ public fun test_27(a: &mut S, b: S, c: S): bool { - │ - The type '0x42::a::S' does not have the ability 'drop' + │ - - The type '0x42::a::S' does not have the ability 'drop' + │ │ + │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 82 │ a == b && b == c && a == c - │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:19 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 81 │ public fun test_27(a: &mut S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'b' might still contain a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 82 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' -error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:26 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:82:24 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here · 81 │ public fun test_27(a: &mut S, b: S, c: S): bool { - │ - - The type '0x42::a::S' does not have the ability 'drop' - │ │ - │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns + │ - The type '0x42::a::S' does not have the ability 'drop' 82 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^ '==' requires the 'drop' ability as the value is consumed. Try borrowing the values with '&' first.' error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:86:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:86:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -580,10 +580,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'b' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 86 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:90:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:90:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -593,10 +593,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'b' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 90 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:94:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:94:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -606,10 +606,10 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 94 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return error[E06001]: unused value without 'drop' - ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:98:26 + ┌─ tests/move_2024/typing/eq_refs_struct_invalid_no_drop.move:98:9 │ 3 │ public struct S has copy {} │ - To satisfy the constraint, the 'drop' ability would need to be added here @@ -619,5 +619,5 @@ error[E06001]: unused value without 'drop' │ │ │ The parameter 'c' still contains a value. The value does not have the 'drop' ability and must be consumed before the function returns 98 │ a == b && b == c && a == c - │ ^^ Invalid return + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid return diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/invalid_deprecation_attributes.exp b/external-crates/move/crates/move-compiler/tests/move_2024/typing/invalid_deprecation_attributes.exp index 520679f2275..5a19cba61e4 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/typing/invalid_deprecation_attributes.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/invalid_deprecation_attributes.exp @@ -26,7 +26,7 @@ error[E01002]: unexpected token ┌─ tests/move_2024/typing/invalid_deprecation_attributes.move:8:18 │ 8 │ #[deprecated(b"This is a deprecated function")] - │ ^ Expected attribute + │ ^ Unexpected ''. Expected attribute error[E10004]: invalid usage of known attribute ┌─ tests/move_2024/typing/invalid_deprecation_attributes.move:11:7 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/let_mut_macro_return.exp b/external-crates/move/crates/move-compiler/tests/move_2024/typing/let_mut_macro_return.exp index ef0562c047b..8830b43bb6a 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/typing/let_mut_macro_return.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/let_mut_macro_return.exp @@ -8,19 +8,14 @@ warning[W09012]: unused 'mut' modifiers │ = This warning can be suppressed with '#[allow(unused_let_mut)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09005]: dead or unreachable code - ┌─ tests/move_2024/typing/let_mut_macro_return.move:7:13 - │ -7 │ i = i + 1; - │ ^^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - warning[W09005]: dead or unreachable code ┌─ tests/move_2024/typing/let_mut_macro_return.move:16:35 │ + 7 │ i = i + 1; + │ --------- Unreachable code. This statement (and any following statements) will not be executed. + · 16 │ 'a: { for_each!(0, 1, |_| return 'a) } - │ ^^^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ ^^^^^^^^^ Any code after this expression will not be reached │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.exp b/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.exp index 42ecdc0db3c..bf05af2a310 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.exp @@ -23,17 +23,9 @@ error[E05001]: ability constraint not satisfied 9 │ macro fun baz<$T>(): NeedsCopy<$T> { abort 0 } │ ^^^^^^^^^^^^^ 'copy' constraint not satisfied · -18 │ baz!(); // TODO do not complain about dead code? +18 │ baz!() │ ---- The type 'a::m::None' does not have the ability 'copy' -warning[W09005]: dead or unreachable code - ┌─ tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move:9:42 - │ -9 │ macro fun baz<$T>(): NeedsCopy<$T> { abort 0 } - │ ^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - error[E05001]: ability constraint not satisfied ┌─ tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move:13:9 │ @@ -49,3 +41,14 @@ error[E05001]: ability constraint not satisfied │ │ The type 'a::m::None' does not have the ability 'copy' │ 'copy' constraint not satisfied +error[E04007]: incompatible types + ┌─ tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move:18:9 + │ + 9 │ macro fun baz<$T>(): NeedsCopy<$T> { abort 0 } + │ ------------- Given: 'a::m::NeedsCopy' + · +17 │ fun t2() { + │ -- Expected: '()' +18 │ baz!() + │ ^^^^^^^^^^^^ Invalid return expression + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move b/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move index 63a5aa7d2fc..13e88671fbd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/macros_types_checked_invalid_constraints_simple.move @@ -15,7 +15,7 @@ module a::m { } fun t2() { - baz!(); // TODO do not complain about dead code? + baz!() } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.exp b/external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.exp new file mode 100644 index 00000000000..af549552af0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.exp @@ -0,0 +1,12 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/typing/named_block_invalid_if.move:4:5 + │ +4 │ ╭ 'a: { +5 │ │ if (cond) { return 'a 5 } + │ │ ------------------------- + │ │ │ │ + │ │ │ Found: integer. It is not compatible with the other type. + │ │ Found: '()'. It is not compatible with the other type. +6 │ │ } + │ ╰─────^ Invalid named block + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.move b/external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.move new file mode 100644 index 00000000000..005d5a12ced --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/typing/named_block_invalid_if.move @@ -0,0 +1,7 @@ +module 0x42::m; + +fun test(cond: bool): u64 { + 'a: { + if (cond) { return 'a 5 } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/control_flow/while_after_while.move b/external-crates/move/crates/move-compiler/tests/move_check/control_flow/while_after_while.move new file mode 100644 index 00000000000..9f3a5e22d4d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/control_flow/while_after_while.move @@ -0,0 +1,6 @@ +module 0x42::m { + fun main() { + while (true) { }; + while (true) { }; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/duplicate_alias.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/duplicate_alias.exp index 900bc7b3579..2cdce394ac6 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/duplicate_alias.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/duplicate_alias.exp @@ -1,11 +1,3 @@ -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/expansion/duplicate_alias.move:8:19 - │ -7 │ use 0x2::X as Z; - │ - Alias previously defined here -8 │ use 0x2::Y as Z; - │ ^ Duplicate module alias 'Z'. Module aliases must be unique within a given namespace - warning[W09001]: unused alias ┌─ tests/move_check/expansion/duplicate_alias.move:8:19 │ @@ -14,3 +6,11 @@ warning[W09001]: unused alias │ = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/expansion/duplicate_alias.move:8:19 + │ +7 │ use 0x2::X as Z; + │ - Alias previously defined here +8 │ use 0x2::Y as Z; + │ ^ Duplicate module alias 'Z'. Module aliases must be unique within a given namespace + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_local_name.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_local_name.exp index a5ee675ddbe..3a1b0730e81 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_local_name.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_local_name.exp @@ -28,12 +28,6 @@ error[E03005]: unbound unscoped name 15 │ F { No }; │ ^^ Unbound constant 'No' -error[E03011]: invalid use of reserved name - ┌─ tests/move_check/expansion/invalid_local_name.move:23:13 - │ -23 │ let vector; - │ ^^^^^^ Invalid variable name 'vector'. 'vector' is restricted and cannot be used to name a variable - warning[W09002]: unused variable ┌─ tests/move_check/expansion/invalid_local_name.move:23:13 │ @@ -42,3 +36,9 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E03011]: invalid use of reserved name + ┌─ tests/move_check/expansion/invalid_local_name.move:23:13 + │ +23 │ let vector; + │ ^^^^^^ Invalid variable name 'vector'. 'vector' is restricted and cannot be used to name a variable + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp index f198f83f1b3..7a7b36c26de 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp @@ -17,7 +17,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.move:5:9 │ 5 │ foo() = 0; - │ ^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_mdot_no_struct.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_mdot_no_struct.exp index 314137b0ee3..5b62308ca81 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_mdot_no_struct.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_mdot_no_struct.exp @@ -14,7 +14,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/expansion/invalid_unpack_assign_mdot_no_struct.move:4:9 │ 4 │ Self::f() = 0; - │ ^^^^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp index 37e07fee6ff..5a4d3632028 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp @@ -20,7 +20,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/expansion/mdot_with_non_address_exp.move:17:9 │ 17 │ foo().bar().X::bar() - │ ^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp index 0366c61028b..91feb1a7f8d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp @@ -2,7 +2,7 @@ error[E01002]: unexpected token ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:22 │ 4 │ let _s = S { let x = 0; x }; - │ ^ Expected a field expression + │ ^ Unexpected 'let'. Expected a field expression error[E01002]: unexpected token ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:31 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp index 22354ac9476..6ab6d6071f4 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp @@ -8,7 +8,7 @@ error[E01002]: unexpected token ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:4:22 │ 4 │ let _s = S { false }; - │ ^ Expected a field expression + │ ^ Unexpected 'false'. Expected a field expression error[E04016]: too few arguments ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:5:18 @@ -20,5 +20,5 @@ error[E01002]: unexpected token ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:5:22 │ 5 │ let _s = S { 0 }; - │ ^ Expected a field expression + │ ^ Unexpected ''. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp index 727a0505651..02c9e5fd4ac 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp @@ -32,14 +32,6 @@ error[E01002]: unexpected token │ Unexpected 'f' │ Expected ';' -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:8:18 - │ -8 │ let _g = G (); - │ ^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E03013]: positional call mismatch ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:8:18 │ @@ -49,9 +41,17 @@ error[E03013]: positional call mismatch 8 │ let _g = G (); │ ^^^^ Invalid struct instantiation. Named struct declarations require named instantiations +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:8:18 + │ +8 │ let _g = G (); + │ ^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + error[E01002]: unexpected token ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:9:22 │ 9 │ let _g = G { {} }; - │ ^ Expected a field expression + │ ^ Unexpected '{'. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp index 34687fe6788..df5c5a6921a 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/expansion/type_arguments_on_field_access.move:6:9 │ 6 │ x.f; - │ ^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp index ec26e6b5c07..848a91f9959 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp @@ -1,9 +1,3 @@ -error[E04016]: too few arguments - ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:9 - │ -4 │ S { let f = 0; } = S { f: 0 }; - │ ^^^^^^^^^^^^^ Missing argument for field 'f' in '0x42::M::S' - error[E05001]: ability constraint not satisfied ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:9 │ @@ -16,11 +10,17 @@ error[E05001]: ability constraint not satisfied │ Cannot ignore values without the 'drop' ability. The value must be used │ The type '0x42::M::S' does not have the ability 'drop' +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:9 + │ +4 │ S { let f = 0; } = S { f: 0 }; + │ ^^^^^^^^^^^^^ Missing argument for field 'f' in '0x42::M::S' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:13 │ 4 │ S { let f = 0; } = S { f: 0 }; - │ ^ Expected a field expression + │ ^ Unexpected 'let'. Expected a field expression error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:22 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp index e9971fb374a..743f5ded110 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp @@ -8,5 +8,5 @@ error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_block_single_expr.move:4:13 │ 4 │ S { 0 } = S { f: 0 }; - │ ^ Expected a field expression + │ ^ Unexpected ''. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp index c7480d4407d..9f8fa6ab7db 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp @@ -1,11 +1,3 @@ -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 - │ -6 │ S ( f ) = S { f: 0 }; - │ ^^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E03013]: positional call mismatch ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 │ @@ -15,11 +7,13 @@ error[E03013]: positional call mismatch 6 │ S ( f ) = S { f: 0 }; │ ^^^^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions -error[E04016]: too few arguments +error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 │ 6 │ S ( f ) = S { f: 0 }; - │ ^^^^^^^ Missing assignment for field 'f' in '0x42::M::S' + │ ^^^^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. error[E03010]: unbound field ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 @@ -27,6 +21,12 @@ error[E03010]: unbound field 6 │ S ( f ) = S { f: 0 }; │ ^^^^^^^ Unbound field '0' in '0x42::M::S' +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 + │ +6 │ S ( f ) = S { f: 0 }; + │ ^^^^^^^ Missing assignment for field 'f' in '0x42::M::S' + warning[W09002]: unused variable ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:8:13 │ @@ -52,14 +52,6 @@ error[E01002]: unexpected token │ Unexpected 'f' │ Expected ';' -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:11:9 - │ -11 │ G () = G {}; - │ ^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E03013]: positional call mismatch ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:11:9 │ @@ -69,9 +61,17 @@ error[E03013]: positional call mismatch 11 │ G () = G {}; │ ^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:11:9 + │ +11 │ G () = G {}; + │ ^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:12:12 │ 12 │ G {{}} = G{}; - │ ^ Expected a field expression + │ ^ Unexpected '{'. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_function.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_function.exp index 76797512c77..2611d1f02c8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_function.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_function.exp @@ -6,6 +6,14 @@ error[E02001]: duplicate declaration, item, or annotation 10 │ fun u() { │ ^ Duplicate module member or alias 'u'. Top level names in a namespace must be unique +warning[W09001]: unused alias + ┌─ tests/move_check/expansion/use_function_same_name_as_function.move:17:22 + │ +17 │ use 0x2::X::u as bar; + │ ^^^ Unused 'use' of alias 'bar'. Consider removing it + │ + = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/expansion/use_function_same_name_as_function.move:17:22 │ @@ -15,11 +23,3 @@ error[E02001]: duplicate declaration, item, or annotation 17 │ use 0x2::X::u as bar; │ ^^^ Duplicate module member or alias 'bar'. Top level names in a namespace must be unique -warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_function_same_name_as_function.move:17:22 - │ -17 │ use 0x2::X::u as bar; - │ ^^^ Unused 'use' of alias 'bar'. Consider removing it - │ - = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_struct.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_struct.exp index 706ae484b97..f3a1e75bb5d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_struct.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_function_same_name_as_struct.exp @@ -12,14 +12,6 @@ error[E02010]: invalid name 10 │ struct u {} │ ^ Invalid struct name 'u'. Struct names must start with 'A'..'Z' -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/expansion/use_function_same_name_as_struct.move:15:22 - │ -14 │ struct Bar {} - │ --- Alias previously defined here -15 │ use 0x2::X::u as Bar; - │ ^^^ Duplicate module member or alias 'Bar'. Top level names in a namespace must be unique - warning[W09001]: unused alias ┌─ tests/move_check/expansion/use_function_same_name_as_struct.move:15:22 │ @@ -28,3 +20,11 @@ warning[W09001]: unused alias │ = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/expansion/use_function_same_name_as_struct.move:15:22 + │ +14 │ struct Bar {} + │ --- Alias previously defined here +15 │ use 0x2::X::u as Bar; + │ ^^^ Duplicate module member or alias 'Bar'. Top level names in a namespace must be unique + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_inner_scope_duplicates.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_inner_scope_duplicates.exp index c8e1d655a89..8427a46e482 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_inner_scope_duplicates.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_inner_scope_duplicates.exp @@ -1,3 +1,11 @@ +warning[W09001]: unused alias + ┌─ tests/move_check/expansion/use_inner_scope_duplicates.move:13:43 + │ +13 │ use 0x2::M::{check as foo, num as foo}; + │ ^^^ Unused 'use' of alias 'foo'. Consider removing it + │ + = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/expansion/use_inner_scope_duplicates.move:13:43 │ @@ -7,10 +15,10 @@ error[E02001]: duplicate declaration, item, or annotation │ Alias previously defined here warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_inner_scope_duplicates.move:13:43 + ┌─ tests/move_check/expansion/use_inner_scope_duplicates.move:15:23 │ -13 │ use 0x2::M::{check as foo, num as foo}; - │ ^^^ Unused 'use' of alias 'foo'. Consider removing it +15 │ use 0x2::M as N; + │ ^ Unused 'use' of alias 'N'. Consider removing it │ = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') @@ -22,11 +30,3 @@ error[E02001]: duplicate declaration, item, or annotation 15 │ use 0x2::M as N; │ ^ Duplicate module alias 'N'. Module aliases must be unique within a given namespace -warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_inner_scope_duplicates.move:15:23 - │ -15 │ use 0x2::M as N; - │ ^ Unused 'use' of alias 'N'. Consider removing it - │ - = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_function.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_function.exp index 5a666e062ee..5c30551fa02 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_function.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_function.exp @@ -16,6 +16,14 @@ error[E02001]: duplicate declaration, item, or annotation 11 │ fun U2() {} │ ^^ Duplicate module member or alias 'U2'. Top level names in a namespace must be unique +warning[W09001]: unused alias + ┌─ tests/move_check/expansion/use_struct_same_name_as_function.move:15:18 + │ +15 │ use 0x2::X::{R, R as R2}; + │ ^ Unused 'use' of alias 'R'. Consider removing it + │ + = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/expansion/use_struct_same_name_as_function.move:15:18 │ @@ -26,10 +34,10 @@ error[E02001]: duplicate declaration, item, or annotation │ ^ Duplicate module member or alias 'R'. Top level names in a namespace must be unique warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_struct_same_name_as_function.move:15:18 + ┌─ tests/move_check/expansion/use_struct_same_name_as_function.move:15:26 │ 15 │ use 0x2::X::{R, R as R2}; - │ ^ Unused 'use' of alias 'R'. Consider removing it + │ ^^ Unused 'use' of alias 'R2'. Consider removing it │ = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') @@ -42,11 +50,3 @@ error[E02001]: duplicate declaration, item, or annotation 15 │ use 0x2::X::{R, R as R2}; │ ^^ Duplicate module member or alias 'R2'. Top level names in a namespace must be unique -warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_struct_same_name_as_function.move:15:26 - │ -15 │ use 0x2::X::{R, R as R2}; - │ ^^ Unused 'use' of alias 'R2'. Consider removing it - │ - = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_struct.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_struct.exp index b60cc7403f0..2480aa139eb 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_struct.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/use_struct_same_name_as_struct.exp @@ -16,6 +16,14 @@ error[E02001]: duplicate declaration, item, or annotation 11 │ struct U2 {} │ ^^ Duplicate module member or alias 'U2'. Top level names in a namespace must be unique +warning[W09001]: unused alias + ┌─ tests/move_check/expansion/use_struct_same_name_as_struct.move:15:18 + │ +15 │ use 0x2::X::{R, R as R2}; + │ ^ Unused 'use' of alias 'R'. Consider removing it + │ + = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/expansion/use_struct_same_name_as_struct.move:15:18 │ @@ -26,10 +34,10 @@ error[E02001]: duplicate declaration, item, or annotation │ ^ Duplicate module member or alias 'R'. Top level names in a namespace must be unique warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_struct_same_name_as_struct.move:15:18 + ┌─ tests/move_check/expansion/use_struct_same_name_as_struct.move:15:26 │ 15 │ use 0x2::X::{R, R as R2}; - │ ^ Unused 'use' of alias 'R'. Consider removing it + │ ^^ Unused 'use' of alias 'R2'. Consider removing it │ = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') @@ -42,11 +50,3 @@ error[E02001]: duplicate declaration, item, or annotation 15 │ use 0x2::X::{R, R as R2}; │ ^^ Duplicate module member or alias 'R2'. Top level names in a namespace must be unique -warning[W09001]: unused alias - ┌─ tests/move_check/expansion/use_struct_same_name_as_struct.move:15:26 - │ -15 │ use 0x2::X::{R, R as R2}; - │ ^^ Unused 'use' of alias 'R2'. Consider removing it - │ - = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/dot_call.exp b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/dot_call.exp index fb1bd37f8a5..ed14de5c2ff 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/dot_call.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/dot_call.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:4:5 │ 4 │ public use fun imm as S.f; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:13:9 │ 13 │ use fun mut as S.g; - │ ^^^^^^^^^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -18,7 +18,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:14:9 │ 14 │ s.imm(); - │ ^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -26,7 +26,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:15:9 │ 15 │ s.f(); - │ ^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -34,7 +34,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:16:9 │ 16 │ s.mut(); - │ ^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -42,7 +42,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:17:9 │ 17 │ s.g(); - │ ^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -50,7 +50,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/dot_call.move:18:9 │ 18 │ s.val(); - │ ^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_call.exp b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_call.exp index e4648fa6d5f..cca06c20af8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_call.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_call.exp @@ -14,7 +14,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_call.move:4:12 │ 4 │ foo!(|| ()) - │ ^ 'macro' functions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'macro' functions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition.exp b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition.exp index 707e8546f53..17219b065cb 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_definition.move:2:12 │ 2 │ public macro fun do($f: || ()) { $f() } - │ ^^^^^ 'macro' functions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ 'macro' functions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_definition.move:2:38 │ 2 │ public macro fun do($f: || ()) { $f() } - │ ^^^^ lambda expressions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^ lambda expressions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition_with_usage.exp b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition_with_usage.exp index 3a965f8c7d3..7c953664841 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition_with_usage.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_definition_with_usage.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_definition_with_usage.move:2:12 │ 2 │ public macro fun do($f: || ()) { $f() } - │ ^^^^^ 'macro' functions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ 'macro' functions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_definition_with_usage.move:2:38 │ 2 │ public macro fun do($f: || ()) { $f() } - │ ^^^^ lambda expressions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^ lambda expressions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -18,7 +18,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_definition_with_usage.move:4:24 │ 4 │ public fun t() { do!(|| q() ) } - │ ^ 'macro' functions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'macro' functions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_lambda.exp b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_lambda.exp index 13484c9d8ba..d37d770411e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_lambda.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/macro_lambda.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_lambda.move:2:17 │ 2 │ fun tfun(_: |u64| u64) {} - │ ^^^^^^^^^ 'macro' functions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^ 'macro' functions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/macro_lambda.move:4:17 │ 4 │ let _ = |x| x; - │ ^^^^^ lambda expressions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ lambda expressions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/public_package.exp b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/public_package.exp index 1f1f89e7b48..f09729eb5ed 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/public_package.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/feature_gate/public_package.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/feature_gate/public_package.move:2:5 │ 2 │ public(package) fun foo(): u64 { 0 } - │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/dot_incomplete.move b/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/dot_incomplete.move index 58d90004aaa..09595773d7b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/dot_incomplete.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/dot_incomplete.move @@ -9,7 +9,7 @@ module a::m { } fun foo() { - let _s = AnotherStruct { another_field: SomeStruct { some_field: 0 } }; + let s = AnotherStruct { another_field: SomeStruct { some_field: 0 } }; let _tmp1 = s.; // incomplete with `;` (next line should parse) let _tmp2 = s.another_field.; // incomplete with `;` (next line should parse) let _tmp3 = s.another_field. // incomplete without `;` (unexpected `let`) diff --git a/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/named_struct_autocomplete.ide.exp b/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/named_struct_autocomplete.ide.exp index e91de143d99..2a3e88ee2ac 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/named_struct_autocomplete.ide.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/ide_mode/named_struct_autocomplete.ide.exp @@ -59,6 +59,17 @@ note[I15006]: IDE path autocomplete = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' = type params: +note[I15006]: IDE path autocomplete + ┌─ tests/move_check/ide_mode/named_struct_autocomplete.move:13:21 + │ +13 │ let _tmp1 = _s.; + │ ^^ Possible in-scope names + │ + = members: 'A -> a::m::A', 'B -> a::m::B', 'foo -> a::m::foo', or 'unit_test_poison -> a::m::unit_test_poison' + = modules: 'Self -> a::m' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: + note[I15001]: IDE dot autocomplete ┌─ tests/move_check/ide_mode/named_struct_autocomplete.move:13:23 │ @@ -74,6 +85,23 @@ error[E01002]: unexpected token │ Unexpected ';' │ Expected an identifier or a decimal number +note[I15006]: IDE path autocomplete + ┌─ tests/move_check/ide_mode/named_struct_autocomplete.move:14:21 + │ +14 │ let _tmp2 = _s.a.; + │ ^^ Possible in-scope names + │ + = members: 'A -> a::m::A', 'B -> a::m::B', 'foo -> a::m::foo', or 'unit_test_poison -> a::m::unit_test_poison' + = modules: 'Self -> a::m' + = addresses: 'A -> 0x41', 'B -> 0x42', 'K -> 0x19', 'M -> 0x40', 'a -> 0x44', 'b -> 0x45', 'iota -> 0x2', 'k -> 0x19', or 'std -> 0x1' + = type params: + +note[I15001]: IDE dot autocomplete + ┌─ tests/move_check/ide_mode/named_struct_autocomplete.move:14:23 + │ +14 │ let _tmp2 = _s.a.; + │ ^ Possible dot names: 'a' + note[I15001]: IDE dot autocomplete ┌─ tests/move_check/ide_mode/named_struct_autocomplete.move:14:24 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.exp b/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.exp deleted file mode 100644 index 68f174d5739..00000000000 --- a/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.exp +++ /dev/null @@ -1,12 +0,0 @@ -warning[W09004]: unnecessary trailing semicolon - ┌─ tests/move_check/liveness/loop_weirdness.move:9:43 - │ -9 │ if (my_local >= 0) { break; }; - │ -----^ - │ │ │ - │ │ Invalid trailing ';' - │ │ A trailing ';' in an expression block implicitly adds a '()' value after the semicolon. That '()' value will not be reachable - │ Any code after this expression will not be reached - │ - = This warning can be suppressed with '#[allow(unused_trailing_semi)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.move b/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.move index 669c383ab90..40f1ae97c24 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/liveness/loop_weirdness.move @@ -1,3 +1,4 @@ +#[allow(unused_trailing_semi)] module 0x8675309::M { fun t() { let x = 0; diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead.exp b/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead.exp index e1977d94514..b652e5c9f89 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead.exp @@ -14,14 +14,6 @@ warning[W09005]: dead or unreachable code │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09005]: dead or unreachable code - ┌─ tests/move_check/liveness/nested_dead.move:8:9 - │ -8 │ return - │ ^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - warning[W09005]: dead or unreachable code ┌─ tests/move_check/liveness/nested_dead.move:12:23 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.exp b/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.exp new file mode 100644 index 00000000000..1fa168625ea --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.exp @@ -0,0 +1,8 @@ +warning[W09005]: dead or unreachable code + ┌─ tests/move_check/liveness/nested_dead_single.move:3:23 + │ +3 │ loop { return abort 0 } + │ ^^^^^^^ Expected a value. Any code surrounding or after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.move b/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.move new file mode 100644 index 00000000000..c5fa45e358d --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/liveness/nested_dead_single.move @@ -0,0 +1,5 @@ +module 0x8675309::m { + fun t0() { + loop { return abort 0 } + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.exp b/external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.exp new file mode 100644 index 00000000000..c3b84db7956 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.exp @@ -0,0 +1,12 @@ +warning[W09004]: unnecessary trailing semicolon + ┌─ tests/move_check/liveness/trailing_semi_single.move:3:15 + │ +3 │ return; + │ ------^ + │ │ │ + │ │ Invalid trailing ';' + │ │ A trailing ';' in an expression block implicitly adds a '()' value after the semicolon. That '()' value will not be reachable + │ Any code after this expression will not be reached + │ + = This warning can be suppressed with '#[allow(unused_trailing_semi)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.move b/external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.move new file mode 100644 index 00000000000..216c9a37f39 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/liveness/trailing_semi_single.move @@ -0,0 +1,5 @@ +module 1::m { + fun main() { + return; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/assert_one_arg.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/assert_one_arg.exp index 4dc41013014..ed3a328682e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/assert_one_arg.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/assert_one_arg.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/assert_one_arg.move:3:9 │ 3 │ assert!(false); - │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/assert_one_arg.move:4:9 │ 4 │ assert!(0 != 1); - │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -18,7 +18,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/assert_one_arg.move:5:9 │ 5 │ assert!(x != y); - │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/duplicate_type_parameter_struct.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/duplicate_type_parameter_struct.exp index 619bd572aed..699caeb56eb 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/duplicate_type_parameter_struct.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/duplicate_type_parameter_struct.exp @@ -22,14 +22,6 @@ warning[W09006]: unused struct type parameter │ = This warning can be suppressed with '#[allow(unused_type_parameter)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:3:24 - │ -3 │ struct S2 { f: T } - │ - ^ Duplicate type parameter declared with name 'T' - │ │ - │ Type parameter previously defined here - warning[W09006]: unused struct type parameter ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:3:24 │ @@ -38,6 +30,14 @@ warning[W09006]: unused struct type parameter │ = This warning can be suppressed with '#[allow(unused_type_parameter)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:3:24 + │ +3 │ struct S2 { f: T } + │ - ^ Duplicate type parameter declared with name 'T' + │ │ + │ Type parameter previously defined here + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:3:32 │ @@ -70,14 +70,6 @@ warning[W09006]: unused struct type parameter │ = This warning can be suppressed with '#[allow(unused_type_parameter)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:5:24 - │ -5 │ struct R2 { f: T } - │ - ^ Duplicate type parameter declared with name 'T' - │ │ - │ Type parameter previously defined here - warning[W09006]: unused struct type parameter ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:5:24 │ @@ -86,6 +78,14 @@ warning[W09006]: unused struct type parameter │ = This warning can be suppressed with '#[allow(unused_type_parameter)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:5:24 + │ +5 │ struct R2 { f: T } + │ - ^ Duplicate type parameter declared with name 'T' + │ │ + │ Type parameter previously defined here + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/naming/duplicate_type_parameter_struct.move:5:32 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.exp index 1517d8e3c80..82e8512409d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:3:9 │ 3 │ 'name: { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -22,7 +22,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:11:14 │ 11 │ loop 'name: { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -36,7 +36,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:17:14 │ 17 │ loop 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -44,7 +44,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:18:18 │ 18 │ loop 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -64,7 +64,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:26:22 │ 26 │ while (cond) 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -72,7 +72,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:27:26 │ 27 │ while (cond) 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -92,7 +92,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:35:22 │ 35 │ while (cond) 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -100,7 +100,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:36:22 │ 36 │ let _x = 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -120,7 +120,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:45:14 │ 45 │ loop 'l: { - │ ^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -128,7 +128,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:46:18 │ 46 │ loop 'l: { - │ ^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -142,7 +142,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:53:9 │ 53 │ 'name: { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -156,7 +156,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:60:14 │ 60 │ loop 'name: { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -176,7 +176,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:67:14 │ 67 │ loop 'outer2: { - │ ^^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -184,7 +184,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:68:18 │ 68 │ loop 'inner2: { - │ ^^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -204,7 +204,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:76:22 │ 76 │ while (cond) 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -212,7 +212,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:77:26 │ 77 │ while (cond) 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -232,7 +232,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:85:14 │ 85 │ loop 'l: { - │ ^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -240,7 +240,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/named_blocks_invalid.move:86:18 │ 86 │ loop 'l: { - │ ^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/other_builtins_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/other_builtins_invalid.exp index ac10191d7d4..a0d57cef627 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/other_builtins_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/other_builtins_invalid.exp @@ -29,7 +29,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/other_builtins_invalid.move:6:9 │ 6 │ assert!(false); - │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -37,7 +37,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/other_builtins_invalid.move:7:9 │ 7 │ assert!(0 != 1); - │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/syntax_annotations_unsupported.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/syntax_annotations_unsupported.exp index 33b75713082..6237eb07cee 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/syntax_annotations_unsupported.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/syntax_annotations_unsupported.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/syntax_annotations_unsupported.move:6:7 │ 6 │ #[syntax(index)] - │ ^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/syntax_annotations_unsupported.move:10:7 │ 10 │ #[syntax(index)] - │ ^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -27,7 +27,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/syntax_annotations_unsupported.move:21:7 │ 21 │ #[syntax(for)] - │ ^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -35,7 +35,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/syntax_annotations_unsupported.move:25:7 │ 25 │ #[syntax(assign)] - │ ^^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -43,7 +43,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/syntax_annotations_unsupported.move:29:7 │ 29 │ #[syntax(nonsense)] - │ ^^^^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^^^^ 'syntax' methods are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_invalid_usage.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_invalid_usage.exp index 35785b3d7cb..da6d9df6753 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_invalid_usage.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_invalid_usage.exp @@ -1,11 +1,3 @@ -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/naming/type_hole_gated_invalid_usage.move:2:22 - │ -2 │ struct S { f: _ } - │ ^ '_' placeholders for type inference are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E03021]: invalid type annotation ┌─ tests/move_check/naming/type_hole_gated_invalid_usage.move:2:22 │ @@ -13,10 +5,10 @@ error[E03021]: invalid type annotation │ ^ Invalid usage of a placeholder for type inference '_'. Struct fields require fully specified types. Replace '_' with a specific type or consider adding a new type parameter error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/naming/type_hole_gated_invalid_usage.move:3:16 + ┌─ tests/move_check/naming/type_hole_gated_invalid_usage.move:2:22 │ -3 │ fun foo(_: _) {} - │ ^ '_' placeholders for type inference are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature +2 │ struct S { f: _ } + │ ^ '_' placeholders for type inference are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -28,3 +20,11 @@ error[E03021]: invalid type annotation │ = Only 'macro' functions can use '_' in their signatures +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/naming/type_hole_gated_invalid_usage.move:3:16 + │ +3 │ fun foo(_: _) {} + │ ^ '_' placeholders for type inference are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_valid_usage.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_valid_usage.exp index 1664af909a5..afc0bbf38cf 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_valid_usage.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/type_hole_gated_valid_usage.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/type_hole_gated_valid_usage.move:3:23 │ 3 │ let v: vector<_> = vector[0]; - │ ^ '_' placeholders for type inference are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ '_' placeholders for type inference are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/unknown_assertion_annotation.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/unknown_assertion_annotation.exp index f49fb6e08ba..c4b7383e0e8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/unknown_assertion_annotation.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/unknown_assertion_annotation.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/unknown_assertion_annotation.move:2:7 │ 2 │ #[error] - │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/var_as_fun_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/naming/var_as_fun_invalid.exp index 1c201d01195..f6016a643db 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/var_as_fun_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/var_as_fun_invalid.exp @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/naming/var_as_fun_invalid.move:4:9 │ 4 │ var(); - │ ^^^^^ lambda expressions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ lambda expressions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_infix_and_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_infix_and_postfix.exp index 3c85f3370b2..b605a12fc73 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_infix_and_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_infix_and_postfix.exp @@ -1,11 +1,3 @@ -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/ability_modifier_infix_and_postfix.move:5:34 - │ -5 │ struct Foo has copy, drop {} has store; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E01003]: invalid modifier ┌─ tests/move_check/parser/ability_modifier_infix_and_postfix.move:5:34 │ @@ -14,3 +6,11 @@ error[E01003]: invalid modifier │ │ │ Ability declaration previously given here +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/ability_modifier_infix_and_postfix.move:5:34 + │ +5 │ struct Foo has copy, drop {} has store; + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp index c7b5a24b547..ffe0610baf4 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp @@ -8,7 +8,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.move:4:23 │ 4 │ struct Foo has {} has copy; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp index a47a243ca29..227eec63936 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_postfix_missing_commas.move:5:19 │ 5 │ struct Foo {} has store copy; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_semi_multiple_structs.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_semi_multiple_structs.exp index 7f5b115d627..ce8542bfb93 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_semi_multiple_structs.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_semi_multiple_structs.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_postfix_missing_semi_multiple_structs.move:5:19 │ 5 │ struct Foo {} has store - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp index 3334f435cf6..da4345cb7fe 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.move:5:19 │ 5 │ struct Foo {} has - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp index e29baaf3fce..aea73fe2dc9 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.move:5:19 │ 5 │ struct Foo {} has; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp index 9b15192721e..d86e6e13205 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_postfix_no_semi.move:5:19 │ 5 │ struct Foo {} has store - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_with_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_with_semi.exp index ace58a9edd8..150c6b26e08 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_with_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_with_semi.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifier_postfix_with_semi.move:4:19 │ 4 │ struct Foo {} has store; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp index 37587798c5d..35abb513bd7 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp @@ -1,11 +1,3 @@ -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.move:4:28 - │ -4 │ struct Foo has copy {} has; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E01003]: invalid modifier ┌─ tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.move:4:28 │ @@ -14,6 +6,14 @@ error[E01003]: invalid modifier │ │ │ Ability declaration previously given here +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.move:4:28 + │ +4 │ struct Foo has copy {} has; + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + error[E01002]: unexpected token ┌─ tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.move:4:31 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp index f7129990acc..f77298e9e09 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp @@ -8,7 +8,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.move:4:23 │ 4 │ struct Foo has {} has; - │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^ Postfix abilities are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.exp new file mode 100644 index 00000000000..341e9838953 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.exp @@ -0,0 +1,18 @@ +warning[W01004]: invalid documentation comment + ┌─ tests/move_check/parser/block_comments_inline.move:11:61 + │ +11 │ let /*comment*/s = S { /***/w, /**/x, /*comment*/y, /** doc */z }; + │ ^^^^^^^^ Documentation comment cannot be matched to a language item + +warning[W01004]: invalid documentation comment + ┌─ tests/move_check/parser/block_comments_inline.move:12:17 + │ +12 │ let S { /****/w, /**/x, /*comment*/y, /** doc */z } = /*comment*/s; + │ ^^^^ Documentation comment cannot be matched to a language item + +warning[W01004]: invalid documentation comment + ┌─ tests/move_check/parser/block_comments_inline.move:12:47 + │ +12 │ let S { /****/w, /**/x, /*comment*/y, /** doc */z } = /*comment*/s; + │ ^^^^^^^^ Documentation comment cannot be matched to a language item + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.move new file mode 100644 index 00000000000..c8290f0ba4c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/block_comments_inline.move @@ -0,0 +1,15 @@ +module 0x42::m { + + struct S { + /*comment*/ w: u64, + /*comment*/ x: u64, + /**/ y: u64, + /** doc */ z: u64, + } + + fun t(w: u64, x: u64, /*ignore*/y: u64, z:u64/**/): (u64, u64, u64, u64) { + let /*comment*/s = S { /***/w, /**/x, /*comment*/y, /** doc */z }; + let S { /****/w, /**/x, /*comment*/y, /** doc */z } = /*comment*/s; + (w, x, y, z) + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/comments_nested_unbalanced.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/comments_nested_unbalanced.exp index 8b0a03fd067..180386f798e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/comments_nested_unbalanced.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/comments_nested_unbalanced.exp @@ -2,5 +2,5 @@ warning[W01004]: invalid documentation comment ┌─ tests/move_check/parser/comments_nested_unbalanced.move:1:4 │ 1 │ /* /** /** * / */ /** */ - │ ^^ Unclosed block comment + │ ^^^ Unclosed block comment diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp index f8e6e2bde40..2a9548ff14d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp @@ -1,14 +1,32 @@ +error[E04005]: expected a single type + ┌─ tests/move_check/parser/control_exp_associativity_else_after_if_block.move:13:9 + │ +13 │ if (cond) { s1 }.f else s2.f + │ ^^^^^^^^^^^^^^^^ + │ │ + │ Invalid dot access + │ Expected a single type, but found expression list type: '()' + error[E04007]: incompatible types ┌─ tests/move_check/parser/control_exp_associativity_else_after_if_block.move:13:9 │ 7 │ fun t(cond: bool, s1: S, s2: S) { - │ - Found: '0x42::M::S'. It is not compatible with the other type. + │ - Given: '0x42::M::S' · 13 │ if (cond) { s1 }.f else s2.f │ ^^^^^^^^^^^^^^^^ │ │ - │ Incompatible branches - │ Found: '()'. It is not compatible with the other type. + │ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ Expected: '()' + +error[E04009]: expected specific type + ┌─ tests/move_check/parser/control_exp_associativity_else_after_if_block.move:13:9 + │ +13 │ if (cond) { s1 }.f else s2.f + │ ^^^^^^^^^^^^^^^^^^ + │ │ + │ Unbound field 'f' + │ Expected a struct type in the current module but got: '()' error[E01002]: unexpected token ┌─ tests/move_check/parser/control_exp_associativity_else_after_if_block.move:13:28 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_typing_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_typing_invalid.exp index 789d0a379b1..be79cfda6a9 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_typing_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_typing_invalid.exp @@ -2,13 +2,13 @@ error[E04007]: incompatible types ┌─ tests/move_check/parser/control_exp_associativity_typing_invalid.move:12:9 │ 7 │ fun bar(): u64 { 0 } - │ --- Found: 'u64'. It is not compatible with the other type. + │ --- Given: 'u64' · 12 │ if (cond) bar() + 1; │ ^^^^^^^^^^^^^^^^^^^ │ │ - │ Incompatible branches - │ Found: '()'. It is not compatible with the other type. + │ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ Expected: '()' error[E04003]: built-in operation not supported ┌─ tests/move_check/parser/control_exp_associativity_typing_invalid.move:15:9 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_unreachable_code.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_unreachable_code.exp index ccf0483509a..9fc61237e01 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_unreachable_code.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_unreachable_code.exp @@ -14,11 +14,3 @@ warning[W09005]: dead or unreachable code │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09005]: dead or unreachable code - ┌─ tests/move_check/parser/control_exp_associativity_unreachable_code.move:12:9 - │ -12 │ 1 + loop foo(); - │ ^^^^^^^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/copy_move_path.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/copy_move_path.exp index c8997f4bd5d..f0f418b6b46 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/copy_move_path.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/copy_move_path.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/copy_move_path.move:12:9 │ 12 │ copy x.y.z; - │ ^^^^ Move 2024 paths are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^ Move 2024 paths are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/copy_move_path.move:13:9 │ 13 │ move x.y.z; - │ ^^^^ Move 2024 paths are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^ Move 2024 paths are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/empty_doc_comment.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/empty_doc_comment.move new file mode 100644 index 00000000000..3fb75a3e35b --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/empty_doc_comment.move @@ -0,0 +1,16 @@ +module 0x42::m { + /* */ + struct A { } + /** **/ + struct B { } + /** */ + struct C { } + /*** */ + struct D { } + /****/ + struct E { } + /***/ + struct F { } + /**/ + struct G { } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.exp index 802e95f2600..4180c5d03a7 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.exp @@ -1,9 +1,8 @@ -error[E01002]: unexpected token - ┌─ tests/move_check/parser/expr_abort_missing_value.move:5:5 +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/expr_abort_missing_value.move:4:22 │ -5 │ } - │ ^ - │ │ - │ Unexpected '}' - │ Expected an expression term +4 │ if (v > 100) abort + │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move index 2b53c3c6bbe..b167cba1efd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move @@ -1,6 +1,6 @@ module 0x42::M { - fun f(_v: u64) { - // Aborts always require a value + fun f(v: u64) { + // Aborts always require a value if not in Move 2024 if (v > 100) abort } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_conflicting_visibility.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_conflicting_visibility.exp index 41734be93a0..b8e5ce074b3 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_conflicting_visibility.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_conflicting_visibility.exp @@ -6,14 +6,6 @@ error[E02001]: duplicate declaration, item, or annotation │ │ │ 'public' modifier previously given here -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/function_conflicting_visibility.move:2:20 - │ -2 │ public(friend) public(package) fun t0() {} - │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E02016]: invalid visibility modifier ┌─ tests/move_check/parser/function_conflicting_visibility.move:2:20 │ @@ -23,6 +15,14 @@ error[E02016]: invalid visibility modifier 11 │ public(friend) public(friend) fun s2() {} │ -------------- 'friend' visibility used here +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/function_conflicting_visibility.move:2:20 + │ +2 │ public(friend) public(package) fun t0() {} + │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/parser/function_conflicting_visibility.move:3:21 │ @@ -47,14 +47,6 @@ error[E02001]: duplicate declaration, item, or annotation │ │ │ 'public' modifier previously given here -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/function_conflicting_visibility.move:4:12 - │ -4 │ public public(package) fun t2() {} - │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E02016]: invalid visibility modifier ┌─ tests/move_check/parser/function_conflicting_visibility.move:4:12 │ @@ -64,6 +56,14 @@ error[E02016]: invalid visibility modifier 11 │ public(friend) public(friend) fun s2() {} │ -------------- 'friend' visibility used here +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/function_conflicting_visibility.move:4:12 + │ +4 │ public public(package) fun t2() {} + │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/parser/function_conflicting_visibility.move:5:21 │ @@ -113,14 +113,6 @@ error[E02001]: duplicate declaration, item, or annotation │ │ │ 'public' modifier previously given here -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/function_conflicting_visibility.move:10:21 - │ -10 │ public(package) public(package) fun s1() {} - │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E02016]: invalid visibility modifier ┌─ tests/move_check/parser/function_conflicting_visibility.move:10:21 │ @@ -129,6 +121,14 @@ error[E02016]: invalid visibility modifier 11 │ public(friend) public(friend) fun s2() {} │ -------------- 'friend' visibility used here +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/function_conflicting_visibility.move:10:21 + │ +10 │ public(package) public(package) fun s1() {} + │ ^^^^^^^^^^^^^^^ 'public(package)' is not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/parser/function_conflicting_visibility.move:11:20 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_type_extra_comma.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_type_extra_comma.exp index e39a42d045e..ef0327c7dec 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_type_extra_comma.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_type_extra_comma.exp @@ -2,5 +2,5 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/function_type_extra_comma.move:2:12 │ 2 │ fun fn<,T>() { } // Test a comma before the first type parameter - │ ^ Expected a type parameter + │ ^ Unexpected ','. Expected a type parameter diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp index db31af4e6dc..e57fd920507 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp @@ -8,7 +8,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:9:9 │ 9 │ X::S () = 0; - │ ^^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -37,5 +37,5 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:13:16 │ 13 │ X::S { 0 } = 0; - │ ^ Expected a field expression + │ ^ Unexpected ''. Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.exp index a3220c2d009..cba54510c39 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_2.move:4:9 │ 4 │ 'name { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.exp index 0d418bc960a..ed7f3f6b344 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:4:9 │ 4 │ 'name: { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -16,7 +16,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:11:14 │ 11 │ loop 'name: { - │ ^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -30,7 +30,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:17:14 │ 17 │ loop 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -38,7 +38,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:18:18 │ 18 │ loop 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -58,7 +58,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:26:22 │ 26 │ while (cond) 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -66,7 +66,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:27:26 │ 27 │ while (cond) 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -86,7 +86,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:35:22 │ 35 │ while (cond) 'outer: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -94,7 +94,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:36:22 │ 36 │ let _x = 'inner: { - │ ^^^^^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -114,7 +114,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:45:14 │ 45 │ loop 'l: { - │ ^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -122,7 +122,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/named_blocks_invalid_3.move:46:18 │ 46 │ loop 'l: { - │ ^^ Block labels are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ Block labels are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_declaration.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_declaration.exp index acd1c98736a..04730eb4980 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_declaration.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_declaration.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/positional_struct_declaration.move:4:15 │ 4 │ struct Foo(u64) - │ ^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp index 67ee81c08f3..b97065f3d62 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp @@ -1,24 +1,24 @@ -error[E13001]: feature is not supported in specified edition +error[E01003]: invalid modifier ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:5 │ 4 │ public struct Foo(fun) - │ ^^^^^^ Struct visibility modifiers are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Invalid struct declaration. Structs cannot have visibility modifiers as they are always 'public' │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + = Starting in the Move 2024 edition visibility must be annotated on struct declarations. -error[E01003]: invalid modifier +error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:5 │ 4 │ public struct Foo(fun) - │ ^^^^^^ Invalid struct declaration. Structs cannot have visibility modifiers as they are always 'public' + │ ^^^^^^ Struct visibility modifiers are not supported by current edition 'legacy'; the '2024' edition supports this feature │ - = Starting in the Move 2024 edition visibility must be annotated on struct declarations. + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:22 │ 4 │ public struct Foo(fun) - │ ^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -26,7 +26,7 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:23 │ 4 │ public struct Foo(fun) - │ ^ Expected a type + │ ^ Unexpected 'fun'. Expected a type error[E01002]: unexpected token ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:26 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_pack.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_pack.exp index da4ebc20a7d..1c74aef4ab5 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_pack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_pack.exp @@ -1,11 +1,3 @@ -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/positional_struct_pack.move:7:17 - │ -7 │ let _ = Foo(0); - │ ^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E03013]: positional call mismatch ┌─ tests/move_check/parser/positional_struct_pack.move:7:17 │ @@ -15,11 +7,13 @@ error[E03013]: positional call mismatch 7 │ let _ = Foo(0); │ ^^^^^^ Invalid struct instantiation. Named struct declarations require named instantiations -error[E04016]: too few arguments +error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/positional_struct_pack.move:7:17 │ 7 │ let _ = Foo(0); - │ ^^^^^^ Missing argument for field 'x' in '0x42::M::Foo' + │ ^^^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. error[E03010]: unbound field ┌─ tests/move_check/parser/positional_struct_pack.move:7:17 @@ -27,3 +21,9 @@ error[E03010]: unbound field 7 │ let _ = Foo(0); │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' +error[E04016]: too few arguments + ┌─ tests/move_check/parser/positional_struct_pack.move:7:17 + │ +7 │ let _ = Foo(0); + │ ^^^^^^ Missing argument for field 'x' in '0x42::M::Foo' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_unpack.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_unpack.exp index 871cc84a241..d2e089a451a 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_unpack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_unpack.exp @@ -1,11 +1,3 @@ -error[E13001]: feature is not supported in specified edition - ┌─ tests/move_check/parser/positional_struct_unpack.move:7:9 - │ -7 │ Foo(_) = x; - │ ^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. - error[E03013]: positional call mismatch ┌─ tests/move_check/parser/positional_struct_unpack.move:7:9 │ @@ -15,11 +7,13 @@ error[E03013]: positional call mismatch 7 │ Foo(_) = x; │ ^^^^^^ Invalid struct deconstruction. Named struct declarations require named deconstructions -error[E04016]: too few arguments +error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/positional_struct_unpack.move:7:9 │ 7 │ Foo(_) = x; - │ ^^^^^^ Missing assignment for field 'f' in '0x42::M::Foo' + │ ^^^^^^ Positional fields are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. error[E03010]: unbound field ┌─ tests/move_check/parser/positional_struct_unpack.move:7:9 @@ -27,3 +21,9 @@ error[E03010]: unbound field 7 │ Foo(_) = x; │ ^^^^^^ Unbound field '0' in '0x42::M::Foo' +error[E04016]: too few arguments + ┌─ tests/move_check/parser/positional_struct_unpack.move:7:9 + │ +7 │ Foo(_) = x; + │ ^^^^^^ Missing assignment for field 'f' in '0x42::M::Foo' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/return_in_binop.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/return_in_binop.exp index 16683862df1..31abf6bb334 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/return_in_binop.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/return_in_binop.exp @@ -6,11 +6,3 @@ warning[W09005]: dead or unreachable code │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -warning[W09005]: dead or unreachable code - ┌─ tests/move_check/parser/return_in_binop.move:4:9 - │ -4 │ return << 0; - │ ^^^^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_index_fail.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_index_fail.exp index b052c761786..b80240be8f0 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_index_fail.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_index_fail.exp @@ -12,6 +12,6 @@ error[E00002]: DEPRECATED. unexpected spec item 3 │ let _ = x[1]; │ ^^^^ Specification blocks are deprecated and are no longer used │ - = If this was intended to be a 'syntax' index call, consider updating your Move edition to '2024.alpha, 2024.beta' + = If this was intended to be a 'syntax' index call, consider updating your Move edition to '2024.alpha, 2024.beta, 2024' = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_lambda_fail.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_lambda_fail.exp index 5b29108bca0..83c54357e98 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_lambda_fail.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_lambda_fail.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/spec_parsing_lambda_fail.move:3:15 │ 3 │ let _ = |y| x + y; - │ ^^^^^^^^^ lambda expressions are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^ lambda expressions are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_public.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_public.exp index 3f418112820..8b081f5d6e7 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_public.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_public.exp @@ -1,18 +1,18 @@ -error[E13001]: feature is not supported in specified edition +error[E01003]: invalid modifier ┌─ tests/move_check/parser/struct_public.move:3:5 │ 3 │ public struct Foo {} - │ ^^^^^^ Struct visibility modifiers are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Invalid struct declaration. Structs cannot have visibility modifiers as they are always 'public' │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + = Starting in the Move 2024 edition visibility must be annotated on struct declarations. -error[E01003]: invalid modifier +error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/struct_public.move:3:5 │ 3 │ public struct Foo {} - │ ^^^^^^ Invalid struct declaration. Structs cannot have visibility modifiers as they are always 'public' + │ ^^^^^^ Struct visibility modifiers are not supported by current edition 'legacy'; the '2024' edition supports this feature │ - = Starting in the Move 2024 edition visibility must be annotated on struct declarations. + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. error[E01003]: invalid modifier ┌─ tests/move_check/parser/struct_public.move:4:5 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp index 33597ab4dda..d4e57bb8d34 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp @@ -2,5 +2,5 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/struct_type_extra_comma.move:2:14 │ 2 │ struct S<,T> { f: T } // Test a comma before the first type parameter - │ ^ Expected a type parameter + │ ^ Unexpected ','. Expected a type parameter diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module.exp index 948b17b93e5..304ea12e7bb 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/top_level_module.move:1:11 │ 1 │ module a::m; - │ ^ 'module' label forms (ending with ';') are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'module' label forms (ending with ';') are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module_address_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module_address_invalid.exp index 94e0c0b0544..2a6e4f2efcd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module_address_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/top_level_module_address_invalid.exp @@ -1,14 +1,14 @@ -error[E13001]: feature is not supported in specified edition +error[E02004]: invalid 'module' declaration ┌─ tests/move_check/parser/top_level_module_address_invalid.move:2:12 │ 2 │ module m; - │ ^ 'module' label forms (ending with ';') are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature - │ - = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + │ ^ Cannot define 'module' label in address block -error[E02004]: invalid 'module' declaration +error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/top_level_module_address_invalid.move:2:12 │ 2 │ module m; - │ ^ Cannot define 'module' label in address block + │ ^ 'module' label forms (ending with ';') are not supported by current edition 'legacy'; the '2024' edition supports this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/use_module_member_invalid_comma.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/use_module_member_invalid_comma.exp index 713a1f82091..335b4821393 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/use_module_member_invalid_comma.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/use_module_member_invalid_comma.exp @@ -2,5 +2,5 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/use_module_member_invalid_comma.move:4:26 │ 4 │ use 0x1::X::{S as XS,,}; - │ ^ Expected a module member alias + │ ^ Unexpected ','. Expected a module member alias diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/use_with_modifiers_exp.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/use_with_modifiers_exp.exp index b0c68c1f7e7..45bc1d7fb87 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/use_with_modifiers_exp.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/use_with_modifiers_exp.exp @@ -11,7 +11,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/parser/use_with_modifiers_exp.move:3:9 │ 3 │ public use fun bar as X.baz; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_args.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_args.exp index 103cfcfd507..eb164bb74a1 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_args.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_args.exp @@ -19,7 +19,7 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/vector_literal_unclosed_args.move:5:5 │ 5 │ } - │ ^ Expected a vector argument expression + │ ^ Unexpected '}'. Expected a vector argument expression error[E01002]: unexpected token ┌─ tests/move_check/parser/vector_literal_unclosed_args.move:7:1 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.exp b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.exp deleted file mode 100644 index 95782c0d701..00000000000 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.exp +++ /dev/null @@ -1,9 +0,0 @@ -error[E01002]: unexpected token - ┌─ tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.move:6:1 - │ -6 │ } - │ ^ - │ │ - │ Unexpected '}' - │ Expected an expression term - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.move b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.move deleted file mode 100644 index 5ae2e1b36d6..00000000000 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/abort_negative_stack_size.move +++ /dev/null @@ -1,7 +0,0 @@ -// check: NEGATIVE_STACK_SIZE_WITHIN_BLOCK -module 0x42::m { - -fun main() { - abort -} -} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/break_unreachable.exp b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/break_unreachable.exp index 4f23dbbfb6f..cbd96b368f5 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/break_unreachable.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/break_unreachable.exp @@ -1,8 +1,10 @@ warning[W09005]: dead or unreachable code - ┌─ tests/move_check/translated_ir_tests/move/commands/break_unreachable.move:8:9 + ┌─ tests/move_check/translated_ir_tests/move/commands/break_unreachable.move:7:9 │ +7 │ break; + │ ^^^^^ Any code after this expression will not be reached 8 │ x = 5; - │ ^^^^^ Unreachable code. This statement (and any following statements) will not be executed. + │ ----- Unreachable code. This statement (and any following statements) will not be executed. │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return.exp b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return.exp index 362b040b4eb..17a7b9b942f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return.exp @@ -1,8 +1,10 @@ warning[W09005]: dead or unreachable code - ┌─ tests/move_check/translated_ir_tests/move/commands/dead_return.move:4:9 + ┌─ tests/move_check/translated_ir_tests/move/commands/dead_return.move:3:9 │ +3 │ return 100; + │ ^^^^^^^^^^ Any code after this expression will not be reached 4 │ return 0 - │ ^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. + │ -------- Unreachable code. This statement (and any following statements) will not be executed. │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return_local.exp b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return_local.exp index ab37185a6b6..e004b20f059 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return_local.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/dead_return_local.exp @@ -1,8 +1,10 @@ warning[W09005]: dead or unreachable code - ┌─ tests/move_check/translated_ir_tests/move/commands/dead_return_local.move:4:5 + ┌─ tests/move_check/translated_ir_tests/move/commands/dead_return_local.move:3:5 │ +3 │ return (); + │ ^^^^^^^^^ Any code after this expression will not be reached 4 │ assert!(false, 42); - │ ^^^^^^^^^^^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. + │ ------------------ Unreachable code. This statement (and any following statements) will not be executed. │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough2.exp b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough2.exp index e6d2d1a982d..2fbbf03754f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough2.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough2.exp @@ -1,8 +1,10 @@ warning[W09005]: dead or unreachable code - ┌─ tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough2.move:5:3 + ┌─ tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough2.move:4:3 │ +4 │ return (); + │ ^^^^^^^^^ Any code after this expression will not be reached 5 │ x = 7 - │ ^^^^^ Unreachable code. This statement (and any following statements) will not be executed. + │ ----- Unreachable code. This statement (and any following statements) will not be executed. │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough3.exp b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough3.exp index c5978886add..0ba463b93d4 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough3.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough3.exp @@ -1,8 +1,10 @@ warning[W09005]: dead or unreachable code - ┌─ tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough3.move:5:3 + ┌─ tests/move_check/translated_ir_tests/move/commands/invalid_fallthrough3.move:4:3 │ +4 │ if (true) return () else return (); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Any code after this expression will not be reached 5 │ x = 7; - │ ^^^^^ Unreachable code. This statement (and any following statements) will not be executed. + │ ----- Unreachable code. This statement (and any following statements) will not be executed. │ = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_duplicate_assigning.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_duplicate_assigning.exp index db12664c746..5a627a82018 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_duplicate_assigning.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_duplicate_assigning.exp @@ -6,6 +6,14 @@ warning[W09003]: unused assignment │ = This warning can be suppressed with '#[allow(unused_assignment)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +warning[W09003]: unused assignment + ┌─ tests/move_check/typing/assign_duplicate_assigning.move:6:13 + │ +6 │ (x, x) = (0, 0); + │ ^ Unused assignment for variable 'x'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_x') + │ + = This warning can be suppressed with '#[allow(unused_assignment)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/typing/assign_duplicate_assigning.move:6:13 │ @@ -15,18 +23,18 @@ error[E02001]: duplicate declaration, item, or annotation │ Previously assigned here warning[W09003]: unused assignment - ┌─ tests/move_check/typing/assign_duplicate_assigning.move:6:13 + ┌─ tests/move_check/typing/assign_duplicate_assigning.move:8:10 │ -6 │ (x, x) = (0, 0); - │ ^ Unused assignment for variable 'x'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_x') +8 │ (f, R{f}, f) = (0, R { f: 0 }, 0); + │ ^ Unused assignment for variable 'f'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_f') │ = This warning can be suppressed with '#[allow(unused_assignment)]' applied to the 'module' or module member ('const', 'fun', or 'struct') warning[W09003]: unused assignment - ┌─ tests/move_check/typing/assign_duplicate_assigning.move:8:10 + ┌─ tests/move_check/typing/assign_duplicate_assigning.move:8:15 │ 8 │ (f, R{f}, f) = (0, R { f: 0 }, 0); - │ ^ Unused assignment for variable 'f'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_f') + │ ^ Unused assignment for variable 'f'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_f') │ = This warning can be suppressed with '#[allow(unused_assignment)]' applied to the 'module' or module member ('const', 'fun', or 'struct') @@ -39,10 +47,10 @@ error[E02001]: duplicate declaration, item, or annotation │ Previously assigned here warning[W09003]: unused assignment - ┌─ tests/move_check/typing/assign_duplicate_assigning.move:8:15 + ┌─ tests/move_check/typing/assign_duplicate_assigning.move:8:19 │ 8 │ (f, R{f}, f) = (0, R { f: 0 }, 0); - │ ^ Unused assignment for variable 'f'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_f') + │ ^ Unused assignment for variable 'f'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_f') │ = This warning can be suppressed with '#[allow(unused_assignment)]' applied to the 'module' or module member ('const', 'fun', or 'struct') @@ -54,11 +62,3 @@ error[E02001]: duplicate declaration, item, or annotation │ │ │ Previously assigned here -warning[W09003]: unused assignment - ┌─ tests/move_check/typing/assign_duplicate_assigning.move:8:19 - │ -8 │ (f, R{f}, f) = (0, R { f: 0 }, 0); - │ ^ Unused assignment for variable 'f'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_f') - │ - = This warning can be suppressed with '#[allow(unused_assignment)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_wrong_arity.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_wrong_arity.exp index 8537b4c404c..a21b7b984c1 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_wrong_arity.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/assign_wrong_arity.exp @@ -14,23 +14,23 @@ error[E04005]: expected a single type │ │ │ Invalid type for local -error[E04007]: incompatible types +error[E04005]: expected a single type ┌─ tests/move_check/typing/assign_wrong_arity.move:7:9 │ -6 │ x = (); - │ -- Expected: '()' 7 │ x = (0, 1, 2); - │ ^ --------- Given: '({integer}, {integer}, {integer})' + │ ^ --------- Expected a single type, but found expression list type: '(u64, u64, u64)' │ │ - │ Invalid assignment to variable 'x' + │ Invalid type for local -error[E04005]: expected a single type +error[E04007]: incompatible types ┌─ tests/move_check/typing/assign_wrong_arity.move:7:9 │ +6 │ x = (); + │ -- Expected: '()' 7 │ x = (0, 1, 2); - │ ^ --------- Expected a single type, but found expression list type: '(u64, u64, u64)' + │ ^ --------- Given: '({integer}, {integer}, {integer})' │ │ - │ Invalid type for local + │ Invalid assignment to variable 'x' error[E04007]: incompatible types ┌─ tests/move_check/typing/assign_wrong_arity.move:8:9 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/bind_duplicate_binding.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/bind_duplicate_binding.exp index f6d580ceaef..c75c6a67e05 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/bind_duplicate_binding.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/bind_duplicate_binding.exp @@ -22,14 +22,6 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/typing/bind_duplicate_binding.move:6:19 - │ -6 │ let (f, R{f}, f) = (0, R { f: 0 }, 0); f; - │ - ^ Duplicate declaration for local 'f' in a given 'let' - │ │ - │ Previously declared here - warning[W09002]: unused variable ┌─ tests/move_check/typing/bind_duplicate_binding.move:6:19 │ @@ -38,6 +30,14 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/typing/bind_duplicate_binding.move:6:19 + │ +6 │ let (f, R{f}, f) = (0, R { f: 0 }, 0); f; + │ - ^ Duplicate declaration for local 'f' in a given 'let' + │ │ + │ Previously declared here + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/typing/bind_duplicate_binding.move:6:23 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/cast_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/cast_invalid.exp index a37661db535..16d9e2e33f1 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/cast_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/cast_invalid.exp @@ -95,7 +95,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:23:9 │ 23 │ false as u8; - │ ^^^^^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -112,7 +112,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:24:9 │ 24 │ true as u128; - │ ^^^^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -129,7 +129,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:26:9 │ 26 │ () as u64; - │ ^^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -146,7 +146,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:27:9 │ 27 │ (0, 1) as u8; - │ ^^^^^^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -163,7 +163,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:29:9 │ 29 │ 0 as bool; - │ ^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -179,7 +179,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:30:9 │ 30 │ 0 as address; - │ ^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -195,7 +195,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:31:15 │ 31 │ R{} = 0 as R; - │ ^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -211,7 +211,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:32:9 │ 32 │ 0 as Cup; - │ ^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -227,7 +227,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:33:9 │ 33 │ 0 as (); - │ ^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -243,7 +243,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:34:9 │ 34 │ 0 as (u64, u8); - │ ^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -259,7 +259,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/cast_invalid.move:36:9 │ 36 │ x"1234" as u64; - │ ^^^^^^^ 'as' without parentheses is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^^ 'as' without parentheses is not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/clever_assertions.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/clever_assertions.exp index 14307ab57fc..fd2dd6769a8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/clever_assertions.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/clever_assertions.exp @@ -2,7 +2,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/clever_assertions.move:4:7 │ 4 │ #[error] - │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -10,7 +10,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/clever_assertions.move:7:7 │ 7 │ #[error] - │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. @@ -18,7 +18,7 @@ error[E13001]: feature is not supported in specified edition ┌─ tests/move_check/typing/clever_assertions.move:23:9 │ 23 │ assert!(false); - │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ ^^^^^^ Clever `assert!`, `abort`, and `#[error]` are not supported by current edition 'legacy'; the '2024' edition supports this feature │ = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/constant_non_base_type.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/constant_non_base_type.exp index dbc957ec77c..d7d407c2d5c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/constant_non_base_type.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/constant_non_base_type.exp @@ -13,15 +13,6 @@ error[E04013]: invalid statement or expression in constant 3 │ const C1: &u64 = &0; │ ^^ References (and reference operations) are not supported in constants -error[E04012]: invalid type for constant - ┌─ tests/move_check/typing/constant_non_base_type.move:4:15 - │ -4 │ const C2: &mut u64 = &0; - │ ^^^^^^^^ - │ │ - │ Unpermitted constant type - │ Found: '&mut u64'. But expected one of: 'u8', 'u16', 'u32', 'u64', 'u128', 'u256', 'bool', 'address', 'vector<_>' - error[E04006]: invalid subtype ┌─ tests/move_check/typing/constant_non_base_type.move:4:15 │ @@ -31,6 +22,15 @@ error[E04006]: invalid subtype │ Invalid constant signature │ Expected: '&mut u64' +error[E04012]: invalid type for constant + ┌─ tests/move_check/typing/constant_non_base_type.move:4:15 + │ +4 │ const C2: &mut u64 = &0; + │ ^^^^^^^^ + │ │ + │ Unpermitted constant type + │ Found: '&mut u64'. But expected one of: 'u8', 'u16', 'u32', 'u64', 'u128', 'u256', 'bool', 'address', 'vector<_>' + error[E04013]: invalid statement or expression in constant ┌─ tests/move_check/typing/constant_non_base_type.move:4:26 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/constraints_not_satisfied_type_arguments_internal_pack.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/constraints_not_satisfied_type_arguments_internal_pack.exp index 9f21541de58..e67458181af 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/constraints_not_satisfied_type_arguments_internal_pack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/constraints_not_satisfied_type_arguments_internal_pack.exp @@ -40,11 +40,3 @@ error[E05001]: ability constraint not satisfied │ Cannot ignore values without the 'drop' ability. The value must be used │ The type '0x8675309::M::Box<0x8675309::M::R>' does not have the ability 'drop' -warning[W09005]: dead or unreachable code - ┌─ tests/move_check/typing/constraints_not_satisfied_type_arguments_internal_pack.move:9:9 - │ -9 │ Box{ f: R{} }; - │ ^^^^^^^^^^^^^^^^ Unreachable code. This statement (and any following statements) will not be executed. - │ - = This warning can be suppressed with '#[allow(dead_code)]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/declare_duplicate_binding.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/declare_duplicate_binding.exp index 85d3b1df0aa..2f8e7ff8d6c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/declare_duplicate_binding.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/declare_duplicate_binding.exp @@ -22,14 +22,6 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/typing/declare_duplicate_binding.move:6:19 - │ -6 │ let (f, R{f}, f); - │ - ^ Duplicate declaration for local 'f' in a given 'let' - │ │ - │ Previously declared here - warning[W09002]: unused variable ┌─ tests/move_check/typing/declare_duplicate_binding.move:6:19 │ @@ -38,6 +30,14 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/typing/declare_duplicate_binding.move:6:19 + │ +6 │ let (f, R{f}, f); + │ - ^ Duplicate declaration for local 'f' in a given 'let' + │ │ + │ Previously declared here + error[E02001]: duplicate declaration, item, or annotation ┌─ tests/move_check/typing/declare_duplicate_binding.move:6:23 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/duplicate_function_parameter_names.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/duplicate_function_parameter_names.exp index 2ff0986168d..b1e02b57d1c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/duplicate_function_parameter_names.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/duplicate_function_parameter_names.exp @@ -6,14 +6,6 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') -error[E02001]: duplicate declaration, item, or annotation - ┌─ tests/move_check/typing/duplicate_function_parameter_names.move:2:21 - │ -2 │ fun foo(x: u64, x: u64) {} - │ - ^ Duplicate parameter with name 'x' - │ │ - │ Previously declared here - warning[W09002]: unused variable ┌─ tests/move_check/typing/duplicate_function_parameter_names.move:2:21 │ @@ -22,3 +14,11 @@ warning[W09002]: unused variable │ = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') +error[E02001]: duplicate declaration, item, or annotation + ┌─ tests/move_check/typing/duplicate_function_parameter_names.move:2:21 + │ +2 │ fun foo(x: u64, x: u64) {} + │ - ^ Duplicate parameter with name 'x' + │ │ + │ Previously declared here + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/exp_list_nested.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/exp_list_nested.exp index 30950647293..492a785e840 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/exp_list_nested.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/exp_list_nested.exp @@ -1,3 +1,12 @@ +error[E04005]: expected a single type + ┌─ tests/move_check/typing/exp_list_nested.move:6:9 + │ +6 │ (0, (S{}, R{})) + │ ^^^^^^^^^^^^^^^ + │ │ │ + │ │ Expected a single type, but found expression list type: '(0x8675309::M::S, 0x8675309::M::R<_>)' + │ Invalid expression list type argument + error[E04007]: incompatible types ┌─ tests/move_check/typing/exp_list_nested.move:6:9 │ @@ -9,15 +18,6 @@ error[E04007]: incompatible types │ Invalid return expression │ Given expression list of length 2: '({integer}, (0x8675309::M::S, 0x8675309::M::R<_>))' -error[E04005]: expected a single type - ┌─ tests/move_check/typing/exp_list_nested.move:6:9 - │ -6 │ (0, (S{}, R{})) - │ ^^^^^^^^^^^^^^^ - │ │ │ - │ │ Expected a single type, but found expression list type: '(0x8675309::M::S, 0x8675309::M::R<_>)' - │ Invalid expression list type argument - error[E04010]: cannot infer type ┌─ tests/move_check/typing/exp_list_nested.move:6:19 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.exp new file mode 100644 index 00000000000..56264bc0132 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.exp @@ -0,0 +1,34 @@ +error[E04007]: incompatible types + ┌─ tests/move_check/typing/if_no_else.move:4:9 + │ +4 │ if (cond) 0; + │ ^^^^^^^^^^^ + │ │ │ + │ │ Given: integer + │ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ Expected: '()' + +error[E04007]: incompatible types + ┌─ tests/move_check/typing/if_no_else.move:5:9 + │ + 5 │ if (cond) foo(); + │ ^^^^^^^^^^^^^^^ + │ │ + │ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ Expected: '()' + · +13 │ fun foo(): u64 { 0 } + │ --- Given: 'u64' + +error[E04007]: incompatible types + ┌─ tests/move_check/typing/if_no_else.move:6:9 + │ + 6 │ ╭ ╭ if (cond) { + 7 │ │ │ let x = 0; + 8 │ │ │ let y = 1; + │ │ │ - Given: integer + 9 │ │ │ x * y +10 │ │ │ } + │ ╰─│─────────^ Invalid 'if'. The body of an 'if' without an 'else' must have type '()' + │ ╰─────────' Expected: '()' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.move b/external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.move new file mode 100644 index 00000000000..245ac3a26b0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/if_no_else.move @@ -0,0 +1,14 @@ + +module a::m { + fun t(cond: bool) { + if (cond) 0; + if (cond) foo(); + if (cond) { + let x = 0; + let y = 1; + x * y + } + } + + fun foo(): u64 { 0 } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/instantiate_signatures.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/instantiate_signatures.exp index 972e709777f..1b4186f7493 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/instantiate_signatures.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/instantiate_signatures.exp @@ -26,18 +26,18 @@ error[E04004]: expected a single non-reference type │ 13 │ f3: &(&u64), │ ^^^^^^^ - │ ││ - │ │Expected a single non-reference type, but found: '&u64' - │ Invalid reference type + │ │ + │ Invalid field type + │ Expected a single non-reference type, but found: '&&u64' error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/instantiate_signatures.move:13:13 │ 13 │ f3: &(&u64), │ ^^^^^^^ - │ │ - │ Invalid field type - │ Expected a single non-reference type, but found: '&&u64' + │ ││ + │ │Expected a single non-reference type, but found: '&u64' + │ Invalid reference type error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/instantiate_signatures.move:14:13 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call.exp index 4577a44320c..0273c5bba3b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call.exp @@ -1,12 +1,3 @@ -error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:43:18 - │ -43 │ let () = X::bing(X::baz(X::bar(X::foo()))); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 - error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:43:18 │ @@ -20,13 +11,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::X::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:43:26 + ┌─ tests/move_check/typing/module_call.move:43:18 │ 43 │ let () = X::bing(X::baz(X::bar(X::foo()))); - │ ^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::baz'. The call expected 2 argument(s) but got 1 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call.move:43:26 @@ -38,13 +29,13 @@ error[E04004]: expected a single non-reference type │ ^^^^^^^^^^^^^^^^^^^^^^^^ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:44:18 + ┌─ tests/move_check/typing/module_call.move:43:26 │ -44 │ let () = X::bing (X::baz (X::bar (X::foo()))); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 +43 │ let () = X::bing(X::baz(X::bar(X::foo()))); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::baz'. The call expected 2 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:44:18 @@ -59,13 +50,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::X::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:44:27 + ┌─ tests/move_check/typing/module_call.move:44:18 │ 44 │ let () = X::bing (X::baz (X::bar (X::foo()))); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::baz'. The call expected 2 argument(s) but got 1 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call.move:44:27 @@ -77,13 +68,13 @@ error[E04004]: expected a single non-reference type │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:45:18 + ┌─ tests/move_check/typing/module_call.move:44:27 │ -45 │ let () = X::bing (X::baz (X::bar(1))); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 +44 │ let () = X::bing (X::baz (X::bar (X::foo()))); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::baz'. The call expected 2 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:45:18 @@ -98,13 +89,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::X::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:45:27 + ┌─ tests/move_check/typing/module_call.move:45:18 │ 45 │ let () = X::bing (X::baz (X::bar(1))); - │ ^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::baz'. The call expected 2 argument(s) but got 1 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call.move:45:27 @@ -116,13 +107,13 @@ error[E04004]: expected a single non-reference type │ ^^^^^^^^^^^^^^^^^^ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:46:18 + ┌─ tests/move_check/typing/module_call.move:45:27 │ -46 │ let () = X::bing (X::baz (@0x0, 1)); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 +45 │ let () = X::bing (X::baz (X::bar(1))); + │ ^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::baz'. The call expected 2 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:46:18 @@ -137,13 +128,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::X::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:51:18 + ┌─ tests/move_check/typing/module_call.move:46:18 │ -51 │ let () = bing(baz(bar(foo()))); - │ ^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 +46 │ let () = X::bing (X::baz (@0x0, 1)); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::X::bing'. The call expected 3 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:51:18 @@ -158,13 +149,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::M::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:51:23 + ┌─ tests/move_check/typing/module_call.move:51:18 │ 51 │ let () = bing(baz(bar(foo()))); - │ ^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::baz'. The call expected 2 argument(s) but got 1 + │ ^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call.move:51:23 @@ -176,13 +167,13 @@ error[E04004]: expected a single non-reference type │ ^^^^^^^^^^^^^^^ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:52:18 + ┌─ tests/move_check/typing/module_call.move:51:23 │ -52 │ let () = bing (baz (bar (foo()))); - │ ^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 +51 │ let () = bing(baz(bar(foo()))); + │ ^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::baz'. The call expected 2 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:52:18 @@ -197,13 +188,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::M::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:52:24 + ┌─ tests/move_check/typing/module_call.move:52:18 │ 52 │ let () = bing (baz (bar (foo()))); - │ ^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::baz'. The call expected 2 argument(s) but got 1 + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call.move:52:24 @@ -215,13 +206,13 @@ error[E04004]: expected a single non-reference type │ ^^^^^^^^^^^^^^^^^ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:53:18 + ┌─ tests/move_check/typing/module_call.move:52:24 │ -53 │ let () = bing (baz (bar(1))); - │ ^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 +52 │ let () = bing (baz (bar (foo()))); + │ ^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::baz'. The call expected 2 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:53:18 @@ -236,13 +227,13 @@ error[E04007]: incompatible types │ ^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::M::bing'. Invalid argument for parameter '_' error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:53:24 + ┌─ tests/move_check/typing/module_call.move:53:18 │ 53 │ let () = bing (baz (bar(1))); - │ ^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::baz'. The call expected 2 argument(s) but got 1 + │ ^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call.move:53:24 @@ -254,13 +245,13 @@ error[E04004]: expected a single non-reference type │ ^^^^^^^^^^^^ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call.move:54:18 + ┌─ tests/move_check/typing/module_call.move:53:24 │ -54 │ let () = bing (baz (@0x0, 1)); - │ ^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 +53 │ let () = bing (baz (bar(1))); + │ ^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::baz'. The call expected 2 argument(s) but got 1 error[E04007]: incompatible types ┌─ tests/move_check/typing/module_call.move:54:18 @@ -274,3 +265,12 @@ error[E04007]: incompatible types 54 │ let () = bing (baz (@0x0, 1)); │ ^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x2::M::bing'. Invalid argument for parameter '_' +error[E04016]: too few arguments + ┌─ tests/move_check/typing/module_call.move:54:18 + │ +54 │ let () = bing (baz (@0x0, 1)); + │ ^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x2::M::bing'. The call expected 3 argument(s) but got 1 + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_complicated_rhs.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_complicated_rhs.exp index 318bd43fa8b..08a96618350 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_complicated_rhs.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_complicated_rhs.exp @@ -7,23 +7,23 @@ error[E04017]: too many arguments │ │ Found 1 argument(s) here │ Invalid call of '0x8675309::M::foo'. The call expected 0 argument(s) but got 1 -error[E04016]: too few arguments +error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call_complicated_rhs.move:13:9 │ 13 │ baz (if (cond) (false, @0x0) else (true, @0x1)); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 + │ │ │ + │ │ Expected a single non-reference type, but found: '(bool, address)' + │ Invalid type argument -error[E04004]: expected a single non-reference type +error[E04016]: too few arguments ┌─ tests/move_check/typing/module_call_complicated_rhs.move:13:9 │ 13 │ baz (if (cond) (false, @0x0) else (true, @0x1)); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Expected a single non-reference type, but found: '(bool, address)' - │ Invalid type argument + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 error[E04017]: too many arguments ┌─ tests/move_check/typing/module_call_complicated_rhs.move:17:9 @@ -34,23 +34,23 @@ error[E04017]: too many arguments │ │ Found 1 argument(s) here │ Invalid call of '0x8675309::M::foo'. The call expected 0 argument(s) but got 1 -error[E04016]: too few arguments +error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call_complicated_rhs.move:19:9 │ 19 │ baz(if (cond) (false, @0x0) else (true, @0x1)); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 + │ │ │ + │ │ Expected a single non-reference type, but found: '(bool, address)' + │ Invalid type argument -error[E04004]: expected a single non-reference type +error[E04016]: too few arguments ┌─ tests/move_check/typing/module_call_complicated_rhs.move:19:9 │ 19 │ baz(if (cond) (false, @0x0) else (true, @0x1)); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Expected a single non-reference type, but found: '(bool, address)' - │ Invalid type argument + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 error[E04017]: too many arguments ┌─ tests/move_check/typing/module_call_complicated_rhs.move:23:9 @@ -70,15 +70,6 @@ error[E04017]: too many arguments │ │ Found 1 argument(s) here │ Invalid call of '0x8675309::M::foo'. The call expected 0 argument(s) but got 1 -error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call_complicated_rhs.move:31:9 - │ -31 │ baz({ (a, x) }); - │ ^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 - error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call_complicated_rhs.move:31:9 │ @@ -89,10 +80,10 @@ error[E04004]: expected a single non-reference type │ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call_complicated_rhs.move:32:9 + ┌─ tests/move_check/typing/module_call_complicated_rhs.move:31:9 │ -32 │ baz({ let a = false; (a, x) }); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +31 │ baz({ (a, x) }); + │ ^^^^^^^^^^^^^^^ │ │ │ │ │ Found 1 argument(s) here │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 @@ -106,6 +97,15 @@ error[E04004]: expected a single non-reference type │ │ Expected a single non-reference type, but found: '(bool, u64)' │ Invalid type argument +error[E04016]: too few arguments + ┌─ tests/move_check/typing/module_call_complicated_rhs.move:32:9 + │ +32 │ baz({ let a = false; (a, x) }); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 + error[E04017]: too many arguments ┌─ tests/move_check/typing/module_call_complicated_rhs.move:36:9 │ @@ -124,15 +124,6 @@ error[E04017]: too many arguments │ │ Found 1 argument(s) here │ Invalid call of '0x8675309::M::foo'. The call expected 0 argument(s) but got 1 -error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call_complicated_rhs.move:44:9 - │ -44 │ baz({ (a, x) }); - │ ^^^^^^^^^^^^^^^ - │ │ │ - │ │ Found 1 argument(s) here - │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 - error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/module_call_complicated_rhs.move:44:9 │ @@ -143,10 +134,10 @@ error[E04004]: expected a single non-reference type │ Invalid type argument error[E04016]: too few arguments - ┌─ tests/move_check/typing/module_call_complicated_rhs.move:45:9 + ┌─ tests/move_check/typing/module_call_complicated_rhs.move:44:9 │ -45 │ baz({ let a = false; (a, x) }); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +44 │ baz({ (a, x) }); + │ ^^^^^^^^^^^^^^^ │ │ │ │ │ Found 1 argument(s) here │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 @@ -160,3 +151,12 @@ error[E04004]: expected a single non-reference type │ │ Expected a single non-reference type, but found: '(bool, u64)' │ Invalid type argument +error[E04016]: too few arguments + ┌─ tests/move_check/typing/module_call_complicated_rhs.move:45:9 + │ +45 │ baz({ let a = false; (a, x) }); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 1 argument(s) here + │ Invalid call of '0x8675309::M::baz'. The call expected 2 argument(s) but got 1 + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_constraints_not_satisfied.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_constraints_not_satisfied.exp index 6f5c4c4a765..75d4390aeac 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_constraints_not_satisfied.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/module_call_constraints_not_satisfied.exp @@ -1,3 +1,18 @@ +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:28:9 + │ + 3 │ struct Coin has key {} + │ ---- To satisfy the constraint, the 'copy' ability would need to be added here + · +15 │ fun both(_r: R, _c: C) { + │ ---- 'copy' constraint declared here + · +28 │ both(S{}, Coin{}); + │ ^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ The type '0x8675309::M::Coin' does not have the ability 'copy' + │ 'copy' constraint not satisfied + error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:28:9 │ @@ -14,7 +29,7 @@ error[E05001]: ability constraint not satisfied │ 'key' constraint not satisfied error[E05001]: ability constraint not satisfied - ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:28:9 + ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:29:9 │ 3 │ struct Coin has key {} │ ---- To satisfy the constraint, the 'copy' ability would need to be added here @@ -22,10 +37,10 @@ error[E05001]: ability constraint not satisfied 15 │ fun both(_r: R, _c: C) { │ ---- 'copy' constraint declared here · -28 │ both(S{}, Coin{}); - │ ^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ The type '0x8675309::M::Coin' does not have the ability 'copy' +29 │ both(0, Coin{}) + │ ^^^^^^^^^^^^^^^ + │ │ │ + │ │ The type '0x8675309::M::Coin' does not have the ability 'copy' │ 'copy' constraint not satisfied error[E05001]: ability constraint not satisfied @@ -41,18 +56,18 @@ error[E05001]: ability constraint not satisfied │ 'key' constraint not satisfied error[E05001]: ability constraint not satisfied - ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:29:9 + ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:33:9 │ - 3 │ struct Coin has key {} - │ ---- To satisfy the constraint, the 'copy' ability would need to be added here + 7 │ fun new_box(): Box { + │ ------ The type '0x8675309::M::Box' does not have the ability 'copy' · 15 │ fun both(_r: R, _c: C) { │ ---- 'copy' constraint declared here · -29 │ both(0, Coin{}) - │ ^^^^^^^^^^^^^^^ - │ │ │ - │ │ The type '0x8675309::M::Coin' does not have the ability 'copy' +33 │ both(new_box(), new_box()) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ The type '0x8675309::M::Box' can have the ability 'copy' but the type argument 'R' does not have the required ability 'copy' │ 'copy' constraint not satisfied error[E05001]: ability constraint not satisfied @@ -70,21 +85,6 @@ error[E05001]: ability constraint not satisfied 33 │ both(new_box(), new_box()) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 'key' constraint not satisfied -error[E05001]: ability constraint not satisfied - ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:33:9 - │ - 7 │ fun new_box(): Box { - │ ------ The type '0x8675309::M::Box' does not have the ability 'copy' - · -15 │ fun both(_r: R, _c: C) { - │ ---- 'copy' constraint declared here - · -33 │ both(new_box(), new_box()) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ The type '0x8675309::M::Box' can have the ability 'copy' but the type argument 'R' does not have the required ability 'copy' - │ 'copy' constraint not satisfied - error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/module_call_constraints_not_satisfied.move:37:9 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/native_structs_pack_unpack.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/native_structs_pack_unpack.exp index f187f0db1d6..226ab645b02 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/native_structs_pack_unpack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/native_structs_pack_unpack.exp @@ -1,38 +1,38 @@ -error[E04015]: invalid use of native item +error[E04001]: restricted visibility ┌─ tests/move_check/typing/native_structs_pack_unpack.move:9:9 │ 3 │ native struct T; - │ ------ Struct declared 'native' here + │ - Struct defined in module '0x42::C' · 9 │ C::T {} - │ ^^^^^^^ Invalid argument usage for native struct '0x42::C::T'. Native structs cannot be directly constructed/deconstructed, and their fields cannot be directly accessed + │ ^^^^^^^ Struct '0x42::C::T' can only be instantiated within its defining module '0x42::C' -error[E04001]: restricted visibility +error[E04015]: invalid use of native item ┌─ tests/move_check/typing/native_structs_pack_unpack.move:9:9 │ 3 │ native struct T; - │ - Struct defined in module '0x42::C' + │ ------ Struct declared 'native' here · 9 │ C::T {} - │ ^^^^^^^ Struct '0x42::C::T' can only be instantiated within its defining module '0x42::C' + │ ^^^^^^^ Invalid argument usage for native struct '0x42::C::T'. Native structs cannot be directly constructed/deconstructed, and their fields cannot be directly accessed -error[E04015]: invalid use of native item +error[E04001]: restricted visibility ┌─ tests/move_check/typing/native_structs_pack_unpack.move:12:13 │ 3 │ native struct T; - │ ------ Struct declared 'native' here + │ - Struct defined in module '0x42::C' · 12 │ let C::T {} = c; - │ ^^^^^^^ Invalid binding usage for native struct '0x42::C::T'. Native structs cannot be directly constructed/deconstructed, and their fields cannot be directly accessed + │ ^^^^^^^ Struct '0x42::C::T' can only be used in deconstruction binding within its defining module '0x42::C' -error[E04001]: restricted visibility +error[E04015]: invalid use of native item ┌─ tests/move_check/typing/native_structs_pack_unpack.move:12:13 │ 3 │ native struct T; - │ - Struct defined in module '0x42::C' + │ ------ Struct declared 'native' here · 12 │ let C::T {} = c; - │ ^^^^^^^ Struct '0x42::C::T' can only be used in deconstruction binding within its defining module '0x42::C' + │ ^^^^^^^ Invalid binding usage for native struct '0x42::C::T'. Native structs cannot be directly constructed/deconstructed, and their fields cannot be directly accessed error[E04001]: restricted visibility ┌─ tests/move_check/typing/native_structs_pack_unpack.move:15:18 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/phantom_params_constraint_abilities_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/phantom_params_constraint_abilities_invalid.exp index ec60be40b93..3cf658e942d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/phantom_params_constraint_abilities_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/phantom_params_constraint_abilities_invalid.exp @@ -28,45 +28,27 @@ error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:11:12 │ 9 │ struct S1 { a: T } - │ ----- 'store' constraint declared here + │ --- 'key' constraint declared here 10 │ struct S2 { 11 │ a: S1>, │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ │ │ │ - │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' - │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' - │ 'store' constraint not satisfied + │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'key' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' + │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'key' + │ 'key' constraint not satisfied error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:11:12 │ 9 │ struct S1 { a: T } - │ --- 'key' constraint declared here + │ ----- 'store' constraint declared here 10 │ struct S2 { 11 │ a: S1>, │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ │ │ │ - │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'key' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' - │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'key' - │ 'key' constraint not satisfied - -error[E05001]: ability constraint not satisfied - ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:16:12 - │ -14 │ struct S3 { a: T1, b: T2, c: T3, d: T4 } - │ ---- 'drop' constraint declared here -15 │ struct S4 { -16 │ a: S3< HasDrop, - │ --------------------------------- - │ │ │ - │ │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'drop' but the type argument '0x42::M::NoAbilities' does not have the required ability 'drop' - │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'drop' - │ ╭────────────^ -17 │ │ HasCopy, -18 │ │ HasStore, -19 │ │ HasKey -20 │ │ > - │ ╰──────────────^ 'drop' constraint not satisfied + │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' + │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' + │ 'store' constraint not satisfied error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:16:12 @@ -90,19 +72,19 @@ error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:16:12 │ 14 │ struct S3 { a: T1, b: T2, c: T3, d: T4 } - │ ----- 'store' constraint declared here + │ ---- 'drop' constraint declared here 15 │ struct S4 { 16 │ a: S3< HasDrop, + │ --------------------------------- + │ │ │ + │ │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'drop' but the type argument '0x42::M::NoAbilities' does not have the required ability 'drop' + │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'drop' │ ╭────────────^ 17 │ │ HasCopy, 18 │ │ HasStore, - │ │ ---------------------------------- - │ │ │ │ - │ │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' - │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' 19 │ │ HasKey 20 │ │ > - │ ╰──────────────^ 'store' constraint not satisfied + │ ╰──────────────^ 'drop' constraint not satisfied error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:16:12 @@ -122,6 +104,24 @@ error[E05001]: ability constraint not satisfied 20 │ │ > │ ╰──────────────^ 'key' constraint not satisfied +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:16:12 + │ +14 │ struct S3 { a: T1, b: T2, c: T3, d: T4 } + │ ----- 'store' constraint declared here +15 │ struct S4 { +16 │ a: S3< HasDrop, + │ ╭────────────^ +17 │ │ HasCopy, +18 │ │ HasStore, + │ │ ---------------------------------- + │ │ │ │ + │ │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' + │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' +19 │ │ HasKey +20 │ │ > + │ ╰──────────────^ 'store' constraint not satisfied + error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:25:9 │ @@ -152,44 +152,27 @@ error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:25:9 │ 23 │ fun f1() { } - │ ----- 'store' constraint declared here + │ --- 'key' constraint declared here 24 │ fun f2() { 25 │ f1>(); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ │ │ │ - │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' - │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' - │ 'store' constraint not satisfied + │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'key' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' + │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'key' + │ 'key' constraint not satisfied error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:25:9 │ 23 │ fun f1() { } - │ --- 'key' constraint declared here + │ ----- 'store' constraint declared here 24 │ fun f2() { 25 │ f1>(); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ │ │ │ - │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'key' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' - │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'key' - │ 'key' constraint not satisfied - -error[E05001]: ability constraint not satisfied - ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:30:9 - │ -28 │ fun f3() { } - │ ---- 'drop' constraint declared here -29 │ fun f4() { -30 │ ╭ f3< HasDrop, - │ --------------------------------- - │ │ │ - │ │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'drop' but the type argument '0x42::M::NoAbilities' does not have the required ability 'drop' - │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'drop' -31 │ │ HasCopy, -32 │ │ HasStore, -33 │ │ HasKey -34 │ │ >(); - │ ╰─────────────^ 'drop' constraint not satisfied + │ │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' + │ │ The type '0x42::M::HasAbilities<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' + │ 'store' constraint not satisfied error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:30:9 @@ -212,18 +195,18 @@ error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:30:9 │ 28 │ fun f3() { } - │ ----- 'store' constraint declared here + │ ---- 'drop' constraint declared here 29 │ fun f4() { 30 │ ╭ f3< HasDrop, + │ --------------------------------- + │ │ │ + │ │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'drop' but the type argument '0x42::M::NoAbilities' does not have the required ability 'drop' + │ The type '0x42::M::HasDrop<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'drop' 31 │ │ HasCopy, 32 │ │ HasStore, - │ │ ---------------------------------- - │ │ │ │ - │ │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' - │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' 33 │ │ HasKey 34 │ │ >(); - │ ╰─────────────^ 'store' constraint not satisfied + │ ╰─────────────^ 'drop' constraint not satisfied error[E05001]: ability constraint not satisfied ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:30:9 @@ -242,3 +225,20 @@ error[E05001]: ability constraint not satisfied 34 │ │ >(); │ ╰─────────────^ 'key' constraint not satisfied +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/phantom_params_constraint_abilities_invalid.move:30:9 + │ +28 │ fun f3() { } + │ ----- 'store' constraint declared here +29 │ fun f4() { +30 │ ╭ f3< HasDrop, +31 │ │ HasCopy, +32 │ │ HasStore, + │ │ ---------------------------------- + │ │ │ │ + │ │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' can have the ability 'store' but the type argument '0x42::M::NoAbilities' does not have the required ability 'store' + │ │ The type '0x42::M::HasStore<0x42::M::NoAbilities, 0x42::M::NoAbilities>' does not have the ability 'store' +33 │ │ HasKey +34 │ │ >(); + │ ╰─────────────^ 'store' constraint not satisfied + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/recursive_local.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/recursive_local.exp index f4894001f6b..e19f34747c6 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/recursive_local.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/recursive_local.exp @@ -4,14 +4,6 @@ error[E04010]: cannot infer type 4 │ let x; │ ^ Could not infer this type. Try adding an annotation -error[E04008]: invalid type. recursive type found - ┌─ tests/move_check/typing/recursive_local.move:5:9 - │ -4 │ let x; - │ - Unable to infer the type. Recursive type found. -5 │ x = (x, 0); - │ ^ Invalid assignment to variable 'x' - error[E04005]: expected a single type ┌─ tests/move_check/typing/recursive_local.move:5:9 │ @@ -20,6 +12,14 @@ error[E04005]: expected a single type │ │ │ Invalid type for local +error[E04008]: invalid type. recursive type found + ┌─ tests/move_check/typing/recursive_local.move:5:9 + │ +4 │ let x; + │ - Unable to infer the type. Recursive type found. +5 │ x = (x, 0); + │ ^ Invalid assignment to variable 'x' + error[E04010]: cannot infer type ┌─ tests/move_check/typing/recursive_local.move:5:14 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/vector_mismatched_args_non_base_type.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/vector_mismatched_args_non_base_type.exp index d9ae23fb205..efb1fef8612 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/vector_mismatched_args_non_base_type.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/vector_mismatched_args_non_base_type.exp @@ -1,21 +1,21 @@ -error[E04006]: invalid subtype +error[E04004]: expected a single non-reference type ┌─ tests/move_check/typing/vector_mismatched_args_non_base_type.move:7:9 │ 7 │ vector<&mut u64>[&0]; │ ^^^^^^^^^^^^^^^^^^^^ - │ │ │ │ - │ │ │ Given: '&{integer}' - │ │ Expected: '&mut u64' - │ Invalid 'vector' instantiation. Invalid argument type + │ │ │ + │ │ Expected a single non-reference type, but found: '&mut u64' + │ Invalid 'vector' type -error[E04004]: expected a single non-reference type +error[E04006]: invalid subtype ┌─ tests/move_check/typing/vector_mismatched_args_non_base_type.move:7:9 │ 7 │ vector<&mut u64>[&0]; │ ^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ Expected a single non-reference type, but found: '&mut u64' - │ Invalid 'vector' type + │ │ │ │ + │ │ │ Given: '&{integer}' + │ │ Expected: '&mut u64' + │ Invalid 'vector' instantiation. Invalid argument type error[E04007]: incompatible types ┌─ tests/move_check/typing/vector_mismatched_args_non_base_type.move:8:9 diff --git a/external-crates/move/crates/move-compiler/tests/move_check_testsuite.rs b/external-crates/move/crates/move-compiler/tests/move_check_testsuite.rs index 0e2fd4d63fc..259bdfb4058 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check_testsuite.rs +++ b/external-crates/move/crates/move-compiler/tests/move_check_testsuite.rs @@ -7,16 +7,16 @@ use std::{collections::BTreeMap, fs, path::Path}; use move_command_line_common::{ env::read_bool_env_var, - testing::{add_update_baseline_fix, format_diff, read_env_update_baseline, EXP_EXT, OUT_EXT}, + testing::{EXP_EXT, OUT_EXT, add_update_baseline_fix, format_diff, read_env_update_baseline}, }; use move_compiler::{ + Compiler, PASS_PARSER, command_line::compiler::move_check_for_errors, - diagnostics::*, + diagnostics::{warning_filters::WarningFiltersBuilder, *}, editions::{Edition, Flavor}, iota_mode, linters::{self, LintLevel}, shared::{Flags, NumericalAddress, PackageConfig, PackagePaths}, - Compiler, PASS_PARSER, }; /// Shared flag to keep any temporary results of the test @@ -71,7 +71,8 @@ fn move_check_testsuite(path: &Path) -> datatest_stable::Result<()> { let config = PackageConfig { flavor, edition, - ..PackageConfig::default() + is_dependency: false, + warning_filter: WarningFiltersBuilder::new_for_source(), }; testsuite(path, config, lint) } @@ -91,7 +92,7 @@ fn testsuite(path: &Path, mut config: PackageConfig, lint: bool) -> datatest_sta let mut config = config.clone(); config .warning_filter - .union(&WarningFilters::unused_warnings_filter_for_test()); + .union(&WarningFiltersBuilder::unused_warnings_filter_for_test()); run_test( path, Path::new(&test_exp_path), @@ -116,7 +117,7 @@ fn testsuite(path: &Path, mut config: PackageConfig, lint: bool) -> datatest_sta let mut config = config.clone(); config .warning_filter - .union(&WarningFilters::unused_warnings_filter_for_test()); + .union(&WarningFiltersBuilder::unused_warnings_filter_for_test()); run_test_inner( path, Path::new(&migration_exp_path), @@ -175,7 +176,7 @@ fn testsuite(path: &Path, mut config: PackageConfig, lint: bool) -> datatest_sta config .warning_filter - .union(&WarningFilters::unused_warnings_filter_for_test()); + .union(&WarningFiltersBuilder::unused_warnings_filter_for_test()); run_test(path, &exp_path, &out_path, Flags::empty(), config, lint)?; Ok(()) } diff --git a/external-crates/move/crates/move-core-types/Cargo.toml b/external-crates/move/crates/move-core-types/Cargo.toml index 8b9af6cfa9c..8aa474bd349 100644 --- a/external-crates/move/crates/move-core-types/Cargo.toml +++ b/external-crates/move/crates/move-core-types/Cargo.toml @@ -25,6 +25,7 @@ rand.workspace = true ref-cast.workspace = true serde.workspace = true serde_bytes.workspace = true +serde_with.workspace = true thiserror.workspace = true uint.workspace = true diff --git a/external-crates/move/crates/move-core-types/src/account_address.rs b/external-crates/move/crates/move-core-types/src/account_address.rs index 65e34491430..17b21684a32 100644 --- a/external-crates/move/crates/move-core-types/src/account_address.rs +++ b/external-crates/move/crates/move-core-types/src/account_address.rs @@ -34,6 +34,14 @@ impl AccountAddress { /// Hex address: 0x2 pub const TWO: Self = Self::get_hex_address_two(); + pub const fn from_suffix(suffix: u16) -> AccountAddress { + let mut addr = [0u8; AccountAddress::LENGTH]; + let [hi, lo] = suffix.to_be_bytes(); + addr[AccountAddress::LENGTH - 2] = hi; + addr[AccountAddress::LENGTH - 1] = lo; + AccountAddress::new(addr) + } + const fn get_hex_address_one() -> Self { let mut addr = [0u8; AccountAddress::LENGTH]; addr[AccountAddress::LENGTH - 1] = 1u8; diff --git a/external-crates/move/crates/move-core-types/src/annotated_extractor.rs b/external-crates/move/crates/move-core-types/src/annotated_extractor.rs new file mode 100644 index 00000000000..077bca1d1a2 --- /dev/null +++ b/external-crates/move/crates/move-core-types/src/annotated_extractor.rs @@ -0,0 +1,335 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + account_address::AccountAddress, annotated_value as A, annotated_visitor as AV, + language_storage::TypeTag, +}; + +/// Elements are components of paths that select values from the sub-structure of other values. +/// They are split into two categories: +/// +/// - Selectors, which recurse into the sub-structure. +/// - Filters, which check properties of the value at that position in the sub-structure. +#[derive(Debug, Clone)] +pub enum Element<'e> { + // Selectors + /// Select a named field, assuming the value in question is a struct or an enum variant. + Field(&'e str), + + /// Select a positional element. This can be the element of a vector, or it can be a positional + /// field in an enum or a struct. + Index(u64), + + // Filters + /// Confirm that the current value has a certain type. + Type(&'e TypeTag), + + /// Confirm that the current value is an enum and its variant has this name. Note that to + /// filter on both the enum type and the variant name, the path must contain the Type first, + /// and then the Variant. Otherwise the type filter will be assumed + Variant(&'e str), +} + +/// An Extractor is an [`AV::Visitor`] that deserializes a sub-structure of the value. The +/// sub-structure is found at the end of a path of [`Element`]s which select fields from structs, +/// indices from vectors, and variants from enums. Deserialization is delegated to another visitor, +/// of type `V`, with the Extractor returning `Option`: +/// +/// - `Some(v)` if the given path exists in the value, or +/// - `None` if the path did not exist, +/// - Or an error if the underlying visitor failed for some reason. +/// +/// At every stage, the path can optionally start with an [`Element::Type`], which restricts the +/// type of the top-level value being deserialized. From there, the elements expected are driven by +/// the layout being deserialized: +/// +/// - When deserializing a vector, the next element must be an [`Element::Index`] which selects the +/// offset into the vector that the extractor recurses into. +/// - When deserializing a struct, the next element may be an [`Element::Field`] which selects the +/// field of the struct that the extractor recurses into by name, or an [`Element::Index`] which +/// selects the field by its offset. +/// - When deserializing a variant, the next elements may optionally be an [`Element::Variant`] +/// which expects a particular variant of the enum, followed by either an [`Element::Field`] or +/// an [`Element::Index`], similar to a struct. +pub struct Extractor<'p, 'v, V> { + inner: &'v mut V, + path: &'p [Element<'p>], +} + +impl<'p, 'v, 'b, 'l, V: AV::Visitor<'b, 'l>> Extractor<'p, 'v, V> +where + V::Error: std::error::Error + Send + Sync + 'static, +{ + pub fn new(inner: &'v mut V, path: &'p [Element<'p>]) -> Self { + Self { inner, path } + } + + pub fn deserialize_value( + bytes: &'b [u8], + layout: &'l A::MoveTypeLayout, + inner: &'v mut V, + path: Vec>, + ) -> anyhow::Result> { + let mut extractor = Extractor::new(inner, &path); + A::MoveValue::visit_deserialize(bytes, layout, &mut extractor) + } + + pub fn deserialize_struct( + bytes: &'b [u8], + layout: &'l A::MoveStructLayout, + inner: &'v mut V, + path: Vec>, + ) -> anyhow::Result> { + let mut extractor = Extractor::new(inner, &path); + A::MoveStruct::visit_deserialize(bytes, layout, &mut extractor) + } +} + +impl<'p, 'v, 'b, 'l, V: AV::Visitor<'b, 'l>> AV::Visitor<'b, 'l> for Extractor<'p, 'v, V> { + type Value = Option; + type Error = V::Error; + + fn visit_u8( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: u8, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::U8)] => Some(self.inner.visit_u8(driver, value)?), + _ => None, + }) + } + + fn visit_u16( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: u16, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::U16)] => Some(self.inner.visit_u16(driver, value)?), + _ => None, + }) + } + + fn visit_u32( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: u32, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::U32)] => Some(self.inner.visit_u32(driver, value)?), + _ => None, + }) + } + + fn visit_u64( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::U64)] => Some(self.inner.visit_u64(driver, value)?), + _ => None, + }) + } + + fn visit_u128( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: u128, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::U128)] => Some(self.inner.visit_u128(driver, value)?), + _ => None, + }) + } + + fn visit_u256( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: crate::u256::U256, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::U256)] => Some(self.inner.visit_u256(driver, value)?), + _ => None, + }) + } + + fn visit_bool( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: bool, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::Bool)] => Some(self.inner.visit_bool(driver, value)?), + _ => None, + }) + } + + fn visit_address( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::Address)] => { + Some(self.inner.visit_address(driver, value)?) + } + _ => None, + }) + } + + fn visit_signer( + &mut self, + driver: &AV::ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { + Ok(match self.path { + [] | [Element::Type(&TypeTag::Signer)] => Some(self.inner.visit_signer(driver, value)?), + _ => None, + }) + } + + fn visit_vector( + &mut self, + driver: &mut AV::VecDriver<'_, 'b, 'l>, + ) -> Result { + use Element as E; + use TypeTag as T; + + // If there is a type element, check that it is a vector type with the correct element + // type, and remove it from the path. + let path = if let [E::Type(t), path @ ..] = self.path { + if !matches!(t, T::Vector(t) if driver.element_layout().is_type(t)) { + return Ok(None); + } + path + } else { + self.path + }; + + // If there are no further path elements, we can delegate to the inner visitor. + let [index, path @ ..] = path else { + return Ok(Some(self.inner.visit_vector(driver)?)); + }; + + // Visiting a vector, the next part of the path must be an index -- anything else is + // guaranteed to fail. + let E::Index(i) = index else { + return Ok(None); + }; + + // Skip all the elements before the index, and then recurse. + while driver.off() < *i && driver.skip_element()? {} + Ok(driver + .next_element(&mut Extractor { + inner: self.inner, + path, + })? + .flatten()) + } + + fn visit_struct( + &mut self, + driver: &mut AV::StructDriver<'_, 'b, 'l>, + ) -> Result { + use Element as E; + use TypeTag as T; + + // If there is a type element, check that it is a struct type with the correct struct tag, + // and remove it from the path. + let path = if let [E::Type(t), path @ ..] = self.path { + if !matches!(t, T::Struct(t) if driver.struct_layout().is_type(t)) { + return Ok(None); + } + path + } else { + self.path + }; + + // If there are no further path elements, we can delegate to the inner visitor. + let [field, path @ ..] = path else { + return Ok(Some(self.inner.visit_struct(driver)?)); + }; + + match field { + // Skip over mismatched fields by name. + E::Field(f) => { + while matches!(driver.peek_field(), Some(l) if l.name.as_str() != *f) { + driver.skip_field()?; + } + } + + // Skip over fields by offset. + E::Index(i) => while driver.off() < *i && driver.skip_field()?.is_some() {}, + + // Any other element is invalid in this position. + _ => return Ok(None), + } + + Ok(driver + .next_field(&mut Extractor { + inner: self.inner, + path, + })? + .and_then(|(_, v)| v)) + } + + fn visit_variant( + &mut self, + driver: &mut AV::VariantDriver<'_, 'b, 'l>, + ) -> Result { + use Element as E; + use TypeTag as T; + + // If there is a type element, check that it is a struct type with the correct struct tag, + // and remove it from the path. + let path = if let [E::Type(t), path @ ..] = self.path { + if !matches!(t, T::Struct(t) if driver.enum_layout().is_type(t)) { + return Ok(None); + } + path + } else { + self.path + }; + + // If there is a variant element, check that it matches and remove it from the path. + let path = if let [E::Variant(v), path @ ..] = path { + if driver.variant_name().as_str() != *v { + return Ok(None); + } + path + } else { + path + }; + + // If there are no further path elements, we can delegate to the inner visitor. + let [field, path @ ..] = path else { + return Ok(Some(self.inner.visit_variant(driver)?)); + }; + + match field { + // Skip over mismatched fields by name. + E::Field(f) => { + while matches!(driver.peek_field(), Some(l) if l.name.as_str() != *f) { + driver.skip_field()?; + } + } + + // Skip over fields by offset. + E::Index(i) => while driver.off() < *i && driver.skip_field()?.is_some() {}, + + // Any other element is invalid in this position. + _ => return Ok(None), + } + + Ok(driver + .next_field(&mut Extractor { + inner: self.inner, + path, + })? + .and_then(|(_, v)| v)) + } +} diff --git a/external-crates/move/crates/move-core-types/src/annotated_value.rs b/external-crates/move/crates/move-core-types/src/annotated_value.rs index 8bd7df72268..09e4e710761 100644 --- a/external-crates/move/crates/move-core-types/src/annotated_value.rs +++ b/external-crates/move/crates/move-core-types/src/annotated_value.rs @@ -6,22 +6,24 @@ use std::{ collections::BTreeMap, fmt::{self, Debug}, + io::Cursor, }; use anyhow::Result as AResult; use serde::{ + Deserialize, Serialize, de::Error as DeError, ser::{SerializeMap, SerializeSeq, SerializeStruct}, - Deserialize, Serialize, }; use crate::{ + VARIANT_COUNT_MAX, account_address::AccountAddress, - annotated_visitor::{visit_struct, visit_value, Error as VError, Visitor}, + annotated_visitor::{Error as VError, ValueDriver, Visitor, visit_struct, visit_value}, identifier::Identifier, language_storage::{StructTag, TypeTag}, runtime_value::{self as R, MOVE_STRUCT_FIELDS, MOVE_STRUCT_TYPE}, - u256, VARIANT_COUNT_MAX, + u256, }; /// In the `WithTypes` configuration, a Move struct gets serialized into a Serde @@ -79,7 +81,7 @@ pub enum MoveValue { Variant(MoveVariant), } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct MoveFieldLayout { pub name: Identifier, pub layout: MoveTypeLayout, @@ -91,15 +93,15 @@ impl MoveFieldLayout { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct MoveStructLayout { /// An decorated representation with both types and human-readable field /// names pub type_: StructTag, - pub fields: Vec, + pub fields: Box>, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct MoveEnumLayout { pub type_: StructTag, pub variants: BTreeMap<(Identifier, u16), Vec>, @@ -107,8 +109,8 @@ pub struct MoveEnumLayout { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum MoveDatatypeLayout { - Struct(MoveStructLayout), - Enum(MoveEnumLayout), + Struct(Box), + Enum(Box), } impl MoveDatatypeLayout { @@ -120,7 +122,7 @@ impl MoveDatatypeLayout { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum MoveTypeLayout { #[serde(rename(serialize = "bool", deserialize = "bool"))] Bool, @@ -135,7 +137,7 @@ pub enum MoveTypeLayout { #[serde(rename(serialize = "vector", deserialize = "vector"))] Vector(Box), #[serde(rename(serialize = "struct", deserialize = "struct"))] - Struct(MoveStructLayout), + Struct(Box), #[serde(rename(serialize = "signer", deserialize = "signer"))] Signer, @@ -147,7 +149,44 @@ pub enum MoveTypeLayout { #[serde(rename(serialize = "u256", deserialize = "u256"))] U256, #[serde(rename(serialize = "enum", deserialize = "enum"))] - Enum(MoveEnumLayout), + Enum(Box), +} + +impl MoveStructLayout { + /// Returns `true` if and only if the layout is for `type_`. + pub fn is_type(&self, type_: &StructTag) -> bool { + self.type_ == *type_ + } +} + +impl MoveEnumLayout { + /// Returns `true` if and only if the layout is for `type_`. + pub fn is_type(&self, type_: &StructTag) -> bool { + self.type_ == *type_ + } +} + +impl MoveTypeLayout { + /// Returns `true` if and only if the layout is for `type_`. + pub fn is_type(&self, type_: &TypeTag) -> bool { + use MoveTypeLayout as L; + use TypeTag as T; + + match self { + L::Bool => matches!(type_, T::Bool), + L::U8 => matches!(type_, T::U8), + L::U16 => matches!(type_, T::U16), + L::U32 => matches!(type_, T::U32), + L::U64 => matches!(type_, T::U64), + L::U128 => matches!(type_, T::U128), + L::U256 => matches!(type_, T::U256), + L::Address => matches!(type_, T::Address), + L::Signer => matches!(type_, T::Signer), + L::Vector(l) => matches!(type_, T::Vector(t) if l.is_type(t)), + L::Struct(l) => matches!(type_, T::Struct(t) if l.is_type(t)), + L::Enum(l) => matches!(type_, T::Struct(t) if l.is_type(t)), + } + } } impl MoveValue { @@ -179,19 +218,21 @@ impl MoveValue { /// Deserialization can fail because of an issue in the serialized format /// (data doesn't match layout, unexpected bytes or trailing bytes), or /// a custom error expressed by the visitor. - pub fn visit_deserialize( - mut blob: &[u8], - ty: &MoveTypeLayout, + pub fn visit_deserialize<'b, 'l, V: Visitor<'b, 'l>>( + blob: &'b [u8], + ty: &'l MoveTypeLayout, visitor: &mut V, ) -> AResult where V::Error: std::error::Error + Send + Sync + 'static, { - let res = visit_value(&mut blob, ty, visitor)?; - if blob.is_empty() { + let mut bytes = Cursor::new(blob); + let res = visit_value(&mut bytes, ty, visitor)?; + if bytes.position() as usize == blob.len() { Ok(res) } else { - Err(VError::TrailingBytes(blob.len()).into()) + let remaining = blob.len() - bytes.position() as usize; + Err(VError::TrailingBytes(remaining).into()) } } @@ -245,19 +286,22 @@ impl MoveStruct { /// Like `MoveValue::visit_deserialize` (see for details), but specialized /// to visiting a struct (the `blob` is known to be a serialized Move /// struct, and the layout is a `MoveStructLayout`). - pub fn visit_deserialize( - mut blob: &[u8], - ty: &MoveStructLayout, + pub fn visit_deserialize<'b, 'l, V: Visitor<'b, 'l>>( + blob: &'b [u8], + ty: &'l MoveStructLayout, visitor: &mut V, ) -> AResult where V::Error: std::error::Error + Send + Sync + 'static, { - let res = visit_struct(&mut blob, ty, visitor)?; - if blob.is_empty() { + let mut bytes = Cursor::new(blob); + let driver = ValueDriver::new(&mut bytes, None); + let res = visit_struct(driver, ty, visitor)?; + if bytes.position() as usize == blob.len() { Ok(res) } else { - Err(VError::TrailingBytes(blob.len()).into()) + let remaining = blob.len() - bytes.position() as usize; + Err(VError::TrailingBytes(remaining).into()) } } @@ -312,7 +356,10 @@ impl MoveVariant { impl MoveStructLayout { pub fn new(type_: StructTag, fields: Vec) -> Self { - Self { type_, fields } + Self { + type_, + fields: Box::new(fields), + } } pub fn into_fields(self) -> Vec { @@ -604,7 +651,7 @@ impl fmt::Display for MoveStructLayout { write!(f, "struct ")?; write!(f, "{} ", self.type_)?; let mut map = f.debug_map(); - for field in &self.fields { + for field in &*self.fields { map.entry(&DD(&field.name), &DD(&field.layout)); } map.finish() @@ -652,8 +699,8 @@ impl From<&MoveTypeLayout> for TypeTag { let inner_type = &**v; TypeTag::Vector(Box::new(inner_type.into())) } - MoveTypeLayout::Struct(v) => TypeTag::Struct(Box::new(v.into())), - MoveTypeLayout::Enum(e) => TypeTag::Struct(Box::new(e.into())), + MoveTypeLayout::Struct(v) => TypeTag::Struct(Box::new(v.as_ref().into())), + MoveTypeLayout::Enum(e) => TypeTag::Struct(Box::new(e.as_ref().into())), } } } diff --git a/external-crates/move/crates/move-core-types/src/annotated_visitor.rs b/external-crates/move/crates/move-core-types/src/annotated_visitor.rs index 432b38722cc..6452f5931ff 100644 --- a/external-crates/move/crates/move-core-types/src/annotated_visitor.rs +++ b/external-crates/move/crates/move-core-types/src/annotated_visitor.rs @@ -2,19 +2,19 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::io::Read; +use std::io::{Cursor, Read}; use crate::{ + VARIANT_COUNT_MAX, account_address::AccountAddress, annotated_value::{MoveEnumLayout, MoveFieldLayout, MoveStructLayout, MoveTypeLayout}, identifier::IdentStr, u256::U256, - VARIANT_COUNT_MAX, }; /// Visitors can be used for building values out of a serialized Move struct or /// value. -pub trait Visitor { +pub trait Visitor<'b, 'l> { type Value; /// Visitors can return any error as long as it can represent an error from @@ -32,29 +32,73 @@ pub trait Visitor { /// ``` type Error: From; - fn visit_u8(&mut self, value: u8) -> Result; - fn visit_u16(&mut self, value: u16) -> Result; - fn visit_u32(&mut self, value: u32) -> Result; - fn visit_u64(&mut self, value: u64) -> Result; - fn visit_u128(&mut self, value: u128) -> Result; - fn visit_u256(&mut self, value: U256) -> Result; - fn visit_bool(&mut self, value: bool) -> Result; - fn visit_address(&mut self, value: AccountAddress) -> Result; - fn visit_signer(&mut self, value: AccountAddress) -> Result; + fn visit_u8( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u8, + ) -> Result; + + fn visit_u16( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u16, + ) -> Result; + + fn visit_u32( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u32, + ) -> Result; + + fn visit_u64( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result; + + fn visit_u128( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u128, + ) -> Result; + + fn visit_u256( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: U256, + ) -> Result; + + fn visit_bool( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: bool, + ) -> Result; + + fn visit_address( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result; + + fn visit_signer( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result; fn visit_vector( &mut self, - driver: &mut VecDriver<'_, '_, '_>, + driver: &mut VecDriver<'_, 'b, 'l>, ) -> Result; fn visit_struct( &mut self, - driver: &mut StructDriver<'_, '_, '_>, + driver: &mut StructDriver<'_, 'b, 'l>, ) -> Result; fn visit_variant( &mut self, - driver: &mut VariantDriver<'_, '_, '_>, + driver: &mut VariantDriver<'_, 'b, 'l>, ) -> Result; } @@ -71,53 +115,89 @@ pub trait Visitor { /// Ok(()) /// } /// ``` -pub trait Traversal { +pub trait Traversal<'b, 'l> { type Error: From; - fn traverse_u8(&mut self, _value: u8) -> Result<(), Self::Error> { + fn traverse_u8( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u8, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_u16(&mut self, _value: u16) -> Result<(), Self::Error> { + fn traverse_u16( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u16, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_u32(&mut self, _value: u32) -> Result<(), Self::Error> { + fn traverse_u32( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u32, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_u64(&mut self, _value: u64) -> Result<(), Self::Error> { + fn traverse_u64( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u64, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_u128(&mut self, _value: u128) -> Result<(), Self::Error> { + fn traverse_u128( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u128, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_u256(&mut self, _value: U256) -> Result<(), Self::Error> { + fn traverse_u256( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: U256, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_bool(&mut self, _value: bool) -> Result<(), Self::Error> { + fn traverse_bool( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: bool, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_address(&mut self, _value: AccountAddress) -> Result<(), Self::Error> { + fn traverse_address( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: AccountAddress, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_signer(&mut self, _value: AccountAddress) -> Result<(), Self::Error> { + fn traverse_signer( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: AccountAddress, + ) -> Result<(), Self::Error> { Ok(()) } - fn traverse_vector(&mut self, driver: &mut VecDriver<'_, '_, '_>) -> Result<(), Self::Error> { + fn traverse_vector(&mut self, driver: &mut VecDriver<'_, 'b, 'l>) -> Result<(), Self::Error> { while driver.next_element(self)?.is_some() {} Ok(()) } fn traverse_struct( &mut self, - driver: &mut StructDriver<'_, '_, '_>, + driver: &mut StructDriver<'_, 'b, 'l>, ) -> Result<(), Self::Error> { while driver.next_field(self)?.is_some() {} Ok(()) @@ -125,7 +205,7 @@ pub trait Traversal { fn traverse_variant( &mut self, - driver: &mut VariantDriver<'_, '_, '_>, + driver: &mut VariantDriver<'_, 'b, 'l>, ) -> Result<(), Self::Error> { while driver.next_field(self)?.is_some() {} Ok(()) @@ -133,73 +213,118 @@ pub trait Traversal { } /// Default implementation converting any traversal into a visitor. -impl Visitor for T { +impl<'b, 'l, T: Traversal<'b, 'l> + ?Sized> Visitor<'b, 'l> for T { type Value = (); type Error = T::Error; - fn visit_u8(&mut self, value: u8) -> Result { - self.traverse_u8(value) + fn visit_u8( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u8, + ) -> Result { + self.traverse_u8(driver, value) } - fn visit_u16(&mut self, value: u16) -> Result { - self.traverse_u16(value) + fn visit_u16( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u16, + ) -> Result { + self.traverse_u16(driver, value) } - fn visit_u32(&mut self, value: u32) -> Result { - self.traverse_u32(value) + fn visit_u32( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u32, + ) -> Result { + self.traverse_u32(driver, value) } - fn visit_u64(&mut self, value: u64) -> Result { - self.traverse_u64(value) + fn visit_u64( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result { + self.traverse_u64(driver, value) } - fn visit_u128(&mut self, value: u128) -> Result { - self.traverse_u128(value) + fn visit_u128( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u128, + ) -> Result { + self.traverse_u128(driver, value) } - fn visit_u256(&mut self, value: U256) -> Result { - self.traverse_u256(value) + fn visit_u256( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: U256, + ) -> Result { + self.traverse_u256(driver, value) } - fn visit_bool(&mut self, value: bool) -> Result { - self.traverse_bool(value) + fn visit_bool( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: bool, + ) -> Result { + self.traverse_bool(driver, value) } - fn visit_address(&mut self, value: AccountAddress) -> Result { - self.traverse_address(value) + fn visit_address( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { + self.traverse_address(driver, value) } - fn visit_signer(&mut self, value: AccountAddress) -> Result { - self.traverse_signer(value) + fn visit_signer( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { + self.traverse_signer(driver, value) } fn visit_vector( &mut self, - driver: &mut VecDriver<'_, '_, '_>, + driver: &mut VecDriver<'_, 'b, 'l>, ) -> Result { self.traverse_vector(driver) } fn visit_struct( &mut self, - driver: &mut StructDriver<'_, '_, '_>, + driver: &mut StructDriver<'_, 'b, 'l>, ) -> Result { self.traverse_struct(driver) } fn visit_variant( &mut self, - driver: &mut VariantDriver<'_, '_, '_>, + driver: &mut VariantDriver<'_, 'b, 'l>, ) -> Result { self.traverse_variant(driver) } } +/// Exposes information about the byte stream that the value being visited came +/// from, namely the bytes themselves, and the offset at which the value starts. +/// Also exposes the layout of the value being visited. +pub struct ValueDriver<'c, 'b, 'l> { + bytes: &'c mut Cursor<&'b [u8]>, + layout: Option<&'l MoveTypeLayout>, + start: usize, +} + /// Exposes information about a vector being visited (the element layout) to a /// visitor implementation, and allows that visitor to progress the traversal /// (by visiting or skipping elements). -pub struct VecDriver<'r, 'b, 'l> { - bytes: &'r mut &'b [u8], +pub struct VecDriver<'c, 'b, 'l> { + inner: ValueDriver<'c, 'b, 'l>, layout: &'l MoveTypeLayout, len: u64, off: u64, @@ -208,23 +333,23 @@ pub struct VecDriver<'r, 'b, 'l> { /// Exposes information about a struct being visited (its layout, details about /// the next field to be visited) to a visitor implementation, and allows that /// visitor to progress the traversal (by visiting or skipping fields). -pub struct StructDriver<'r, 'b, 'l> { - bytes: &'r mut &'b [u8], +pub struct StructDriver<'c, 'b, 'l> { + inner: ValueDriver<'c, 'b, 'l>, layout: &'l MoveStructLayout, - off: usize, + off: u64, } /// Exposes information about a variant being visited (its layout, details about /// the next field to be visited, the variant's tag, and name) to a visitor /// implementation, and allows that visitor to progress the traversal (by /// visiting or skipping fields). -pub struct VariantDriver<'r, 'b, 'l> { - bytes: &'r mut &'b [u8], +pub struct VariantDriver<'c, 'b, 'l> { + inner: ValueDriver<'c, 'b, 'l>, layout: &'l MoveEnumLayout, tag: u16, variant_name: &'l IdentStr, variant_layout: &'l [MoveFieldLayout], - off: usize, + off: u64, } #[derive(thiserror::Error, Debug)] @@ -240,6 +365,9 @@ pub enum Error { #[error("invalid variant tag: {0}")] UnexpectedVariantTag(usize), + + #[error("no layout available for value")] + NoValueLayout, } /// The null traversal implements `Traversal` and `Visitor` but without doing @@ -247,27 +375,104 @@ pub enum Error { /// useful for skipping over parts of the value structure. pub struct NullTraversal; -impl Traversal for NullTraversal { +impl<'b, 'l> Traversal<'b, 'l> for NullTraversal { type Error = Error; } -#[allow(clippy::len_without_is_empty)] -impl<'r, 'b, 'l> VecDriver<'r, 'b, 'l> { - fn new(bytes: &'r mut &'b [u8], layout: &'l MoveTypeLayout, len: u64) -> Self { +impl<'c, 'b, 'l> ValueDriver<'c, 'b, 'l> { + pub(crate) fn new(bytes: &'c mut Cursor<&'b [u8]>, layout: Option<&'l MoveTypeLayout>) -> Self { + let start = bytes.position() as usize; Self { bytes, layout, + start, + } + } + + /// The offset at which the value being visited starts in the byte stream. + pub fn start(&self) -> usize { + self.start + } + + /// The current position in the byte stream. + pub fn position(&self) -> usize { + self.bytes.position() as usize + } + + /// All the bytes in the byte stream (including the ones that have been + /// read). + pub fn bytes(&self) -> &'b [u8] { + self.bytes.get_ref() + } + /// The bytes that haven't been consumed by the visitor yet. + pub fn remaining_bytes(&self) -> &'b [u8] { + &self.bytes.get_ref()[self.position()..] + } + + /// Type layout for the value being visited. May produce an error if a + /// layout was not supplied when the driver was created (which should + /// only happen if the driver was created for visiting a struct + /// specifically). + pub fn layout(&self) -> Result<&'l MoveTypeLayout, Error> { + self.layout.ok_or(Error::NoValueLayout) + } + + fn read_exact(&mut self) -> Result<[u8; N], Error> { + let mut buf = [0u8; N]; + self.bytes + .read_exact(&mut buf) + .map_err(|_| Error::UnexpectedEof)?; + Ok(buf) + } + + fn read_leb128(&mut self) -> Result { + leb128::read::unsigned(self.bytes).map_err(|_| Error::UnexpectedEof) + } +} + +#[allow(clippy::len_without_is_empty)] +impl<'c, 'b, 'l> VecDriver<'c, 'b, 'l> { + fn new(inner: ValueDriver<'c, 'b, 'l>, layout: &'l MoveTypeLayout, len: u64) -> Self { + Self { + inner, + layout, len, off: 0, } } + /// The offset at which the value being visited starts in the byte stream. + pub fn start(&self) -> usize { + self.inner.start() + } + + /// The current position in the byte stream. + pub fn position(&self) -> usize { + self.inner.position() + } + + /// All the bytes in the byte stream (including the ones that have been + /// read). + pub fn bytes(&self) -> &'b [u8] { + self.inner.bytes() + } + + /// The bytes that haven't been consumed by the visitor yet. + pub fn remaining_bytes(&self) -> &'b [u8] { + self.inner.remaining_bytes() + } + /// Type layout for the vector's inner type. pub fn element_layout(&self) -> &'l MoveTypeLayout { self.layout } - /// The number of elements in this vector + /// The number of elements in this vector that have been visited so far. + pub fn off(&self) -> u64 { + self.off + } + + /// The number of elements in this vector. pub fn len(&self) -> u64 { self.len } @@ -285,14 +490,14 @@ impl<'r, 'b, 'l> VecDriver<'r, 'b, 'l> { /// if there was an element and it was successfully visited (where `v` /// is the value returned by the visitor) or an error if there was an /// underlying deserialization error, or an error during visitation. - pub fn next_element( + pub fn next_element + ?Sized>( &mut self, visitor: &mut V, ) -> Result, V::Error> { Ok(if self.off >= self.len { None } else { - let res = visit_value(self.bytes, self.layout, visitor)?; + let res = visit_value(self.inner.bytes, self.layout, visitor)?; self.off += 1; Some(res) }) @@ -306,24 +511,50 @@ impl<'r, 'b, 'l> VecDriver<'r, 'b, 'l> { } } -impl<'r, 'b, 'l> StructDriver<'r, 'b, 'l> { - fn new(bytes: &'r mut &'b [u8], layout: &'l MoveStructLayout) -> Self { +impl<'c, 'b, 'l> StructDriver<'c, 'b, 'l> { + fn new(inner: ValueDriver<'c, 'b, 'l>, layout: &'l MoveStructLayout) -> Self { Self { - bytes, + inner, layout, off: 0, } } + /// The offset at which the value being visited starts in the byte stream. + pub fn start(&self) -> usize { + self.inner.start() + } + + /// The current position in the byte stream. + pub fn position(&self) -> usize { + self.inner.position() + } + + /// All the bytes in the byte stream (including the ones that have been + /// read). + pub fn bytes(&self) -> &'b [u8] { + self.inner.bytes() + } + + /// The bytes that haven't been consumed by the visitor yet. + pub fn remaining_bytes(&self) -> &'b [u8] { + self.inner.remaining_bytes() + } + /// The layout of the struct being visited. pub fn struct_layout(&self) -> &'l MoveStructLayout { self.layout } + /// The number of fields in this struct that have been visited so far. + pub fn off(&self) -> u64 { + self.off + } + /// The layout of the next field to be visited (if there is one), or `None` /// otherwise. pub fn peek_field(&self) -> Option<&'l MoveFieldLayout> { - self.layout.fields.get(self.off) + self.layout.fields.get(self.off as usize) } /// Visit the next field in the struct. The driver accepts a visitor to use @@ -335,7 +566,7 @@ impl<'r, 'b, 'l> StructDriver<'r, 'b, 'l> { /// `v` is the value returned by the visitor, and `f` is the layout of /// the field that was visited) or an error if there was an underlying /// deserialization error, or an error during visitation. - pub fn next_field( + pub fn next_field + ?Sized>( &mut self, visitor: &mut V, ) -> Result, V::Error> { @@ -343,7 +574,7 @@ impl<'r, 'b, 'l> StructDriver<'r, 'b, 'l> { return Ok(None); }; - let res = visit_value(self.bytes, &field.layout, visitor)?; + let res = visit_value(self.inner.bytes, &field.layout, visitor)?; self.off += 1; Ok(Some((field, res))) } @@ -357,16 +588,16 @@ impl<'r, 'b, 'l> StructDriver<'r, 'b, 'l> { } } -impl<'r, 'b, 'l> VariantDriver<'r, 'b, 'l> { +impl<'c, 'b, 'l> VariantDriver<'c, 'b, 'l> { fn new( - bytes: &'r mut &'b [u8], + inner: ValueDriver<'c, 'b, 'l>, layout: &'l MoveEnumLayout, variant_layout: &'l [MoveFieldLayout], variant_name: &'l IdentStr, tag: u16, ) -> Self { Self { - bytes, + inner, layout, tag, variant_name, @@ -375,6 +606,27 @@ impl<'r, 'b, 'l> VariantDriver<'r, 'b, 'l> { } } + /// The offset at which the value being visited starts in the byte stream. + pub fn start(&self) -> usize { + self.inner.start() + } + + /// The current position in the byte stream. + pub fn position(&self) -> usize { + self.inner.position() + } + + /// All the bytes in the byte stream (including the ones that have been + /// read). + pub fn bytes(&self) -> &'b [u8] { + self.inner.bytes() + } + + /// The bytes that haven't been consumed by the visitor yet. + pub fn remaining_bytes(&self) -> &'b [u8] { + self.inner.remaining_bytes() + } + /// The layout of the enum being visited. pub fn enum_layout(&self) -> &'l MoveEnumLayout { self.layout @@ -395,10 +647,15 @@ impl<'r, 'b, 'l> VariantDriver<'r, 'b, 'l> { self.variant_name } + /// The number of elements in this vector that have been visited so far. + pub fn off(&self) -> u64 { + self.off + } + /// The layout of the next field to be visited (if there is one), or `None` /// otherwise. pub fn peek_field(&self) -> Option<&'l MoveFieldLayout> { - self.variant_layout.get(self.off) + self.variant_layout.get(self.off as usize) } /// Visit the next field in the variant. The driver accepts a visitor to use @@ -410,7 +667,7 @@ impl<'r, 'b, 'l> VariantDriver<'r, 'b, 'l> { /// `v` is the value returned by the visitor, and `f` is the layout of /// the field that was visited) or an error if there was an underlying /// deserialization error, or an error during visitation. - pub fn next_field( + pub fn next_field + ?Sized>( &mut self, visitor: &mut V, ) -> Result, V::Error> { @@ -418,7 +675,7 @@ impl<'r, 'b, 'l> VariantDriver<'r, 'b, 'l> { return Ok(None); }; - let res = visit_value(self.bytes, &field.layout, visitor)?; + let res = visit_value(self.inner.bytes, &field.layout, visitor)?; self.off += 1; Ok(Some((field, res))) } @@ -434,50 +691,91 @@ impl<'r, 'b, 'l> VariantDriver<'r, 'b, 'l> { /// Visit a serialized Move value with the provided `layout`, held in `bytes`, /// using the provided visitor to build a value out of it. See -/// `annotated_value::MoveValue::visit_deserialize` for details. -pub(crate) fn visit_value( - bytes: &mut &[u8], - layout: &MoveTypeLayout, +/// `annoted_value::MoveValue::visit_deserialize` for details. +pub(crate) fn visit_value<'c, 'b, 'l, V: Visitor<'b, 'l> + ?Sized>( + bytes: &'c mut Cursor<&'b [u8]>, + layout: &'l MoveTypeLayout, visitor: &mut V, ) -> Result { use MoveTypeLayout as L; + let mut driver = ValueDriver::new(bytes, Some(layout)); match layout { - L::Bool => match read_exact::<1>(bytes)? { - [0] => visitor.visit_bool(false), - [1] => visitor.visit_bool(true), + L::Bool => match driver.read_exact()? { + [0] => visitor.visit_bool(&driver, false), + [1] => visitor.visit_bool(&driver, true), [b] => Err(Error::UnexpectedByte(b).into()), }, - L::U8 => visitor.visit_u8(u8::from_le_bytes(read_exact::<1>(bytes)?)), - L::U16 => visitor.visit_u16(u16::from_le_bytes(read_exact::<2>(bytes)?)), - L::U32 => visitor.visit_u32(u32::from_le_bytes(read_exact::<4>(bytes)?)), - L::U64 => visitor.visit_u64(u64::from_le_bytes(read_exact::<8>(bytes)?)), - L::U128 => visitor.visit_u128(u128::from_le_bytes(read_exact::<16>(bytes)?)), - L::U256 => visitor.visit_u256(U256::from_le_bytes(&read_exact::<32>(bytes)?)), - L::Address => visitor.visit_address(AccountAddress::new(read_exact::<32>(bytes)?)), - L::Signer => visitor.visit_signer(AccountAddress::new(read_exact::<32>(bytes)?)), - - L::Vector(l) => { - let len = leb128::read::unsigned(bytes).map_err(|_| Error::UnexpectedEof)?; - let mut driver = VecDriver::new(bytes, l.as_ref(), len); - let res = visitor.visit_vector(&mut driver)?; - while driver.skip_element()? {} - Ok(res) + L::U8 => { + let v = u8::from_le_bytes(driver.read_exact()?); + visitor.visit_u8(&driver, v) } - L::Enum(e) => visit_variant(bytes, e, visitor), - L::Struct(l) => visit_struct(bytes, l, visitor), + + L::U16 => { + let v = u16::from_le_bytes(driver.read_exact()?); + visitor.visit_u16(&driver, v) + } + + L::U32 => { + let v = u32::from_le_bytes(driver.read_exact()?); + visitor.visit_u32(&driver, v) + } + + L::U64 => { + let v = u64::from_le_bytes(driver.read_exact()?); + visitor.visit_u64(&driver, v) + } + + L::U128 => { + let v = u128::from_le_bytes(driver.read_exact()?); + visitor.visit_u128(&driver, v) + } + + L::U256 => { + let v = U256::from_le_bytes(&driver.read_exact()?); + visitor.visit_u256(&driver, v) + } + + L::Address => { + let v = AccountAddress::new(driver.read_exact()?); + visitor.visit_address(&driver, v) + } + + L::Signer => { + let v = AccountAddress::new(driver.read_exact()?); + visitor.visit_signer(&driver, v) + } + + L::Vector(l) => visit_vector(driver, l.as_ref(), visitor), + L::Struct(l) => visit_struct(driver, l, visitor), + L::Enum(e) => visit_variant(driver, e, visitor), } } +/// Like `visit_value` but specialized to visiting a vector (where the `bytes` +/// is known to be a serialized move vector), and the layout is the vector's +/// element's layout. +fn visit_vector<'c, 'b, 'l, V: Visitor<'b, 'l> + ?Sized>( + mut inner: ValueDriver<'c, 'b, 'l>, + layout: &'l MoveTypeLayout, + visitor: &mut V, +) -> Result { + let len = inner.read_leb128()?; + let mut driver = VecDriver::new(inner, layout, len); + let res = visitor.visit_vector(&mut driver)?; + while driver.skip_element()? {} + Ok(res) +} + /// Like `visit_value` but specialized to visiting a struct (where the `bytes` /// is known to be a serialized move struct), and the layout is a struct layout. -pub(crate) fn visit_struct( - bytes: &mut &[u8], - layout: &MoveStructLayout, +pub(crate) fn visit_struct<'c, 'b, 'l, V: Visitor<'b, 'l> + ?Sized>( + inner: ValueDriver<'c, 'b, 'l>, + layout: &'l MoveStructLayout, visitor: &mut V, ) -> Result { - let mut driver = StructDriver::new(bytes, layout); + let mut driver = StructDriver::new(inner, layout); let res = visitor.visit_struct(&mut driver)?; while driver.skip_field()?.is_some() {} Ok(res) @@ -485,15 +783,15 @@ pub(crate) fn visit_struct( /// Like `visit_struct` but specialized to visiting a variant (where the `bytes` /// is known to be a serialized move variant), and the layout is an enum layout. -pub(crate) fn visit_variant( - bytes: &mut &[u8], - layout: &MoveEnumLayout, +fn visit_variant<'c, 'b, 'l, V: Visitor<'b, 'l> + ?Sized>( + mut inner: ValueDriver<'c, 'b, 'l>, + layout: &'l MoveEnumLayout, visitor: &mut V, ) -> Result { // Since variants are bounded at 127, we can read the tag as a single byte. // When we add true ULEB encoding for enum variants switch to this: - // let tag = leb128::read::unsigned(bytes).map_err(|_| Error::UnexpectedEof)?; - let [tag] = read_exact::<1>(bytes)?; + // let tag = inner.read_leb128()?; + let [tag] = inner.read_exact()?; if tag >= VARIANT_COUNT_MAX as u8 { return Err(Error::UnexpectedVariantTag(tag as usize).into()); } @@ -504,7 +802,7 @@ pub(crate) fn visit_variant( .ok_or(Error::UnexpectedVariantTag(tag as usize))?; let mut driver = VariantDriver::new( - bytes, + inner, layout, variant_layout.1, &variant_layout.0.0, @@ -514,11 +812,3 @@ pub(crate) fn visit_variant( while driver.skip_field()?.is_some() {} Ok(res) } - -fn read_exact(bytes: &mut &[u8]) -> Result<[u8; N], Error> { - let mut buf = [0u8; N]; - bytes - .read_exact(&mut buf) - .map_err(|_| Error::UnexpectedEof)?; - Ok(buf) -} diff --git a/external-crates/move/crates/move-core-types/src/identifier.rs b/external-crates/move/crates/move-core-types/src/identifier.rs index 2701140d3ee..503e43bcb9a 100644 --- a/external-crates/move/crates/move-core-types/src/identifier.rs +++ b/external-crates/move/crates/move-core-types/src/identifier.rs @@ -32,11 +32,12 @@ use std::{borrow::Borrow, fmt, ops::Deref, str::FromStr}; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; #[cfg(any(test, feature = "fuzzing"))] use proptest::prelude::*; use ref_cast::RefCast; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::{DeserializeAs as _, SerializeAs}; use crate::gas_algebra::AbstractMemorySize; @@ -97,12 +98,30 @@ pub(crate) static ALLOWED_NO_SELF_IDENTIFIERS: &str = /// An owned identifier. /// /// For more details, see the module level documentation. -#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))] pub struct Identifier(Box); // An identifier cannot be mutated so use Box instead of String -- it is 1 // word smaller. +impl Serialize for Identifier { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serde_with::DisplayFromStr::serialize_as(self, serializer) + } +} + +impl<'de> Deserialize<'de> for Identifier { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + serde_with::DisplayFromStr::deserialize_as(deserializer) + } +} + impl Identifier { /// Creates a new `Identifier` instance. pub fn new(s: impl Into>) -> Result { @@ -114,6 +133,18 @@ impl Identifier { } } + /// Creates a new `Identifier` from a string without checking if it is a + /// valid identifier. This should not be used under normal + /// circumstances, but is used in cases where we need to + /// preserve backwards compatibility. + /// + /// # Safety + /// + /// Only use this function when preserving backwards compatibility. + pub unsafe fn new_unchecked(s: impl Into>) -> Self { + Self(s.into()) + } + /// Returns true if this string is a valid identifier. pub fn is_valid(s: impl AsRef) -> bool { is_valid(s.as_ref()) diff --git a/external-crates/move/crates/move-core-types/src/language_storage.rs b/external-crates/move/crates/move-core-types/src/language_storage.rs index de01dde227c..c3f1a1314e9 100644 --- a/external-crates/move/crates/move-core-types/src/language_storage.rs +++ b/external-crates/move/crates/move-core-types/src/language_storage.rs @@ -18,7 +18,7 @@ use crate::{ account_address::AccountAddress, gas_algebra::{AbstractMemorySize, BOX_ABSTRACT_SIZE, ENUM_BASE_ABSTRACT_SIZE}, identifier::{IdentStr, Identifier}, - parser::{parse_struct_tag, parse_type_tag}, + parsing::types::{ParsedModuleId, ParsedStructType, ParsedType}, }; pub const CODE_TAG: u8 = 0; @@ -64,23 +64,28 @@ pub enum TypeTag { impl TypeTag { /// Return a canonical string representation of the type. All types are /// represented using their source syntax: - /// "u8", "u64", "u128", "bool", "address", "vector", "signer" for ground - /// types. Struct types are represented as fully qualified type names; - /// e.g. `00000000000000000000000000000001::string::String` or - /// `0000000000000000000000000000000a::module_name1::type_name1<0000000000000000000000000000000a::module_name2::type_name2>` - /// With or without the prefix 0x depending on the `with_prefix` flag. - /// Addresses are hex-encoded lowercase values of length ADDRESS_LENGTH (16, - /// 20, or 32 depending on the Move platform) Note: this function is - /// guaranteed to be stable, and this is suitable for use inside - /// Move native functions or the VM. By contrast, the `Display` - /// implementation is subject to change and should not be used inside - /// stable code. + /// + /// - "bool", "u8", "u16", "u32", "u64", "u128", "u256", "address", + /// "signer", "vector" for ground types. + /// + /// - Structs are represented as fully qualified type names, with or without + /// the prefix "0x" depending on the `with_prefix` flag, e.g. + /// `0x000...0001::string::String` or + /// `0x000...000a::m::T<0x000...000a::n::U>`. + /// + /// - Addresses are hex-encoded lowercase values of length 32 (zero-padded). + /// + /// Note: this function is guaranteed to be stable -- suitable for use + /// inside Move native functions or the VM. By contrast, this type's + /// `Display` implementation is subject to change and should be used + /// inside code that needs to return a stable output (e.g. that might be + /// committed to effects on-chain). pub fn to_canonical_string(&self, with_prefix: bool) -> String { self.to_canonical_display(with_prefix).to_string() } - /// Return the canonical string representation of the TypeTag conditionally - /// with prefix 0x + /// Implements the canonical string representation of the type with optional + /// prefix 0x pub fn to_canonical_display(&self, with_prefix: bool) -> impl std::fmt::Display + '_ { struct CanonicalDisplay<'a> { data: &'a TypeTag, @@ -138,7 +143,7 @@ impl FromStr for TypeTag { type Err = anyhow::Error; fn from_str(s: &str) -> Result { - parse_type_tag(s) + ParsedType::parse(s)?.into_type_tag(&|_| None) } } @@ -180,23 +185,25 @@ impl StructTag { } /// Return a canonical string representation of the struct. - /// Struct types are represented as fully qualified type names; e.g. - /// `00000000000000000000000000000001::string::String`, - /// `0000000000000000000000000000000a::module_name1::type_name1<0000000000000000000000000000000a::module_name2::type_name2>`, - /// or `0000000000000000000000000000000a::module_name2::type_name2. With or without the prefix 0x depending on the `with_prefix` - /// flag. Addresses are hex-encoded lowercase values of length - /// ADDRESS_LENGTH (16, 20, or 32 depending on the Move platform) - /// Note: this function is guaranteed to be stable, and this is suitable for - /// use inside Move native functions or the VM. By contrast, the - /// `Display` implementation is subject to change and should not be used - /// inside stable code. + /// + /// - Structs are represented as fully qualified type names, with or without + /// the prefix "0x" depending on the `with_prefix` flag, e.g. + /// `0x000...0001::string::String` or + /// `0x000...000a::m::T<0x000...000a::n::U>`. + /// + /// - Addresses are hex-encoded lowercase values of length 32 (zero-padded). + /// + /// Note: this function is guaranteed to be stable -- suitable for use + /// inside Move native functions or the VM. By contrast, this type's + /// `Display` implementation is subject to change and should be used + /// inside code that needs to return a stable output (e.g. that might be + /// committed to effects on-chain). pub fn to_canonical_string(&self, with_prefix: bool) -> String { self.to_canonical_display(with_prefix).to_string() } - /// Implements the canonical string representation of the StructTag with the - /// prefix 0x + /// Implements the canonical string representation of the StructTag with + /// optional prefix 0x pub fn to_canonical_display(&self, with_prefix: bool) -> impl std::fmt::Display + '_ { struct CanonicalDisplay<'a> { data: &'a StructTag, @@ -255,7 +262,7 @@ impl FromStr for StructTag { type Err = anyhow::Error; fn from_str(s: &str) -> Result { - parse_struct_tag(s) + ParsedStructType::parse(s)?.into_struct_tag(&|_| None) } } @@ -331,6 +338,13 @@ impl Display for ModuleId { } } +impl FromStr for ModuleId { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + ParsedModuleId::parse(s)?.into_module_id(&|_| None) + } +} + impl ModuleId { pub fn short_str_lossless(&self) -> String { format!("0x{}::{}", self.address.short_str_lossless(), self.name) diff --git a/external-crates/move/crates/move-core-types/src/lib.rs b/external-crates/move/crates/move-core-types/src/lib.rs index 4399e7b935e..83b3a77a145 100644 --- a/external-crates/move/crates/move-core-types/src/lib.rs +++ b/external-crates/move/crates/move-core-types/src/lib.rs @@ -9,6 +9,7 @@ use std::fmt; pub mod abi; pub mod account_address; +pub mod annotated_extractor; pub mod annotated_value; pub mod annotated_visitor; pub mod effects; @@ -18,7 +19,7 @@ pub mod identifier; pub mod language_storage; pub mod metadata; pub mod move_resource; -pub mod parser; +pub mod parsing; #[cfg(any(test, feature = "fuzzing"))] pub mod proptest_types; pub mod resolver; diff --git a/external-crates/move/crates/move-core-types/src/parser.rs b/external-crates/move/crates/move-core-types/src/parser.rs deleted file mode 100644 index dac8cb26ca5..00000000000 --- a/external-crates/move/crates/move-core-types/src/parser.rs +++ /dev/null @@ -1,635 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use std::iter::Peekable; - -use anyhow::{bail, format_err, Result}; - -use crate::{ - account_address::AccountAddress, - identifier::{self, Identifier}, - language_storage::{StructTag, TypeTag}, - transaction_argument::TransactionArgument, -}; - -#[derive(Eq, PartialEq, Debug)] -enum Token { - U8Type, - U16Type, - U32Type, - U64Type, - U128Type, - U256Type, - BoolType, - AddressType, - VectorType, - SignerType, - Whitespace(String), - Name(String), - Address(String), - U8(String), - U16(String), - U32(String), - U64(String), - U128(String), - U256(String), - - Bytes(String), - True, - False, - ColonColon, - Lt, - Gt, - Comma, - EOF, -} - -impl Token { - fn is_whitespace(&self) -> bool { - matches!(self, Self::Whitespace(_)) - } -} - -fn token_as_name(tok: Token) -> Result { - use Token::*; - Ok(match tok { - U8Type => "u8".to_string(), - U16Type => "u16".to_string(), - U32Type => "u32".to_string(), - U64Type => "u64".to_string(), - U128Type => "u128".to_string(), - U256Type => "u256".to_string(), - BoolType => "bool".to_string(), - AddressType => "address".to_string(), - VectorType => "vector".to_string(), - True => "true".to_string(), - False => "false".to_string(), - SignerType => "signer".to_string(), - Name(s) => s, - Whitespace(_) | Address(_) | U8(_) | U16(_) | U32(_) | U64(_) | U128(_) | U256(_) - | Bytes(_) | ColonColon | Lt | Gt | Comma | EOF => { - bail!("Invalid token. Expected a name but got {:?}", tok) - } - }) -} - -fn name_token(s: String) -> Token { - match s.as_str() { - "u8" => Token::U8Type, - "u16" => Token::U16Type, - "u32" => Token::U32Type, - "u64" => Token::U64Type, - "u128" => Token::U128Type, - "u256" => Token::U256Type, - "bool" => Token::BoolType, - "address" => Token::AddressType, - "vector" => Token::VectorType, - "true" => Token::True, - "false" => Token::False, - "signer" => Token::SignerType, - _ => Token::Name(s), - } -} - -fn next_number(initial: char, mut it: impl Iterator) -> Result<(Token, usize)> { - let mut num = String::new(); - num.push(initial); - loop { - match it.next() { - Some(c) if c.is_ascii_digit() || c == '_' => num.push(c), - Some(c) if c.is_alphanumeric() => { - let mut suffix = String::new(); - suffix.push(c); - loop { - match it.next() { - Some(c) if c.is_ascii_alphanumeric() => suffix.push(c), - _ => { - let len = num.len() + suffix.len(); - let tok = match suffix.as_str() { - "u8" => Token::U8(num), - "u16" => Token::U16(num), - "u32" => Token::U32(num), - "u64" => Token::U64(num), - "u128" => Token::U128(num), - "u256" => Token::U256(num), - _ => bail!("invalid suffix"), - }; - return Ok((tok, len)); - } - } - } - } - _ => { - let len = num.len(); - return Ok((Token::U64(num), len)); - } - } - } -} - -#[allow(clippy::many_single_char_names)] -fn next_token(s: &str) -> Result> { - let mut it = s.chars().peekable(); - match it.next() { - None => Ok(None), - Some(c) => Ok(Some(match c { - '<' => (Token::Lt, 1), - '>' => (Token::Gt, 1), - ',' => (Token::Comma, 1), - ':' => match it.next() { - Some(':') => (Token::ColonColon, 2), - _ => bail!("unrecognized token"), - }, - '0' if it.peek() == Some(&'x') || it.peek() == Some(&'X') => { - it.next().unwrap(); - match it.next() { - Some(c) if c.is_ascii_hexdigit() => { - let mut r = String::new(); - r.push('0'); - r.push('x'); - r.push(c); - for c in it { - if c.is_ascii_hexdigit() { - r.push(c); - } else { - break; - } - } - let len = r.len(); - (Token::Address(r), len) - } - _ => bail!("unrecognized token"), - } - } - c if c.is_ascii_digit() => next_number(c, it)?, - 'b' if it.peek() == Some(&'"') => { - it.next().unwrap(); - let mut r = String::new(); - loop { - match it.next() { - Some('"') => break, - Some(c) if c.is_ascii() => r.push(c), - _ => bail!("unrecognized token"), - } - } - let len = r.len() + 3; - (Token::Bytes(hex::encode(r)), len) - } - 'x' if it.peek() == Some(&'"') => { - it.next().unwrap(); - let mut r = String::new(); - loop { - match it.next() { - Some('"') => break, - Some(c) if c.is_ascii_hexdigit() => r.push(c), - _ => bail!("unrecognized token"), - } - } - let len = r.len() + 3; - (Token::Bytes(r), len) - } - c if c.is_ascii_whitespace() => { - let mut r = String::new(); - r.push(c); - for c in it { - if c.is_ascii_whitespace() { - r.push(c); - } else { - break; - } - } - let len = r.len(); - (Token::Whitespace(r), len) - } - c if c.is_ascii_alphabetic() => { - let mut r = String::new(); - r.push(c); - for c in it { - if identifier::is_valid_identifier_char(c) { - r.push(c); - } else { - break; - } - } - let len = r.len(); - (name_token(r), len) - } - _ => bail!("unrecognized token"), - })), - } -} - -fn tokenize(mut s: &str) -> Result> { - let mut v = vec![]; - while let Some((tok, n)) = next_token(s)? { - v.push(tok); - s = &s[n..]; - } - Ok(v) -} - -struct Parser> { - it: Peekable, -} - -impl> Parser { - fn new>(v: T) -> Self { - Self { - it: v.into_iter().peekable(), - } - } - - fn next(&mut self) -> Result { - match self.it.next() { - Some(tok) => Ok(tok), - None => bail!("out of tokens, this should not happen"), - } - } - - fn peek(&mut self) -> Option<&Token> { - self.it.peek() - } - - fn consume(&mut self, tok: Token) -> Result<()> { - let t = self.next()?; - if t != tok { - bail!("expected token {:?}, got {:?}", tok, t) - } - Ok(()) - } - - fn parse_comma_list( - &mut self, - parse_list_item: F, - end_token: Token, - allow_trailing_comma: bool, - ) -> Result> - where - F: Fn(&mut Self) -> Result, - R: std::fmt::Debug, - { - let mut v = vec![]; - if !(self.peek() == Some(&end_token)) { - loop { - v.push(parse_list_item(self)?); - if self.peek() == Some(&end_token) { - break; - } - self.consume(Token::Comma)?; - if self.peek() == Some(&end_token) && allow_trailing_comma { - break; - } - } - } - Ok(v) - } - - fn parse_type_tag(&mut self) -> Result { - Ok(match self.next()? { - Token::U8Type => TypeTag::U8, - Token::U16Type => TypeTag::U16, - Token::U32Type => TypeTag::U32, - Token::U64Type => TypeTag::U64, - Token::U128Type => TypeTag::U128, - Token::U256Type => TypeTag::U256, - Token::BoolType => TypeTag::Bool, - Token::AddressType => TypeTag::Address, - Token::SignerType => TypeTag::Signer, - Token::VectorType => { - self.consume(Token::Lt)?; - let ty = self.parse_type_tag()?; - self.consume(Token::Gt)?; - TypeTag::Vector(Box::new(ty)) - } - Token::Address(addr) => { - self.consume(Token::ColonColon)?; - let module = self.next().and_then(token_as_name)?; - self.consume(Token::ColonColon)?; - let name = self.next().and_then(token_as_name)?; - let ty_args = if self.peek() == Some(&Token::Lt) { - self.next()?; - let ty_args = - self.parse_comma_list(|parser| parser.parse_type_tag(), Token::Gt, true)?; - self.consume(Token::Gt)?; - ty_args - } else { - vec![] - }; - TypeTag::Struct(Box::new(StructTag { - address: AccountAddress::from_hex_literal(&addr)?, - module: Identifier::new(module)?, - name: Identifier::new(name)?, - type_params: ty_args, - })) - } - tok => bail!("unexpected token {:?}, expected type tag", tok), - }) - } - - fn parse_transaction_argument(&mut self) -> Result { - Ok(match self.next()? { - Token::U8(s) => TransactionArgument::U8(s.replace('_', "").parse()?), - Token::U16(s) => TransactionArgument::U16(s.replace('_', "").parse()?), - Token::U32(s) => TransactionArgument::U32(s.replace('_', "").parse()?), - Token::U64(s) => TransactionArgument::U64(s.replace('_', "").parse()?), - Token::U128(s) => TransactionArgument::U128(s.replace('_', "").parse()?), - Token::U256(s) => TransactionArgument::U256(s.replace('_', "").parse()?), - Token::True => TransactionArgument::Bool(true), - Token::False => TransactionArgument::Bool(false), - Token::Address(addr) => { - TransactionArgument::Address(AccountAddress::from_hex_literal(&addr)?) - } - Token::Bytes(s) => TransactionArgument::U8Vector(hex::decode(s)?), - tok => bail!("unexpected token {:?}, expected transaction argument", tok), - }) - } -} - -fn parse(s: &str, f: F) -> Result -where - F: Fn(&mut Parser>) -> Result, -{ - let mut tokens: Vec<_> = tokenize(s)? - .into_iter() - .filter(|tok| !tok.is_whitespace()) - .collect(); - tokens.push(Token::EOF); - let mut parser = Parser::new(tokens); - let res = f(&mut parser)?; - parser.consume(Token::EOF)?; - Ok(res) -} - -pub fn parse_type_tag(s: &str) -> Result { - parse(s, |parser| parser.parse_type_tag()) -} - -pub fn parse_transaction_argument(s: &str) -> Result { - parse(s, |parser| parser.parse_transaction_argument()) -} - -pub fn parse_struct_tag(s: &str) -> Result { - let type_tag = parse(s, |parser| parser.parse_type_tag()) - .map_err(|e| format_err!("invalid struct tag: {}, {}", s, e))?; - if let TypeTag::Struct(struct_tag) = type_tag { - Ok(*struct_tag) - } else { - bail!("invalid struct tag: {}", s) - } -} - -#[cfg(test)] -mod tests { - use std::str::FromStr; - - use crate::{ - account_address::AccountAddress, - parser::{parse_struct_tag, parse_transaction_argument, parse_type_tag}, - transaction_argument::TransactionArgument, - u256, - }; - - #[allow(clippy::unreadable_literal)] - #[test] - fn tests_parse_transaction_argument_positive() { - use TransactionArgument as T; - - for (s, expected) in &[ - (" 0u8", T::U8(0)), - ("0u8", T::U8(0)), - ("255u8", T::U8(255)), - ("0", T::U64(0)), - ("0123", T::U64(123)), - ("0u64", T::U64(0)), - ("18446744073709551615", T::U64(18446744073709551615)), - ("18446744073709551615u64", T::U64(18446744073709551615)), - ("0u128", T::U128(0)), - ("1_0u8", T::U8(1_0)), - ("10_u8", T::U8(10)), - ("10___u8", T::U8(10)), - ("1_000u64", T::U64(1_000)), - ("1_000", T::U64(1_000)), - ("1_0_0_0u64", T::U64(1_000)), - ("1_000_000u128", T::U128(1_000_000)), - ( - "340282366920938463463374607431768211455u128", - T::U128(340282366920938463463374607431768211455), - ), - (" 0u16", T::U16(0)), - ("0u16", T::U16(0)), - ("532u16", T::U16(532)), - ("65535u16", T::U16(65535)), - ("0u32", T::U32(0)), - ("01239498u32", T::U32(1239498)), - ("35366u32", T::U32(35366)), - ("4294967295u32", T::U32(4294967295)), - ("0u256", T::U256(u256::U256::from(0u8))), - ("1_0u16", T::U16(1_0)), - ("10_u16", T::U16(10)), - ("10___u16", T::U16(10)), - ("1_000u32", T::U32(1_000)), - ("1_0_00u32", T::U32(1_000)), - ("1_0_0_0u32", T::U32(1_000)), - ("1_000_000u256", T::U256(u256::U256::from(1_000_000u64))), - ( - "1_000_000_000u256", - T::U256(u256::U256::from(1_000_000_000u128)), - ), - ( - "3402823669209384634633746074317682114551234u256", - T::U256( - u256::U256::from_str("3402823669209384634633746074317682114551234").unwrap(), - ), - ), - ("true", T::Bool(true)), - ("false", T::Bool(false)), - ( - "0x0", - T::Address(AccountAddress::from_hex_literal("0x0").unwrap()), - ), - ( - "0x54afa3526", - T::Address(AccountAddress::from_hex_literal("0x54afa3526").unwrap()), - ), - ( - "0X54afa3526", - T::Address(AccountAddress::from_hex_literal("0x54afa3526").unwrap()), - ), - ("x\"7fff\"", T::U8Vector(vec![0x7f, 0xff])), - ("x\"\"", T::U8Vector(vec![])), - ("x\"00\"", T::U8Vector(vec![0x00])), - ("x\"deadbeef\"", T::U8Vector(vec![0xde, 0xad, 0xbe, 0xef])), - ] { - assert_eq!(&parse_transaction_argument(s).unwrap(), expected) - } - } - - #[test] - fn tests_parse_transaction_argument_negative() { - /// Test cases for the parser that should always fail. - const PARSE_VALUE_NEGATIVE_TEST_CASES: &[&str] = &[ - "-3", - "0u42", - "0u645", - "0u64x", - "0u6 4", - "0u", - "_10", - "_10_u8", - "_10__u8", - "_1014__u32", - "10_u8__", - "_", - "__", - "__4", - "_u8", - "5_bool", - "256u8", - "18446744073709551616u64", - "340282366920938463463374607431768211456u128", - "340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456u256", - "0xg", - "0x00g0", - "0x", - "0x_", - "", - "@@", - "()", - "x\"ffff", - "x\"a \"", - "x\" \"", - "x\"0g\"", - "x\"0\"", - "garbage", - "true3", - "3false", - "3 false", - "", - ]; - - for s in PARSE_VALUE_NEGATIVE_TEST_CASES { - assert!( - parse_transaction_argument(s).is_err(), - "test case unexpectedly succeeded: {}", - s - ) - } - } - - #[test] - fn test_type_tag() { - for s in &[ - "u64", - "bool", - "vector", - "vector>", - "vector", - "vector>", - "vector", - "vector>", - "vector", - "vector>", - "vector", - "vector>", - "signer", - "0x1::M::S", - "0x2::M::S_", - "0x3::M_::S", - "0x4::M_::S_", - "0x00000000004::M::S", - "0x1::M::S", - "0x1::M::S", - "0x1::M::S", - "0x1::M::S", - "0x1::M::S<0x2::P::Q>", - "vector<0x1::M::S>", - "vector<0x1::M_::S_>", - "vector>", - "0x1::M::S>", - "0x1::M::S>", - "0x1::M::S>", - "0x1::M::S>", - "0x1::M::S>", - "0x1::M::S>", - ] { - assert!(parse_type_tag(s).is_ok(), "Failed to parse tag {}", s); - } - } - - #[test] - fn test_parse_valid_struct_tag() { - let valid = vec![ - "0x1::Diem::Diem", - "0x1::Diem_Type::Diem", - "0x1::Diem_::Diem", - "0x1::X_123::X32_", - "0x1::Diem::Diem_Type", - "0x1::Diem::Diem<0x1::XDX::XDX>", - "0x1::Diem::Diem<0x1::XDX::XDX_Type>", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem
", - "0x1::Diem::Diem", - "0x1::Diem::Diem>", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem", - "0x1::Diem::Diem,address,signer>", - "0x1::Diem::Diem>>", - "0x1::Diem::Diem<0x1::Diem::Struct, 0x1::Diem::Diem>>>>", - ]; - for text in valid { - let st = parse_struct_tag(text).expect("valid StructTag"); - assert_eq!( - st.to_string().replace(' ', ""), - text.replace(' ', ""), - "text: {:?}, StructTag: {:?}", - text, - st - ); - } - } - - #[test] - fn test_parse_struct_tag_with_type_names() { - let names = vec![ - "address", "vector", "u128", "u256", "u64", "u32", "u16", "u8", "bool", "signer", - ]; - - let mut tests = vec![]; - for name in &names { - for name_type in &names { - tests.push(format!("0x1::{name}::{name_type}")) - } - } - - let mut instantiations = vec![]; - for ty in &tests { - for other_ty in &tests { - instantiations.push(format!("{ty}<{other_ty}>")) - } - } - - for text in tests.iter().chain(instantiations.iter()) { - let st = parse_struct_tag(text).expect("valid StructTag"); - assert_eq!( - st.to_string().replace(' ', ""), - text.replace(' ', ""), - "text: {:?}, StructTag: {:?}", - text, - st - ); - } - } -} diff --git a/external-crates/move/crates/move-command-line-common/src/address.rs b/external-crates/move/crates/move-core-types/src/parsing/address.rs similarity index 91% rename from external-crates/move/crates/move-command-line-common/src/address.rs rename to external-crates/move/crates/move-core-types/src/parsing/address.rs index 037f401e096..d48ac874239 100644 --- a/external-crates/move/crates/move-command-line-common/src/address.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/address.rs @@ -5,10 +5,12 @@ use std::{fmt, hash::Hash}; use anyhow::anyhow; -use move_core_types::account_address::AccountAddress; -use num_bigint::BigUint; -use crate::parser::{parse_address_number, NumberFormat}; +use crate::{ + account_address::AccountAddress, + parsing::parser::{NumberFormat, parse_address_number}, + u256::U256, +}; // Parsed Address, either a name or a numerical address #[derive(Eq, PartialEq, Debug, Clone)] @@ -65,10 +67,7 @@ impl NumericalAddress { pub fn parse_str(s: &str) -> Result { match parse_address_number(s) { - Some((n, format)) => Ok(NumericalAddress { - bytes: AccountAddress::new(n), - format, - }), + Some((n, format)) => Ok(NumericalAddress { bytes: n, format }), None => // TODO the kind of error is in an unstable nightly API // But currently the only way this should fail is if the number is too long @@ -93,7 +92,7 @@ impl fmt::Display for NumericalAddress { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.format { NumberFormat::Decimal => { - let n = BigUint::from_bytes_be(self.bytes.as_ref()); + let n = U256::from_be_bytes(&self.bytes); write!(f, "{}", n) } NumberFormat::Hex => write!(f, "{:#X}", self), @@ -182,6 +181,16 @@ impl PartialEq for NumericalAddress { } impl Eq for NumericalAddress {} +impl PartialEq for NumericalAddress { + fn eq(&self, other: &AccountAddress) -> bool { + let Self { + bytes: self_bytes, + format: _, + } = self; + self_bytes == other + } +} + impl Hash for NumericalAddress { fn hash(&self, state: &mut H) { let Self { diff --git a/external-crates/move/crates/move-core-types/src/parsing/mod.rs b/external-crates/move/crates/move-core-types/src/parsing/mod.rs new file mode 100644 index 00000000000..bdb2683bcda --- /dev/null +++ b/external-crates/move/crates/move-core-types/src/parsing/mod.rs @@ -0,0 +1,11 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +pub mod address; +pub mod parser; +pub mod types; +pub mod values; diff --git a/external-crates/move/crates/move-command-line-common/src/parser.rs b/external-crates/move/crates/move-core-types/src/parsing/parser.rs similarity index 59% rename from external-crates/move/crates/move-command-line-common/src/parser.rs rename to external-crates/move/crates/move-core-types/src/parsing/parser.rs index f71b89e174c..6197de7f3fc 100644 --- a/external-crates/move/crates/move-command-line-common/src/parser.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/parser.rs @@ -4,21 +4,22 @@ use std::{fmt::Display, iter::Peekable, num::ParseIntError}; -use anyhow::{anyhow, bail, Result}; -use move_core_types::{ - account_address::AccountAddress, - u256::{U256FromStrError, U256}, -}; -use num_bigint::BigUint; +use anyhow::{Result, anyhow, bail}; use crate::{ - address::{NumericalAddress, ParsedAddress}, - types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType, TypeToken}, - values::{ParsableValue, ParsedValue, ValueToken}, + account_address::AccountAddress, + parsing::{ + address::{NumericalAddress, ParsedAddress}, + types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType, TypeToken}, + values::{ParsableValue, ParsedValue, ValueToken}, + }, + u256::{U256, U256FromStrError}, }; const MAX_TYPE_DEPTH: u64 = 128; const MAX_TYPE_NODE_COUNT: u64 = 256; +// See: https://stackoverflow.com/questions/43787672/the-max-number-of-digits-in-an-int-based-on-number-of-bits +const U256_MAX_DECIMAL_DIGITS: usize = 241 * AccountAddress::LENGTH / 100 + 1; pub trait Token: Display + Copy + Eq { fn is_whitespace(&self) -> bool; @@ -79,7 +80,7 @@ impl ParsedValue { } } -fn parse<'a, Tok: Token, R>( +pub(crate) fn parse<'a, Tok: Token, R>( s: &'a str, f: impl FnOnce(&mut Parser<'a, Tok, std::vec::IntoIter<(Tok, &'a str)>>) -> Result, ) -> Result { @@ -142,8 +143,12 @@ impl<'a, Tok: Token, I: Iterator> Parser<'a, Tok, I> { break; } self.advance(delim)?; - if is_end(self.peek_tok()) && allow_trailing_delim { - break; + if is_end(self.peek_tok()) { + if allow_trailing_delim { + break; + } else { + bail!("Invalid type list: trailing delimiter '{}'", delim) + } } } Ok(v) @@ -228,6 +233,9 @@ impl<'a, I: Iterator> Parser<'a, TypeToken, I> { true, )?; self.advance(TypeToken::Gt)?; + if type_args.is_empty() { + bail!("expected at least one type argument") + } type_args } _ => vec![], @@ -443,306 +451,20 @@ pub fn parse_u256(s: &str) -> Result<(U256, NumberFormat), U256FromStrError> { } // Parse an address from a decimal or hex encoding -pub fn parse_address_number(s: &str) -> Option<([u8; AccountAddress::LENGTH], NumberFormat)> { +pub fn parse_address_number(s: &str) -> Option<(AccountAddress, NumberFormat)> { let (txt, base) = determine_num_text_and_base(s); - let parsed = BigUint::parse_bytes( - txt.as_bytes(), - match base { - NumberFormat::Hex => 16, - NumberFormat::Decimal => 10, - }, - )?; - let bytes = parsed.to_bytes_be(); - if bytes.len() > AccountAddress::LENGTH { - return None; - } - let mut result = [0u8; AccountAddress::LENGTH]; - result[(AccountAddress::LENGTH - bytes.len())..].clone_from_slice(&bytes); - Some((result, base)) -} - -#[cfg(test)] -mod tests { - use move_core_types::{account_address::AccountAddress, identifier::Identifier, u256::U256}; - use proptest::{prelude::*, proptest}; - - use crate::{ - address::{NumericalAddress, ParsedAddress}, - types::{ParsedStructType, ParsedType}, - values::ParsedValue, + let txt = txt.replace('_', ""); + let max_len = match base { + NumberFormat::Hex => AccountAddress::LENGTH * 2, + NumberFormat::Decimal => U256_MAX_DECIMAL_DIGITS, }; - - #[allow(clippy::unreadable_literal)] - #[test] - fn tests_parse_value_positive() { - use ParsedValue as V; - let cases: &[(&str, V)] = &[ - (" 0u8", V::U8(0)), - ("0u8", V::U8(0)), - ("0xF_Fu8", V::U8(255)), - ("0xF__FF__Eu16", V::U16(u16::MAX - 1)), - ("0xFFF_FF__FF_Cu32", V::U32(u32::MAX - 3)), - ("255u8", V::U8(255)), - ("255u256", V::U256(U256::from(255u64))), - ("0", V::InferredNum(U256::from(0u64))), - ("0123", V::InferredNum(U256::from(123u64))), - ("0xFF", V::InferredNum(U256::from(0xFFu64))), - ("0xF_F", V::InferredNum(U256::from(0xFFu64))), - ("0xFF__", V::InferredNum(U256::from(0xFFu64))), - ( - "0x12_34__ABCD_FF", - V::InferredNum(U256::from(0x1234ABCDFFu64)), - ), - ("0u64", V::U64(0)), - ("0x0u64", V::U64(0)), - ( - "18446744073709551615", - V::InferredNum(U256::from(18446744073709551615u128)), - ), - ("18446744073709551615u64", V::U64(18446744073709551615)), - ("0u128", V::U128(0)), - ("1_0u8", V::U8(1_0)), - ("10_u8", V::U8(10)), - ("1_000u64", V::U64(1_000)), - ("1_000", V::InferredNum(U256::from(1_000u32))), - ("1_0_0_0u64", V::U64(1_000)), - ("1_000_000u128", V::U128(1_000_000)), - ( - "340282366920938463463374607431768211455u128", - V::U128(340282366920938463463374607431768211455), - ), - ("true", V::Bool(true)), - ("false", V::Bool(false)), - ( - "@0x0", - V::Address(ParsedAddress::Numerical(NumericalAddress::new( - AccountAddress::from_hex_literal("0x0") - .unwrap() - .into_bytes(), - crate::parser::NumberFormat::Hex, - ))), - ), - ( - "@0", - V::Address(ParsedAddress::Numerical(NumericalAddress::new( - AccountAddress::from_hex_literal("0x0") - .unwrap() - .into_bytes(), - crate::parser::NumberFormat::Hex, - ))), - ), - ( - "@0x54afa3526", - V::Address(ParsedAddress::Numerical(NumericalAddress::new( - AccountAddress::from_hex_literal("0x54afa3526") - .unwrap() - .into_bytes(), - crate::parser::NumberFormat::Hex, - ))), - ), - ( - "b\"hello\"", - V::Vector("hello".as_bytes().iter().copied().map(V::U8).collect()), - ), - ("x\"7fff\"", V::Vector(vec![V::U8(0x7f), V::U8(0xff)])), - ("x\"\"", V::Vector(vec![])), - ("x\"00\"", V::Vector(vec![V::U8(0x00)])), - ( - "x\"deadbeef\"", - V::Vector(vec![V::U8(0xde), V::U8(0xad), V::U8(0xbe), V::U8(0xef)]), - ), - ]; - - for (s, expected) in cases { - assert_eq!(&ParsedValue::parse(s).unwrap(), expected) - } - } - - #[test] - fn tests_parse_value_negative() { - /// Test cases for the parser that should always fail. - const PARSE_VALUE_NEGATIVE_TEST_CASES: &[&str] = &[ - "-3", - "0u42", - "0u645", - "0u64x", - "0u6 4", - "0u", - "_10", - "_10_u8", - "_10__u8", - "10_u8__", - "0xFF_u8_", - "0xF_u8__", - "0x_F_u8__", - "_", - "__", - "__4", - "_u8", - "5_bool", - "256u8", - "4294967296u32", - "65536u16", - "18446744073709551616u64", - "340282366920938463463374607431768211456u128", - "340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456u256", - "0xg", - "0x00g0", - "0x", - "0x_", - "", - "@@", - "()", - "x\"ffff", - "x\"a \"", - "x\" \"", - "x\"0g\"", - "x\"0\"", - "garbage", - "true3", - "3false", - "3 false", - "", - "0XFF", - "0X0", - ]; - - for s in PARSE_VALUE_NEGATIVE_TEST_CASES { - assert!( - ParsedValue::<()>::parse(s).is_err(), - "Unexpectedly succeeded in parsing: {}", - s - ) - } - } - - #[test] - fn test_parse_type_negative() { - for s in &[ - "_", - "_::_::_", - "0x1::_", - "0x1::__::_", - "0x1::_::__", - "0x1::_::foo", - "0x1::foo::_", - "0x1::_::_", - "0x1::bar::foo<0x1::_::foo>", - ] { - assert!( - ParsedType::parse(s).is_err(), - "Parsed type {s} but should have failed" - ); - } - } - - #[test] - fn test_parse_struct_negative() { - for s in &[ - "_", - "_::_::_", - "0x1::_", - "0x1::__::_", - "0x1::_::__", - "0x1::_::foo", - "0x1::foo::_", - "0x1::_::_", - "0x1::bar::foo<0x1::_::foo>", - ] { - assert!( - ParsedStructType::parse(s).is_err(), - "Parsed type {s} but should have failed" - ); - } - } - - #[test] - fn test_type_type() { - for s in &[ - "u64", - "bool", - "vector", - "vector>", - "address", - "signer", - "0x1::M::S", - "0x2::M::S_", - "0x3::M_::S", - "0x4::M_::S_", - "0x00000000004::M::S", - "0x1::M::S", - "0x1::M::S<0x2::P::Q>", - "vector<0x1::M::S>", - "vector<0x1::M_::S_>", - "vector>", - "0x1::M::S>", - "0x1::_bar::_BAR", - "0x1::__::__", - "0x1::_bar::_BAR<0x2::_____::______fooo______>", - "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", - ] { - assert!(ParsedType::parse(s).is_ok(), "Failed to parse type {}", s); - } - } - - #[test] - fn test_parse_valid_struct_type() { - let valid = vec![ - "0x1::Foo::Foo", - "0x1::Foo_Type::Foo", - "0x1::Foo_::Foo", - "0x1::X_123::X32_", - "0x1::Foo::Foo_Type", - "0x1::Foo::Foo<0x1::ABC::ABC>", - "0x1::Foo::Foo<0x1::ABC::ABC_Type>", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo
", - "0x1::Foo::Foo", - "0x1::Foo::Foo>", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo,address,signer>", - "0x1::Foo::Foo>>", - "0x1::Foo::Foo<0x1::Foo::Struct, 0x1::Foo::Foo>>>>", - "0x1::_bar::_BAR", - "0x1::__::__", - "0x1::_bar::_BAR<0x2::_____::______fooo______>", - "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", - ]; - for s in valid { - assert!( - ParsedStructType::parse(s).is_ok(), - "Failed to parse struct {}", - s - ); - } - } - - fn struct_type_gen() -> impl Strategy { - ( - any::(), - any::(), - any::(), - ) - .prop_map(|(address, module, name)| format!("0x{}::{}::{}", address, module, name)) - } - - proptest! { - #[test] - fn test_parse_valid_struct_type_proptest(s in struct_type_gen()) { - prop_assert!(ParsedStructType::parse(&s).is_ok()); - } - - #[test] - fn test_parse_valid_type_struct_only_proptest(s in struct_type_gen()) { - prop_assert!(ParsedStructType::parse(&s).is_ok()); - } + if txt.len() > max_len { + return None; } + let parsed = U256::from_str_radix(&txt, match base { + NumberFormat::Hex => 16, + NumberFormat::Decimal => 10, + }) + .ok()?; + Some((AccountAddress::new(parsed.to_be_bytes()), base)) } diff --git a/external-crates/move/crates/move-command-line-common/src/types.rs b/external-crates/move/crates/move-core-types/src/parsing/types.rs similarity index 94% rename from external-crates/move/crates/move-command-line-common/src/types.rs rename to external-crates/move/crates/move-core-types/src/parsing/types.rs index b2cccabd5c3..af8cc701289 100644 --- a/external-crates/move/crates/move-command-line-common/src/types.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/types.rs @@ -4,14 +4,14 @@ use std::fmt::{self, Display}; -use anyhow::bail; -use move_core_types::{ +use crate::{ account_address::AccountAddress, identifier::{self, Identifier}, language_storage::{ModuleId, StructTag, TypeTag}, }; +use anyhow::bail; -use crate::{address::ParsedAddress, parser::Token}; +use crate::parsing::{address::ParsedAddress, parser::Token}; #[derive(Eq, PartialEq, Debug, Clone, Copy)] pub enum TypeToken { @@ -92,10 +92,10 @@ impl Token for TypeToken { Some(':') => (Self::ColonColon, 2), _ => bail!("unrecognized token: {}", s), }, - '0' if matches!(chars.peek(), Some('x') | Some('X')) => { + '0' if matches!(chars.peek(), Some('x')) => { chars.next().unwrap(); match chars.next() { - Some(c) if c.is_ascii_hexdigit() || c == '_' => { + Some(c) if c.is_ascii_hexdigit() => { // 0x + c + remaining let len = 3 + chars .take_while(|q| char::is_ascii_hexdigit(q) || *q == '_') @@ -107,7 +107,9 @@ impl Token for TypeToken { } c if c.is_ascii_digit() => { // c + remaining - let len = 1 + chars.take_while(char::is_ascii_digit).count(); + let len = 1 + chars + .take_while(|c| c.is_ascii_digit() || *c == '_') + .count(); (Self::AddressIdent, len) } c if c.is_ascii_whitespace() => { diff --git a/external-crates/move/crates/move-command-line-common/src/values.rs b/external-crates/move/crates/move-core-types/src/parsing/values.rs similarity index 98% rename from external-crates/move/crates/move-command-line-common/src/values.rs rename to external-crates/move/crates/move-core-types/src/parsing/values.rs index f2f923c2538..0e478c38ad9 100644 --- a/external-crates/move/crates/move-command-line-common/src/values.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/values.rs @@ -5,17 +5,17 @@ use std::fmt::{self, Display}; use anyhow::bail; -use move_core_types::{ + +use crate::{ account_address::AccountAddress, identifier, + parsing::{ + address::ParsedAddress, + parser::{Parser, Token}, + }, runtime_value::{MoveStruct, MoveValue}, }; -use crate::{ - address::ParsedAddress, - parser::{Parser, Token}, -}; - #[derive(Eq, PartialEq, Debug, Clone, Copy)] pub enum ValueToken { Number, @@ -42,13 +42,13 @@ pub enum ValueToken { #[derive(Eq, PartialEq, Debug, Clone)] pub enum ParsedValue { Address(ParsedAddress), - InferredNum(move_core_types::u256::U256), + InferredNum(crate::u256::U256), U8(u8), U16(u16), U32(u32), U64(u64), U128(u128), - U256(move_core_types::u256::U256), + U256(crate::u256::U256), Bool(bool), Vector(Vec>), Struct(Vec>), diff --git a/external-crates/move/crates/move-core-types/src/runtime_value.rs b/external-crates/move/crates/move-core-types/src/runtime_value.rs index e91b7daa2da..71718954c12 100644 --- a/external-crates/move/crates/move-core-types/src/runtime_value.rs +++ b/external-crates/move/crates/move-core-types/src/runtime_value.rs @@ -54,15 +54,15 @@ pub enum MoveValue { } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MoveStructLayout(pub Vec); +pub struct MoveStructLayout(pub Box>); #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MoveEnumLayout(pub Vec>); +pub struct MoveEnumLayout(pub Box>>); #[derive(Debug, Clone, Serialize, Deserialize)] pub enum MoveDatatypeLayout { - Struct(MoveStructLayout), - Enum(MoveEnumLayout), + Struct(Box), + Enum(Box), } impl MoveDatatypeLayout { @@ -90,7 +90,7 @@ pub enum MoveTypeLayout { #[serde(rename(serialize = "vector", deserialize = "vector"))] Vector(Box), #[serde(rename(serialize = "struct", deserialize = "struct"))] - Struct(MoveStructLayout), + Struct(Box), #[serde(rename(serialize = "signer", deserialize = "signer"))] Signer, @@ -102,7 +102,7 @@ pub enum MoveTypeLayout { #[serde(rename(serialize = "u256", deserialize = "u256"))] U256, #[serde(rename(serialize = "enum", deserialize = "enum"))] - Enum(MoveEnumLayout), + Enum(Box), } impl MoveValue { @@ -196,7 +196,7 @@ impl MoveStruct { type_: type_.clone(), fields: vals .into_iter() - .zip(fields) + .zip(fields.iter()) .map(|(v, l)| (l.name.clone(), v.decorate(&l.layout))) .collect(), } @@ -232,7 +232,7 @@ impl MoveVariant { tag, fields: fields .into_iter() - .zip(v_layout) + .zip(v_layout.iter()) .map(|(v, l)| (l.name.clone(), v.decorate(&l.layout))) .collect(), variant_name: v_name.clone(), @@ -250,7 +250,7 @@ impl MoveVariant { impl MoveStructLayout { pub fn new(types: Vec) -> Self { - Self(types) + Self(Box::new(types)) } pub fn fields(&self) -> &[MoveTypeLayout] { @@ -258,7 +258,7 @@ impl MoveStructLayout { } pub fn into_fields(self) -> Vec { - self.0 + *self.0 } } diff --git a/external-crates/move/crates/move-core-types/src/u256.rs b/external-crates/move/crates/move-core-types/src/u256.rs index 15b8557474b..2cf519c3923 100644 --- a/external-crates/move/crates/move-core-types/src/u256.rs +++ b/external-crates/move/crates/move-core-types/src/u256.rs @@ -310,6 +310,11 @@ impl U256 { Self(PrimitiveU256::from_little_endian(slice)) } + /// U256 from 32 big endian bytes + pub fn from_be_bytes(slice: &[u8; U256_NUM_BYTES]) -> Self { + Self(PrimitiveU256::from_big_endian(slice)) + } + /// U256 to 32 little endian bytes pub fn to_le_bytes(self) -> [u8; U256_NUM_BYTES] { let mut bytes = [0u8; U256_NUM_BYTES]; @@ -317,6 +322,13 @@ impl U256 { bytes } + /// U256 to 32 big endian bytes + pub fn to_be_bytes(self) -> [u8; U256_NUM_BYTES] { + let mut bytes = [0u8; U256_NUM_BYTES]; + self.0.to_big_endian(&mut bytes); + bytes + } + /// Leading zeros of the number pub fn leading_zeros(&self) -> u32 { self.0.leading_zeros() diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/extractor_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/extractor_test.rs new file mode 100644 index 00000000000..d45ebb17958 --- /dev/null +++ b/external-crates/move/crates/move-core-types/src/unit_tests/extractor_test.rs @@ -0,0 +1,853 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use std::str::FromStr; + +use crate::{ + account_address::AccountAddress, + annotated_extractor::{Element as E, Extractor}, + annotated_value::{MoveTypeLayout, MoveValue}, + language_storage::TypeTag, + unit_tests::visitor_test::{ + enum_layout_, serialize, struct_layout_, struct_value_, variant_value_, PrintVisitor, + }, +}; + +#[test] +fn struct_() { + let expect = r#" +[0] struct 0x0::foo::Bar { + a: u8, + b: u16, + c: u32, + d: u64, + e: u128, + f: u256, + g: bool, + h: address, + i: signer, + j: vector, + k: struct 0x0::foo::Baz { + l: u8, + }, + m: enum 0x0::foo::Qux { + n { + o: u8, + }, + }, + p: vector, +} +[1] 1: u8 +[1] 2: u16 +[1] 3: u32 +[1] 4: u64 +[1] 5: u128 +[1] 6: u256 +[1] true: bool +[1] 0000000000000000000000000000000000000000000000000000000000000000: address +[1] 0000000000000000000000000000000000000000000000000000000000000000: signer +[1] vector +[2] 7: u8 +[2] 8: u8 +[2] 9: u8 +[1] struct 0x0::foo::Baz { + l: u8, +} +[2] 10: u8 +[1] enum 0x0::foo::Qux { + n { + o: u8, + }, +} +[2] 11: u8 +[1] vector +[2] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[3] 12: u8 +[3] true: bool +[2] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[3] 13: u8 +[3] false: bool + "#; + + for path in enumerate_paths(vec![C::Opt(E::Type(&type_("0x0::foo::Bar")))]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_a() { + let expect = r#" +[0] 1: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("a"), E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_b() { + let expect = r#" +[0] 2: u16 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("b"), E::Index(1)]), + C::Opt(E::Type(&type_("u16"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_c() { + let expect = r#" +[0] 3: u32 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("c"), E::Index(2)]), + C::Opt(E::Type(&type_("u32"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_d() { + let expect = r#" +[0] 4: u64 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("d"), E::Index(3)]), + C::Opt(E::Type(&type_("u64"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_e() { + let expect = r#" +[0] 5: u128 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("e"), E::Index(4)]), + C::Opt(E::Type(&type_("u128"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_f() { + let expect = r#" +[0] 6: u256 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("f"), E::Index(5)]), + C::Opt(E::Type(&type_("u256"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_g() { + let expect = r#" +[0] true: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("g"), E::Index(6)]), + C::Opt(E::Type(&type_("bool"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_h() { + let expect = r#" +[0] 0000000000000000000000000000000000000000000000000000000000000000: address + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("h"), E::Index(7)]), + C::Opt(E::Type(&type_("address"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_i() { + let expect = r#" +[0] 0000000000000000000000000000000000000000000000000000000000000000: signer + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("i"), E::Index(8)]), + C::Opt(E::Type(&type_("signer"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_j() { + let expect = r#" +[0] vector +[1] 7: u8 +[1] 8: u8 +[1] 9: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("j"), E::Index(9)]), + C::Opt(E::Type(&type_("vector"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_j_0() { + let expect = r#" +[0] 7: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("j"), E::Index(9)]), + C::Opt(E::Type(&type_("vector"))), + C::Req(vec![E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_j_1() { + let expect = r#" +[0] 8: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("j"), E::Index(9)]), + C::Opt(E::Type(&type_("vector"))), + C::Req(vec![E::Index(1)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_j_2() { + let expect = r#" +[0] 9: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("j"), E::Index(9)]), + C::Opt(E::Type(&type_("vector"))), + C::Req(vec![E::Index(2)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_k() { + let expect = r#" +[0] struct 0x0::foo::Baz { + l: u8, +} +[1] 10: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("k"), E::Index(10)]), + C::Opt(E::Type(&type_("0x0::foo::Baz"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_k_l() { + let expect = r#" +[0] 10: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("k"), E::Index(10)]), + C::Opt(E::Type(&type_("0x0::foo::Baz"))), + C::Req(vec![E::Field("l"), E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_m() { + let expect = r#" +[0] enum 0x0::foo::Qux { + n { + o: u8, + }, +} +[1] 11: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("m"), E::Index(11)]), + C::Opt(E::Type(&type_("0x0::foo::Qux"))), + C::Opt(E::Variant("n")), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_m_o() { + let expect = r#" +[0] 11: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("m"), E::Index(11)]), + C::Opt(E::Type(&type_("0x0::foo::Qux"))), + C::Opt(E::Variant("n")), + C::Req(vec![E::Field("o"), E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p() { + let expect = r#" +[0] vector +[1] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[2] 12: u8 +[2] true: bool +[1] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[2] 13: u8 +[2] false: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p_0() { + let expect = r#" +[0] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[1] 12: u8 +[1] true: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(0)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p_0_q() { + let expect = r#" +[0] 12: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(0)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + C::Req(vec![E::Field("q"), E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p_0_r() { + let expect = r#" +[0] true: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(0)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + C::Req(vec![E::Field("r"), E::Index(1)]), + C::Opt(E::Type(&type_("bool"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p_1() { + let expect = r#" +[0] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[1] 13: u8 +[1] false: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(1)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p_1_q() { + let expect = r#" +[0] 13: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(1)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + C::Req(vec![E::Field("q"), E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn struct_p_1_r() { + let expect = r#" +[0] false: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Bar"))), + C::Req(vec![E::Field("p"), E::Index(12)]), + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(1)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + C::Req(vec![E::Field("r"), E::Index(1)]), + C::Opt(E::Type(&type_("bool"))), + ]) { + assert_path(test_struct(), path, expect); + } +} + +#[test] +fn vector_() { + let expect = r#" +[0] vector +[1] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[2] 12: u8 +[2] true: bool +[1] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[2] 13: u8 +[2] false: bool + "#; + + for path in enumerate_paths(vec![C::Opt(E::Type(&type_("vector<0x0::foo::Quy>")))]) { + assert_path(test_vector(), path, expect); + } +} + +#[test] +fn vector_0() { + let expect = r#" +[0] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[1] 12: u8 +[1] true: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(0)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + ]) { + assert_path(test_vector(), path, expect); + } +} + +#[test] +fn vector_1() { + let expect = r#" +[0] struct 0x0::foo::Quy { + q: u8, + r: bool, +} +[1] 13: u8 +[1] false: bool + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("vector<0x0::foo::Quy>"))), + C::Req(vec![E::Index(1)]), + C::Opt(E::Type(&type_("0x0::foo::Quy"))), + ]) { + assert_path(test_vector(), path, expect); + } +} + +#[test] +fn enum_() { + let expect = r#" +[0] enum 0x0::foo::Qux { + n { + o: u8, + }, +} +[1] 11: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Qux"))), + C::Opt(E::Variant("n")), + ]) { + assert_path(test_enum(), path, expect); + } +} + +#[test] +fn enum_o() { + let expect = r#" +[0] 11: u8 + "#; + + for path in enumerate_paths(vec![ + C::Opt(E::Type(&type_("0x0::foo::Qux"))), + C::Opt(E::Variant("n")), + C::Req(vec![E::Field("o"), E::Index(0)]), + C::Opt(E::Type(&type_("u8"))), + ]) { + assert_path(test_enum(), path, expect); + } +} + +#[test] +fn field_not_found() { + for path in [ + vec![E::Field("z")], + // Trying to access a field on a primitive + vec![E::Field("a"), E::Field("z")], + // Nested field doesn't exist + vec![E::Field("k"), E::Field("z")], + // Nested field on an enum (that doesn't exist) + vec![E::Field("m"), E::Field("z")], + // Trying to access a field on a vector + vec![E::Field("p"), E::Field("z")], + // Nested field on a struct in a vector + vec![E::Field("p"), E::Index(0), E::Field("z")], + ] { + assert_no_path(test_struct(), path); + } +} + +#[test] +fn index_out_of_bounds() { + for path in [ + // Positional access of field, out of bounds + vec![E::Index(1000)], + // Trying to access index on a primitive + vec![E::Field("a"), E::Index(1000)], + // Out of bounds on primitive vector + vec![E::Field("j"), E::Index(1000)], + // Out of bounds field on nested struct + vec![E::Field("k"), E::Index(1000)], + // Out of bounds field on nested enum + vec![E::Field("m"), E::Index(1000)], + // Out of bounds field on struct vector + vec![E::Field("p"), E::Index(1000)], + // Out of bounds field on struct in vector + vec![E::Field("p"), E::Index(0), E::Index(1000)], + ] { + assert_no_path(test_struct(), path); + } +} + +#[test] +fn type_mismatch() { + for path in [ + // Wrong root type + vec![E::Type(&type_("0x0::foo::Baz"))], + // Wrong primitive type + vec![E::Field("a"), E::Type(&type_("u16"))], + // Wrong nested struct + vec![E::Field("k"), E::Type(&type_("0x0::foo::Bar"))], + // Wrong type with further nesting + vec![ + E::Field("k"), + E::Type(&type_("0x0::foo::Bar")), + E::Field("l"), + ], + // Wrong primitive vector + vec![E::Field("j"), E::Type(&type_("vector"))], + vec![E::Field("j"), E::Type(&type_("u8"))], + // Wrong enum type + vec![E::Field("m"), E::Type(&type_("0x0::foo::Bar"))], + // Wrong type nested inside enum + vec![E::Field("m"), E::Field("o"), E::Type(&type_("u16"))], + ] { + assert_no_path(test_struct(), path); + } +} + +#[test] +fn variant_not_found() { + assert_no_path(test_enum(), vec![E::Variant("z")]); + assert_no_path(test_struct(), vec![E::Field("m"), E::Variant("z")]); +} + +/// Components are used to generate paths. Each component offers a number of options for the +/// element that goes in the same position in the generated path. +enum C<'p> { + /// This element is optional -- paths are geneated with and without this element at the + /// component's position. + Opt(E<'p>), + + /// This element is required, and is picked from the provided list. + Req(Vec>), +} + +/// Generate a list of paths as a cartesian product of the provided components. +fn enumerate_paths(components: Vec>) -> Vec>> { + let mut paths = vec![vec![]]; + + for component in components { + let mut new_paths = vec![]; + + for path in paths { + match &component { + C::Opt(element) => { + new_paths.push(path.clone()); + let mut path = path.clone(); + path.push(element.clone()); + new_paths.push(path); + } + C::Req(elements) => { + new_paths.extend(elements.iter().map(|e| { + let mut path = path.clone(); + path.push(e.clone()); + path + })); + } + } + } + + paths = new_paths; + } + + paths +} + +fn assert_path((value, layout): (MoveValue, MoveTypeLayout), path: Vec>, expect: &str) { + let bytes = serialize(value); + let mut printer = PrintVisitor::default(); + + assert!( + Extractor::deserialize_value(&bytes, &layout, &mut printer, path.clone()) + .unwrap() + .is_some(), + "Failed to extract value {path:?}", + ); + + assert_eq!( + printer.output.trim(), + expect.trim(), + "Failed to match value at {path:?}" + ); +} + +fn assert_no_path((value, layout): (MoveValue, MoveTypeLayout), path: Vec>) { + let bytes = serialize(value); + let mut printer = PrintVisitor::default(); + + assert!( + Extractor::deserialize_value(&bytes, &layout, &mut printer, path.clone()) + .unwrap() + .is_none(), + "Expected not to find something at {path:?}", + ); + + assert!( + printer.output.is_empty(), + "Expected not to delegate to the inner visitor for {path:?}" + ); +} + +fn type_(t: &str) -> TypeTag { + TypeTag::from_str(t).unwrap() +} + +fn test_struct() -> (MoveValue, MoveTypeLayout) { + use MoveTypeLayout as T; + use MoveValue as V; + + let (vector, vector_layout) = test_vector(); + let (variant, enum_layout) = test_enum(); + + let value = struct_value_( + "0x0::foo::Bar", + vec![ + ("a", V::U8(1)), + ("b", V::U16(2)), + ("c", V::U32(3)), + ("d", V::U64(4)), + ("e", V::U128(5)), + ("f", V::U256(6u32.into())), + ("g", V::Bool(true)), + ("h", V::Address(AccountAddress::ZERO)), + ("i", V::Signer(AccountAddress::ZERO)), + ("j", V::Vector(vec![V::U8(7), V::U8(8), V::U8(9)])), + ("k", struct_value_("0x0::foo::Baz", vec![("l", V::U8(10))])), + ("m", variant), + ("p", vector), + ], + ); + + let layout = struct_layout_( + "0x0::foo::Bar", + vec![ + ("a", T::U8), + ("b", T::U16), + ("c", T::U32), + ("d", T::U64), + ("e", T::U128), + ("f", T::U256), + ("g", T::Bool), + ("h", T::Address), + ("i", T::Signer), + ("j", T::Vector(Box::new(T::U8))), + ("k", struct_layout_("0x0::foo::Baz", vec![("l", T::U8)])), + ("m", enum_layout), + ("p", vector_layout), + ], + ); + + (value, layout) +} + +fn test_enum() -> (MoveValue, MoveTypeLayout) { + use MoveTypeLayout as T; + use MoveValue as V; + + let value = variant_value_("0x0::foo::Qux", "n", 0, vec![("o", V::U8(11))]); + let layout = enum_layout_("0x0::foo::Qux", vec![("n", vec![("o", T::U8)])]); + + (value, layout) +} + +fn test_vector() -> (MoveValue, MoveTypeLayout) { + use MoveTypeLayout as T; + use MoveValue as V; + + let value = V::Vector(vec![ + struct_value_( + "0x0::foo::Quy", + vec![("q", V::U8(12)), ("r", V::Bool(true))], + ), + struct_value_( + "0x0::foo::Quy", + vec![("q", V::U8(13)), ("r", V::Bool(false))], + ), + ]); + + let layout = T::Vector(Box::new(struct_layout_( + "0x0::foo::Quy", + vec![("q", T::U8), ("r", T::Bool)], + ))); + + (value, layout) +} diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/identifier_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/identifier_test.rs index d70a0233d2c..39abebcf6b6 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/identifier_test.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/identifier_test.rs @@ -56,6 +56,9 @@ fn invalid_identifiers() { "foo.", "foo-bar", "foo\u{1f389}", + ">>><<<", + "foo::bar::<<>>", + "foo!!bar!!<<>>", ]; for identifier in &invalid_identifiers { assert!( @@ -66,6 +69,31 @@ fn invalid_identifiers() { } } +#[test] +fn invalid_identifier_deser() { + let invalid_identifiers = [ + "", + "_", + "0", + "01", + "9876", + "0foo", + ":foo", + "fo\\o", + "fo/o", + "foo.", + "foo-bar", + "foo\u{1f389}", + ">>><<<", + "foo::bar::<<>>", + "foo!!bar!!<<>>", + ]; + for identifier in &invalid_identifiers { + let bytes = bcs::to_bytes(identifier).unwrap(); + bcs::from_bytes::(&bytes).unwrap_err(); + } +} + proptest! { #[test] fn invalid_identifiers_proptest(identifier in invalid_identifier_strategy()) { diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs b/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs index 795fd93f008..8a36bccd760 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs @@ -3,7 +3,9 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +mod extractor_test; mod identifier_test; mod language_storage_test; +mod parsing_test; mod value_test; mod visitor_test; diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs new file mode 100644 index 00000000000..2d69de0be29 --- /dev/null +++ b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs @@ -0,0 +1,678 @@ +use crate::{ + account_address::AccountAddress, + identifier::Identifier, + language_storage::{ModuleId, StructTag, TypeTag}, + parsing::{ + address::{NumericalAddress, ParsedAddress}, + parser::parse, + types::{ParsedFqName, ParsedType, TypeToken}, + values::ParsedValue, + }, + u256::U256, +}; +use anyhow::bail; +use num::BigUint; +use proptest::{prelude::*, proptest}; +use std::str::FromStr; + +const VALID_ADDRS: &[&str] = &[ + "0x0", + "0x1", + "1", + "123", + "0x123", + "0x1234567890abcdef", + "100_00_00", + "0x0_0_0_0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0_00000_0000000000000000000000000000000000000000000000000_000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000", + "00_0000000000000000000000000000000000000000000000000000000_00000000000000000_0000", +]; + +const INVALID_ADDRS: &[&str] = &[ + "_x", + "0x", + "_0x0", + "_0", + "0x_", + "0x_00", + "+0x0", + "+0", + "0xg", + "0x0g", + "0X0", + "_0x0", + "_0x0_", + "_0", + "_0_", + "_00_", + "_0_0_", + "0x_00", + "0x00000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000_0000000", + "0x_0_00000_0000000000000000000000000000000000000000000000000_000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000_0000000000000000000000000000000000000000000000000000000_00000000000000000_0000", +]; + +#[allow(clippy::unreadable_literal)] +#[test] +fn tests_parse_value_positive() { + use ParsedValue as V; + let cases: &[(&str, V)] = &[ + (" 0u8", V::U8(0)), + ("0u8", V::U8(0)), + ("0xF_Fu8", V::U8(255)), + ("0xF__FF__Eu16", V::U16(u16::MAX - 1)), + ("0xFFF_FF__FF_Cu32", V::U32(u32::MAX - 3)), + ("255u8", V::U8(255)), + ("255u256", V::U256(U256::from(255u64))), + ("0", V::InferredNum(U256::from(0u64))), + ("0123", V::InferredNum(U256::from(123u64))), + ("0xFF", V::InferredNum(U256::from(0xFFu64))), + ("0xF_F", V::InferredNum(U256::from(0xFFu64))), + ("0xFF__", V::InferredNum(U256::from(0xFFu64))), + ( + "0x12_34__ABCD_FF", + V::InferredNum(U256::from(0x1234ABCDFFu64)), + ), + ("0u64", V::U64(0)), + ("0x0u64", V::U64(0)), + ( + "18446744073709551615", + V::InferredNum(U256::from(18446744073709551615u128)), + ), + ("18446744073709551615u64", V::U64(18446744073709551615)), + ("0u128", V::U128(0)), + ("1_0u8", V::U8(1_0)), + ("10_u8", V::U8(10)), + ("1_000u64", V::U64(1_000)), + ("1_000", V::InferredNum(U256::from(1_000u32))), + ("1_0_0_0u64", V::U64(1_000)), + ("1_000_000u128", V::U128(1_000_000)), + ( + "340282366920938463463374607431768211455u128", + V::U128(340282366920938463463374607431768211455), + ), + ("true", V::Bool(true)), + ("false", V::Bool(false)), + ( + "@0x0", + V::Address(ParsedAddress::Numerical(NumericalAddress::new( + AccountAddress::from_hex_literal("0x0") + .unwrap() + .into_bytes(), + crate::parsing::parser::NumberFormat::Hex, + ))), + ), + ( + "@0", + V::Address(ParsedAddress::Numerical(NumericalAddress::new( + AccountAddress::from_hex_literal("0x0") + .unwrap() + .into_bytes(), + crate::parsing::parser::NumberFormat::Hex, + ))), + ), + ( + "@0x54afa3526", + V::Address(ParsedAddress::Numerical(NumericalAddress::new( + AccountAddress::from_hex_literal("0x54afa3526") + .unwrap() + .into_bytes(), + crate::parsing::parser::NumberFormat::Hex, + ))), + ), + ( + "b\"hello\"", + V::Vector("hello".as_bytes().iter().copied().map(V::U8).collect()), + ), + ("x\"7fff\"", V::Vector(vec![V::U8(0x7f), V::U8(0xff)])), + ("x\"\"", V::Vector(vec![])), + ("x\"00\"", V::Vector(vec![V::U8(0x00)])), + ( + "x\"deadbeef\"", + V::Vector(vec![V::U8(0xde), V::U8(0xad), V::U8(0xbe), V::U8(0xef)]), + ), + ]; + + for (s, expected) in cases { + assert_eq!(&ParsedValue::parse(s).unwrap(), expected) + } +} + +#[test] +fn tests_parse_value_negative() { + /// Test cases for the parser that should always fail. + const PARSE_VALUE_NEGATIVE_TEST_CASES: &[&str] = &[ + "-3", + "0u42", + "0u645", + "0u64x", + "0u6 4", + "0u", + "_10", + "_10_u8", + "_10__u8", + "10_u8__", + "0xFF_u8_", + "0xF_u8__", + "0x_F_u8__", + "_", + "__", + "__4", + "_u8", + "5_bool", + "256u8", + "4294967296u32", + "65536u16", + "18446744073709551616u64", + "340282366920938463463374607431768211456u128", + "340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456u256", + "0xg", + "0x00g0", + "0x", + "0x_", + "", + "@@", + "()", + "x\"ffff", + "x\"a \"", + "x\" \"", + "x\"0g\"", + "x\"0\"", + "garbage", + "true3", + "3false", + "3 false", + "", + "0XFF", + "0X0", + ]; + + for s in PARSE_VALUE_NEGATIVE_TEST_CASES { + assert!( + ParsedValue::<()>::parse(s).is_err(), + "Unexpectedly succeeded in parsing: {}", + s + ) + } +} + +#[test] +fn test_parse_struct_negative() { + for s in &[ + "_", + "_::_::_", + "0x1::_", + "0x1::__::_", + "0x1::_::__", + "0x1::_::foo", + "0x1::foo::_", + "0x1::_::_", + "0x1::bar::foo<0x1::_::foo>", + "0x1::bar::bar::foo", + "0x1::Foo::Foo<", + "0x1::Foo::Foo<0x1::ABC::ABC", + "0x1::Foo::Foo<0x1::ABC::ABC::>", + "0x1::Foo::Foo<0x1::ABC::ABC::A>", + "0x1::Foo::Foo<>", + "0x1::Foo::Foo<,>", + "0x1::Foo::Foo<,", + "0x1::Foo::Foo,>", + "0x1::Foo::Foo>", + "0x1::Foo::Foo,", + "_0x0_0::a::a", + "_0x_00::a::a", + "_0_0::a::a", + ] { + assert!( + TypeTag::from_str(s).is_err(), + "Parsed type {s} but should have failed" + ); + } +} + +#[test] +fn test_type_type() { + for s in &[ + "u8", + "u16", + "u32", + "u64", + "u128", + "u256", + "bool", + "vector", + "vector>", + "address", + "signer", + "0x1::M::S", + "0x2::M::S_", + "0x3::M_::S", + "0x4::M_::S_", + "0x00000000004::M::S", + "0x1::M::S", + "0x1::M::S<0x2::P::Q>", + "vector<0x1::M::S>", + "vector<0x1::M_::S_>", + "vector>", + "0x1::M::S>", + "0x1::_bar::_BAR", + "0x1::__::__", + "0x1::_bar::_BAR<0x2::_____::______fooo______>", + "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", + "0x0_0::a::a", + "0_0::a::a", + ] { + assert!(TypeTag::from_str(s).is_ok(), "Failed to parse type {}", s); + } + + for valid_addr in VALID_ADDRS { + assert!( + TypeTag::from_str(&format!("{valid_addr}::a::a")).is_ok(), + "Failed to parse type {}::a::a", + valid_addr + ); + } + + for invalid_addr in INVALID_ADDRS { + assert!( + TypeTag::from_str(&format!("{invalid_addr}::a::a")).is_err(), + "Parse type {}::a::a but should have failed", + invalid_addr + ); + } +} + +#[test] +fn test_parse_valid_struct_type() { + let valid = vec![ + "0x1::Foo::Foo", + "0x1::Foo_Type::Foo", + "0x1::Foo_::Foo", + "0x1::X_123::X32_", + "0x1::Foo::Foo_Type", + "0x1::Foo::Foo<0x1::ABC::ABC>", + "0x1::Foo::Foo<0x1::ABC::ABC_Type>", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo
", + "0x1::Foo::Foo", + "0x1::Foo::Foo>", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo,address,signer>", + "0x1::Foo::Foo>>", + "0x1::Foo::Foo<0x1::Foo::Struct, 0x1::Foo::Foo>>>>", + "0x1::_bar::_BAR", + "0x1::__::__", + "0x1::_bar::_BAR<0x2::_____::______fooo______>", + "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", + ]; + for s in valid { + assert!( + StructTag::from_str(s).is_ok(), + "Failed to parse struct {}", + s + ); + } +} + +#[test] +fn test_parse_type_list() { + let valid_with_trails = &[ + "", + "", + ",>", + ]; + let valid_no_trails = &[ + "", + "", + ">", + ]; + let invalid = &[ + "<>", + "<,>", + "", + "<,u64>", + "<,u64,>", + ",", + "", + "<", + "<<", + "><", + ">,<", + ">,", + ",>", + ",,", + ">>", + "", + "u64,>", + "u64, u64,>", + "u64, u64,", + "u64, u64", + "u64 u64", + "", + "", + "u64 u64,", + "", + ",", + ",,>", + ]; + + for t in valid_no_trails.iter().chain(valid_with_trails.iter()) { + assert!(parse_type_tags(t, true).is_ok()); + } + + for t in valid_no_trails { + assert!(parse_type_tags(t, false).is_ok()); + } + + for t in valid_with_trails { + assert!(parse_type_tags(t, false).is_err()); + } + + for t in invalid { + assert!(parse_type_tags(t, true).is_err(), "parsed type {}", t); + assert!(parse_type_tags(t, false).is_err(), "parsed type {}", t); + } +} + +fn struct_type_gen0() -> impl Strategy { + ( + any::(), + any::(), + any::(), + ) + .prop_map(|(address, module, name)| format!("0x{}::{}::{}", address, module, name)) +} + +fn struct_type_gen1() -> impl Strategy { + (any::(), any::(), any::()) + .prop_map(|(address, module, name)| format!("{}::{}::{}", address, module, name)) +} + +fn module_id_gen0() -> impl Strategy { + (any::(), any::()) + .prop_map(|(address, module)| format!("0x{address}::{module}")) +} + +fn module_id_gen1() -> impl Strategy { + (any::(), any::()) + .prop_map(|(address, module)| format!("{address}::{module}")) +} + +fn fq_id_gen0() -> impl Strategy { + ( + any::(), + any::(), + any::(), + ) + .prop_map(|(address, module, name)| format!("0x{address}::{module}::{name}")) +} + +fn fq_id_gen1() -> impl Strategy { + (any::(), any::(), any::()) + .prop_map(|(address, module, name)| format!("{address}::{module}::{name}")) +} + +fn parse_type_tags(s: &str, allow_trailing_delim: bool) -> anyhow::Result> { + parse(s, |parser| { + parser.advance(TypeToken::Lt)?; + let parsed = parser.parse_list( + |parser| parser.parse_type(), + TypeToken::Comma, + TypeToken::Gt, + allow_trailing_delim, + )?; + parser.advance(TypeToken::Gt)?; + if parsed.is_empty() { + bail!("expected at least one type argument") + } + Ok(parsed) + }) +} + +#[test] +fn address_parsing() { + for valid_addr in VALID_ADDRS { + assert!( + ParsedAddress::parse(valid_addr).is_ok(), + "parsed address {}", + valid_addr + ); + } + + for invalid_addr in INVALID_ADDRS { + assert!(ParsedAddress::parse(invalid_addr).is_err()); + } +} + +proptest! { + #[test] + fn parse_type_tag_list(t in struct_type_gen0(), args in proptest::collection::vec(struct_type_gen0(), 1..=100)) { + let s_no_trail = format!("<{}>", args.join(",")); + let s_with_trail = format!("<{},>", args.join(",")); + let s_no_trail_no_trail = parse_type_tags(&s_no_trail, false); + let s_no_trail_allow_trail = parse_type_tags(&s_no_trail, true); + let s_with_trail_no_trail = parse_type_tags(&s_with_trail, false); + let s_with_trail_allow_trail = parse_type_tags(&s_with_trail, true); + prop_assert!(s_no_trail_no_trail.is_ok()); + prop_assert!(s_no_trail_allow_trail.is_ok()); + prop_assert!(s_with_trail_no_trail.is_err()); + prop_assert!(s_with_trail_allow_trail.is_ok()); + let t_with_trail = format!("{t}{s_no_trail}"); + let t_no_trail = format!("{t}{s_with_trail}"); + let t_with_trail = TypeTag::from_str(&t_with_trail); + let t_no_trail = TypeTag::from_str(&t_no_trail); + prop_assert!(t_with_trail.is_ok()); + prop_assert!(t_no_trail.is_ok()); + prop_assert_eq!(t_with_trail.unwrap(), t_no_trail.unwrap()); + } + + #[test] + fn test_parse_valid_struct_type_proptest0(s in struct_type_gen0(), x in r#"(::foo)[^a-zA-Z0-9_\s]+"#) { + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + + // Add remainder string + let s = s + &x; + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + + } + + #[test] + fn test_parse_valid_struct_type_proptest1(s in struct_type_gen1(), x in r#"(::foo)[^a-zA-Z0-9_\s]+"#) { + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_module_id_proptest0(s in module_id_gen0(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ModuleId::from_str(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_module_id_proptest1(s in module_id_gen1(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ModuleId::from_str(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder String + let s = s + &x; + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + + } + + #[test] + fn test_parse_valid_fq_id_proptest0(s in fq_id_gen0(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_fq_id_proptest1(s in fq_id_gen1(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + let s = s + &x; + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_numeric_address(s in "[0-9]{64}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_ok()); + prop_assert!(ParsedAddress::parse(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + } + + #[test] + fn decimal_parse_parity(s in "[0-9]{64}") { + let bigint_parsed = { + let bytes = BigUint::parse_bytes(s.as_bytes(), 10).unwrap().to_bytes_be(); + let mut result = [0u8; AccountAddress::LENGTH]; + result[(AccountAddress::LENGTH - bytes.len())..].clone_from_slice(&bytes); + result + }; + let u256_parsed = U256::from_str(&s).unwrap(); + prop_assert_eq!(bigint_parsed, u256_parsed.to_be_bytes(), "Parsed addresses do not match: {}", s); + } + + #[test] + fn hex_parse_parity(s in "0x[0-9a-fA-F]{1,64}") { + let bigint_parsed = { + let bytes = BigUint::parse_bytes(s[2..].as_bytes(), 16).unwrap().to_bytes_be(); + let mut result = [0u8; AccountAddress::LENGTH]; + result[(AccountAddress::LENGTH - bytes.len())..].clone_from_slice(&bytes); + result + }; + let addr_parsed = AccountAddress::from_hex_literal(&s).unwrap().into_bytes(); + let u256_parsed = AccountAddress::new(U256::from_str_radix(&s[2..], 16).unwrap().to_be_bytes()).into_bytes(); + prop_assert_eq!(bigint_parsed, addr_parsed, "Parsed addresses do not match: {}", s); + prop_assert_eq!(addr_parsed, u256_parsed, "Parsed addresses do not match: {}", s); + } + + #[test] + fn test_parse_different_length_numeric_addresses(s in "[0-9]{1,63}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + } + + #[test] + fn test_parse_valid_hex_address(s in "0x[0-9a-fA-F]{64}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_ok()); + prop_assert!(ParsedAddress::parse(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + } + + #[test] + fn test_parse_invalid_hex_address(s in "[0-9]{63}[a-fA-F]{1}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_ok()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + } +} diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/value_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/value_test.rs index 6bfad4725a6..de6b8813e97 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/value_test.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/value_test.rs @@ -13,6 +13,12 @@ use crate::{ runtime_value as R, }; +#[test] +fn check_layout_size() { + assert_eq!(std::mem::size_of::(), 16); + assert_eq!(std::mem::size_of::(), 16); +} + #[test] fn struct_deserialization() { let struct_type = StructTag { @@ -39,17 +45,21 @@ fn struct_deserialization() { let struct_type_layout = A::MoveStructLayout { type_: struct_type.clone(), - fields: vec![ - A::MoveFieldLayout::new(ident_str!("f").to_owned(), A::MoveTypeLayout::U64), - A::MoveFieldLayout::new(ident_str!("g").to_owned(), A::MoveTypeLayout::Bool), - ] - .into_iter() - .collect(), + fields: Box::new( + vec![ + A::MoveFieldLayout::new(ident_str!("f").to_owned(), A::MoveTypeLayout::U64), + A::MoveFieldLayout::new(ident_str!("g").to_owned(), A::MoveTypeLayout::Bool), + ] + .into_iter() + .collect(), + ), }; - let deser_typed_value = - A::MoveValue::simple_deserialize(&ser, &A::MoveTypeLayout::Struct(struct_type_layout)) - .unwrap(); + let deser_typed_value = A::MoveValue::simple_deserialize( + &ser, + &A::MoveTypeLayout::Struct(Box::new(struct_type_layout)), + ) + .unwrap(); let typed_value = A::MoveStruct::new(struct_type, field_values); assert_eq!( @@ -98,8 +108,8 @@ fn enum_deserialization() { R::MoveTypeLayout::Bool, R::MoveTypeLayout::U8, ]; - let enum_layout = R::MoveEnumLayout(vec![variant_layout1, variant_layout2]); - R::MoveTypeLayout::Enum(enum_layout) + let enum_layout = R::MoveEnumLayout(Box::new(vec![variant_layout1, variant_layout2])); + R::MoveTypeLayout::Enum(Box::new(enum_layout)) }; // test each deserialization scheme @@ -158,9 +168,11 @@ fn enum_deserialization() { json!([1, [8, false, 0]]) ); - let deser_typed_value = - A::MoveValue::simple_deserialize(&ser, &A::MoveTypeLayout::Enum(enum_type_layout.clone())) - .unwrap(); + let deser_typed_value = A::MoveValue::simple_deserialize( + &ser, + &A::MoveTypeLayout::Enum(Box::new(enum_type_layout.clone())), + ) + .unwrap(); let typed_value = A::MoveVariant { type_: enum_type.clone(), variant_name: ident_str!("Variant1").to_owned(), @@ -184,9 +196,11 @@ fn enum_deserialization() { let ser1 = R::MoveValue::Variant(runtime_value.clone()) .simple_serialize() .unwrap(); - let deser1_typed_value = - A::MoveValue::simple_deserialize(&ser1, &A::MoveTypeLayout::Enum(enum_type_layout)) - .unwrap(); + let deser1_typed_value = A::MoveValue::simple_deserialize( + &ser1, + &A::MoveTypeLayout::Enum(Box::new(enum_type_layout)), + ) + .unwrap(); let typed_value = A::MoveVariant { type_: enum_type, variant_name: ident_str!("Variant2").to_owned(), @@ -222,10 +236,10 @@ fn enum_deserialization_vec_option_runtime_layout_equiv() { let vec_ser = vec_option.simple_serialize().unwrap(); let enum_ser = enum_option.simple_serialize().unwrap(); - let enum_layout = R::MoveTypeLayout::Enum(R::MoveEnumLayout(vec![ + let enum_layout = R::MoveTypeLayout::Enum(Box::new(R::MoveEnumLayout(Box::new(vec![ vec![], vec![R::MoveTypeLayout::U64], - ])); + ])))); let vec_layout = R::MoveTypeLayout::Vector(Box::new(R::MoveTypeLayout::U64)); diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/visitor_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/visitor_test.rs index 53514766888..d15e0b92e65 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/visitor_test.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/visitor_test.rs @@ -11,7 +11,8 @@ use crate::{ MoveVariant, }, annotated_visitor::{ - self, NullTraversal, StructDriver, Traversal, VariantDriver, VecDriver, Visitor, + self, NullTraversal, StructDriver, Traversal, ValueDriver, VariantDriver, VecDriver, + Visitor, }, identifier::Identifier, language_storage::StructTag, @@ -19,89 +20,284 @@ use crate::{ VARIANT_COUNT_MAX, }; -#[test] -fn traversal() { - use MoveTypeLayout as T; - use MoveValue as V; +#[derive(Default)] +pub(crate) struct CountingTraversal(usize); - #[derive(Default)] - struct CountingTraversal(usize); +#[derive(Default)] +pub(crate) struct PrintVisitor { + depth: usize, + pub output: String, +} - impl Traversal for CountingTraversal { - type Error = annotated_visitor::Error; +impl<'b, 'l> Traversal<'b, 'l> for CountingTraversal { + type Error = annotated_visitor::Error; - fn traverse_u8(&mut self, _: u8) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_u8( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u8, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_u16(&mut self, _: u16) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_u16( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u16, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_u32(&mut self, _: u32) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_u32( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u32, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_u64(&mut self, _: u64) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_u64( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u64, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_u128(&mut self, _: u128) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_u128( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: u128, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_u256(&mut self, _: U256) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_u256( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: U256, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_bool(&mut self, _: bool) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_bool( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: bool, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_address(&mut self, _: AccountAddress) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_address( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: AccountAddress, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_signer(&mut self, _: AccountAddress) -> Result<(), Self::Error> { - self.0 += 1; - Ok(()) - } + fn traverse_signer( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + _value: AccountAddress, + ) -> Result<(), Self::Error> { + self.0 += 1; + Ok(()) + } - fn traverse_vector( - &mut self, - driver: &mut VecDriver<'_, '_, '_>, - ) -> Result<(), Self::Error> { - self.0 += 1; - while driver.next_element(self)?.is_some() {} - Ok(()) + fn traverse_vector(&mut self, driver: &mut VecDriver<'_, 'b, 'l>) -> Result<(), Self::Error> { + self.0 += 1; + while driver.next_element(self)?.is_some() {} + Ok(()) + } + + fn traverse_struct( + &mut self, + driver: &mut StructDriver<'_, 'b, 'l>, + ) -> Result<(), Self::Error> { + self.0 += 1; + while driver.next_field(self)?.is_some() {} + Ok(()) + } + + fn traverse_variant( + &mut self, + driver: &mut VariantDriver<'_, 'b, 'l>, + ) -> Result<(), Self::Error> { + self.0 += 1; + while driver.next_field(self)?.is_some() {} + Ok(()) + } +} + +impl<'b, 'l> Visitor<'b, 'l> for PrintVisitor { + type Value = MoveValue; + type Error = annotated_visitor::Error; + + fn visit_u8( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u8, + ) -> Result { + write!(self.output, "\n[{}] {value}: u8", self.depth).unwrap(); + Ok(MoveValue::U8(value)) + } + + fn visit_u16( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u16, + ) -> Result { + write!(self.output, "\n[{}] {value}: u16", self.depth).unwrap(); + Ok(MoveValue::U16(value)) + } + + fn visit_u32( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u32, + ) -> Result { + write!(self.output, "\n[{}] {value}: u32", self.depth).unwrap(); + Ok(MoveValue::U32(value)) + } + + fn visit_u64( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result { + write!(self.output, "\n[{}] {value}: u64", self.depth).unwrap(); + Ok(MoveValue::U64(value)) + } + + fn visit_u128( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u128, + ) -> Result { + write!(self.output, "\n[{}] {value}: u128", self.depth).unwrap(); + Ok(MoveValue::U128(value)) + } + + fn visit_u256( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: U256, + ) -> Result { + write!(self.output, "\n[{}] {value}: u256", self.depth).unwrap(); + Ok(MoveValue::U256(value)) + } + + fn visit_bool( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: bool, + ) -> Result { + write!(self.output, "\n[{}] {value}: bool", self.depth).unwrap(); + Ok(MoveValue::Bool(value)) + } + + fn visit_address( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { + write!(self.output, "\n[{}] {value}: address", self.depth).unwrap(); + Ok(MoveValue::Address(value)) + } + + fn visit_signer( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { + write!(self.output, "\n[{}] {value}: signer", self.depth).unwrap(); + Ok(MoveValue::Signer(value)) + } + + fn visit_vector( + &mut self, + driver: &mut VecDriver<'_, 'b, 'l>, + ) -> Result { + let layout = driver.element_layout(); + write!(self.output, "\n[{}] vector<{layout:#}>", self.depth).unwrap(); + + let mut elems = vec![]; + let mut elem_visitor = Self { + depth: self.depth + 1, + output: std::mem::take(&mut self.output), + }; + + while let Some(elem) = driver.next_element(&mut elem_visitor)? { + elems.push(elem) } - fn traverse_struct( - &mut self, - driver: &mut StructDriver<'_, '_, '_>, - ) -> Result<(), Self::Error> { - self.0 += 1; - while driver.next_field(self)?.is_some() {} - Ok(()) + self.output = elem_visitor.output; + Ok(MoveValue::Vector(elems)) + } + + fn visit_struct( + &mut self, + driver: &mut StructDriver<'_, 'b, 'l>, + ) -> Result { + let layout = driver.struct_layout(); + write!(self.output, "\n[{}] {layout:#}", self.depth).unwrap(); + + let mut fields = vec![]; + let mut field_visitor = Self { + depth: self.depth + 1, + output: std::mem::take(&mut self.output), + }; + + while let Some((field, value)) = driver.next_field(&mut field_visitor)? { + fields.push((field.name.clone(), value)); } - fn traverse_variant( - &mut self, - driver: &mut VariantDriver<'_, '_, '_>, - ) -> Result<(), Self::Error> { - self.0 += 1; - while driver.next_field(self)?.is_some() {} - Ok(()) + self.output = field_visitor.output; + let type_ = driver.struct_layout().type_.clone(); + Ok(MoveValue::Struct(MoveStruct { type_, fields })) + } + + fn visit_variant( + &mut self, + driver: &mut VariantDriver<'_, 'b, 'l>, + ) -> Result { + let layout = driver.enum_layout(); + write!(self.output, "\n[{}] {layout:#}", self.depth).unwrap(); + + let mut fields = vec![]; + let mut field_visitor = Self { + depth: self.depth + 1, + output: std::mem::take(&mut self.output), + }; + + while let Some((field, value)) = driver.next_field(&mut field_visitor)? { + fields.push((field.name.clone(), value)); } + + self.output = field_visitor.output; + let type_ = driver.enum_layout().type_.clone(); + Ok(MoveValue::Variant(MoveVariant { + type_, + variant_name: driver.variant_name().to_owned(), + tag: driver.tag(), + fields, + })) } +} + +#[test] +fn traversal() { + use MoveTypeLayout as T; + use MoveValue as V; let type_layout = struct_layout_( "0x0::foo::Bar", @@ -298,132 +494,6 @@ fn nested_datatype_visit() { use MoveTypeLayout as T; use MoveValue as V; - #[derive(Default)] - struct PrintVisitor { - depth: usize, - output: String, - } - - impl Visitor for PrintVisitor { - type Value = MoveValue; - type Error = annotated_visitor::Error; - - fn visit_u8(&mut self, value: u8) -> Result { - write!(self.output, "\n[{}] {value}: u8", self.depth).unwrap(); - Ok(V::U8(value)) - } - - fn visit_u16(&mut self, value: u16) -> Result { - write!(self.output, "\n[{}] {value}: u16", self.depth).unwrap(); - Ok(V::U16(value)) - } - - fn visit_u32(&mut self, value: u32) -> Result { - write!(self.output, "\n[{}] {value}: u32", self.depth).unwrap(); - Ok(V::U32(value)) - } - - fn visit_u64(&mut self, value: u64) -> Result { - write!(self.output, "\n[{}] {value}: u64", self.depth).unwrap(); - Ok(V::U64(value)) - } - - fn visit_u128(&mut self, value: u128) -> Result { - write!(self.output, "\n[{}] {value}: u128", self.depth).unwrap(); - Ok(V::U128(value)) - } - - fn visit_u256(&mut self, value: U256) -> Result { - write!(self.output, "\n[{}] {value}: u256", self.depth).unwrap(); - Ok(V::U256(value)) - } - - fn visit_bool(&mut self, value: bool) -> Result { - write!(self.output, "\n[{}] {value}: bool", self.depth).unwrap(); - Ok(V::Bool(value)) - } - - fn visit_address(&mut self, value: AccountAddress) -> Result { - write!(self.output, "\n[{}] {value}: address", self.depth).unwrap(); - Ok(V::Address(value)) - } - - fn visit_signer(&mut self, value: AccountAddress) -> Result { - write!(self.output, "\n[{}] {value}: signer", self.depth).unwrap(); - Ok(V::Signer(value)) - } - - fn visit_vector( - &mut self, - driver: &mut VecDriver<'_, '_, '_>, - ) -> Result { - let layout = driver.element_layout(); - write!(self.output, "\n[{}] vector<{layout:#}>", self.depth).unwrap(); - - let mut elems = vec![]; - let mut elem_visitor = Self { - depth: self.depth + 1, - output: std::mem::take(&mut self.output), - }; - - while let Some(elem) = driver.next_element(&mut elem_visitor)? { - elems.push(elem) - } - - self.output = elem_visitor.output; - Ok(V::Vector(elems)) - } - - fn visit_struct( - &mut self, - driver: &mut StructDriver<'_, '_, '_>, - ) -> Result { - let layout = driver.struct_layout(); - write!(self.output, "\n[{}] {layout:#}", self.depth).unwrap(); - - let mut fields = vec![]; - let mut field_visitor = Self { - depth: self.depth + 1, - output: std::mem::take(&mut self.output), - }; - - while let Some((field, value)) = driver.next_field(&mut field_visitor)? { - fields.push((field.name.clone(), value)); - } - - self.output = field_visitor.output; - let type_ = driver.struct_layout().type_.clone(); - Ok(V::Struct(MoveStruct { type_, fields })) - } - - fn visit_variant( - &mut self, - driver: &mut VariantDriver<'_, '_, '_>, - ) -> Result { - let layout = driver.enum_layout(); - write!(self.output, "\n[{}] {layout:#}", self.depth).unwrap(); - - let mut fields = vec![]; - let mut field_visitor = Self { - depth: self.depth + 1, - output: std::mem::take(&mut self.output), - }; - - while let Some((field, value)) = driver.next_field(&mut field_visitor)? { - fields.push((field.name.clone(), value)); - } - - self.output = field_visitor.output; - let type_ = driver.enum_layout().type_.clone(); - Ok(V::Variant(MoveVariant { - type_, - variant_name: driver.variant_name().to_owned(), - tag: driver.tag(), - fields, - })) - } - } - let type_layout = struct_layout_( "0x0::foo::Bar", vec![ @@ -522,17 +592,21 @@ fn peek_field_test() { fields: &'f [&'f str], } - impl<'f> Visitor for PeekU64Visitor<'f> { + impl<'b, 'l, 'f> Visitor<'b, 'l> for PeekU64Visitor<'f> { type Value = Option; type Error = annotated_visitor::Error; - fn visit_u64(&mut self, value: u64) -> Result { + fn visit_u64( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result { Ok(self.fields.is_empty().then_some(value)) } fn visit_struct( &mut self, - driver: &mut StructDriver<'_, '_, '_>, + driver: &mut StructDriver<'_, 'b, 'l>, ) -> Result { let [field, fields @ ..] = self.fields else { return Ok(None); @@ -553,7 +627,7 @@ fn peek_field_test() { fn visit_variant( &mut self, - driver: &mut VariantDriver<'_, '_, '_>, + driver: &mut VariantDriver<'_, 'b, 'l>, ) -> Result { let [field, fields @ ..] = self.fields else { return Ok(None); @@ -574,35 +648,67 @@ fn peek_field_test() { // === Empty/default cases === - fn visit_u8(&mut self, _: u8) -> Result { + fn visit_u8( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: u8, + ) -> Result { Ok(None) } - fn visit_u16(&mut self, _: u16) -> Result { + fn visit_u16( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: u16, + ) -> Result { Ok(None) } - fn visit_u32(&mut self, _: u32) -> Result { + fn visit_u32( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: u32, + ) -> Result { Ok(None) } - fn visit_u128(&mut self, _: u128) -> Result { + fn visit_u128( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: u128, + ) -> Result { Ok(None) } - fn visit_u256(&mut self, _: U256) -> Result { + fn visit_u256( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: U256, + ) -> Result { Ok(None) } - fn visit_bool(&mut self, _: bool) -> Result { + fn visit_bool( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: bool, + ) -> Result { Ok(None) } - fn visit_address(&mut self, _: AccountAddress) -> Result { + fn visit_address( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: AccountAddress, + ) -> Result { Ok(None) } - fn visit_signer(&mut self, _: AccountAddress) -> Result { + fn visit_signer( + &mut self, + _: &ValueDriver<'_, 'b, 'l>, + _: AccountAddress, + ) -> Result { Ok(None) } @@ -610,7 +716,7 @@ fn peek_field_test() { /// the field we want under here. fn visit_vector( &mut self, - _: &mut VecDriver<'_, '_, '_>, + _: &mut VecDriver<'_, 'b, 'l>, ) -> Result { Ok(None) } @@ -672,8 +778,286 @@ fn peek_field_test() { assert_eq!(visit_struct(&["f", "h"]), Some(46)); } +#[test] +fn byte_offset_test() { + use MoveTypeLayout as T; + use MoveValue as V; + + #[derive(Default)] + struct ByteOffsetVisitor(String); + + impl<'b, 'l> Traversal<'b, 'l> for ByteOffsetVisitor { + type Error = annotated_visitor::Error; + + fn traverse_u8( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u8, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: u8", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_u16( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u16, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: u16", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_u32( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u32, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: u32", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_u64( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: u64", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_u128( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: u128, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: u128", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_u256( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: U256, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: u256", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_bool( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: bool, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {value}: bool", + driver.start(), + driver.position() + ) + .unwrap(); + Ok(()) + } + + fn traverse_address( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {}: address", + driver.start(), + driver.position(), + value.to_canonical_display(/* with_prefix */ true), + ) + .unwrap(); + Ok(()) + } + + fn traverse_signer( + &mut self, + driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {}: address", + driver.start(), + driver.position(), + value.to_canonical_display(/* with_prefix */ true), + ) + .unwrap(); + Ok(()) + } + + fn traverse_vector( + &mut self, + driver: &mut VecDriver<'_, 'b, 'l>, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] vector<{:#}>", + driver.start(), + driver.position(), + driver.element_layout(), + ) + .unwrap(); + while driver.next_element(self)?.is_some() {} + Ok(()) + } + + fn traverse_struct( + &mut self, + driver: &mut StructDriver<'_, 'b, 'l>, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {:#}", + driver.start(), + driver.position(), + driver.struct_layout(), + ) + .unwrap(); + + while let Some((_, ())) = driver.next_field(self)? {} + Ok(()) + } + + fn traverse_variant( + &mut self, + driver: &mut VariantDriver<'_, 'b, 'l>, + ) -> Result<(), Self::Error> { + write!( + &mut self.0, + "\n[{:>3} .. {:>3}] {:#}", + driver.start(), + driver.position(), + driver.enum_layout(), + ) + .unwrap(); + + while let Some((_, ())) = driver.next_field(self)? {} + Ok(()) + } + } + + let type_layout = struct_layout_( + "0x0::foo::Bar", + vec![ + ( + "inner", + struct_layout_( + "0x0::baz::Qux", + vec![("f", T::U64), ("g", T::Vector(Box::new(T::U32)))], + ), + ), + ( + "last", + enum_layout_("0x0::foo::Baz", vec![("e", vec![("h", T::U64)])]), + ), + ], + ); + + let T::Struct(struct_layout) = &type_layout else { + panic!("Not a struct layout"); + }; + + let bytes = serialize(struct_value_( + "0x0::foo::Bar", + vec![ + ( + "inner", + struct_value_( + "0x0::baz::Qux", + vec![ + ("f", V::U64(7)), + ("g", V::Vector(vec![V::U32(1), V::U32(2), V::U32(3)])), + ], + ), + ), + ( + "last", + variant_value_("0x0::foo::Baz", "e", 0, vec![("h", V::U64(4))]), + ), + ], + )); + + let mut value_visitor = ByteOffsetVisitor::default(); + MoveValue::visit_deserialize(&bytes, &type_layout, &mut value_visitor).unwrap(); + + let mut struct_visitor = ByteOffsetVisitor::default(); + MoveStruct::visit_deserialize(&bytes, struct_layout, &mut struct_visitor).unwrap(); + + let expected_output = r#" +[ 0 .. 0] struct 0x0::foo::Bar { + inner: struct 0x0::baz::Qux { + f: u64, + g: vector, + }, + last: enum 0x0::foo::Baz { + e { + h: u64, + }, + }, +} +[ 0 .. 0] struct 0x0::baz::Qux { + f: u64, + g: vector, +} +[ 0 .. 8] 7: u64 +[ 8 .. 9] vector +[ 9 .. 13] 1: u32 +[ 13 .. 17] 2: u32 +[ 17 .. 21] 3: u32 +[ 21 .. 22] enum 0x0::foo::Baz { + e { + h: u64, + }, +} +[ 22 .. 30] 4: u64"#; + + assert_eq!(value_visitor.0, expected_output); + assert_eq!(struct_visitor.0, expected_output); +} + /// Create a struct value for test purposes. -fn struct_value_(rep: &str, fields: Vec<(&str, MoveValue)>) -> MoveValue { +pub(crate) fn struct_value_(rep: &str, fields: Vec<(&str, MoveValue)>) -> MoveValue { let type_ = StructTag::from_str(rep).unwrap(); let fields = fields .into_iter() @@ -684,18 +1068,26 @@ fn struct_value_(rep: &str, fields: Vec<(&str, MoveValue)>) -> MoveValue { } /// Create a struct layout for test purposes. -fn struct_layout_(rep: &str, fields: Vec<(&str, MoveTypeLayout)>) -> MoveTypeLayout { +pub(crate) fn struct_layout_(rep: &str, fields: Vec<(&str, MoveTypeLayout)>) -> MoveTypeLayout { let type_ = StructTag::from_str(rep).unwrap(); let fields = fields .into_iter() .map(|(name, layout)| MoveFieldLayout::new(Identifier::new(name).unwrap(), layout)) .collect(); - MoveTypeLayout::Struct(MoveStructLayout { type_, fields }) + MoveTypeLayout::Struct(Box::new(MoveStructLayout { + type_, + fields: Box::new(fields), + })) } /// Create a variant value for test purposes. -fn variant_value_(rep: &str, name: &str, tag: u16, fields: Vec<(&str, MoveValue)>) -> MoveValue { +pub(crate) fn variant_value_( + rep: &str, + name: &str, + tag: u16, + fields: Vec<(&str, MoveValue)>, +) -> MoveValue { let type_ = StructTag::from_str(rep).unwrap(); let fields = fields .into_iter() @@ -711,7 +1103,10 @@ fn variant_value_(rep: &str, name: &str, tag: u16, fields: Vec<(&str, MoveValue) } /// Create an enum layout for test purposes. -fn enum_layout_(rep: &str, variants: Vec<(&str, Vec<(&str, MoveTypeLayout)>)>) -> MoveTypeLayout { +pub(crate) fn enum_layout_( + rep: &str, + variants: Vec<(&str, Vec<(&str, MoveTypeLayout)>)>, +) -> MoveTypeLayout { let type_ = StructTag::from_str(rep).unwrap(); let variants = variants .into_iter() @@ -725,10 +1120,10 @@ fn enum_layout_(rep: &str, variants: Vec<(&str, Vec<(&str, MoveTypeLayout)>)>) - }) .collect(); - MoveTypeLayout::Enum(MoveEnumLayout { type_, variants }) + MoveTypeLayout::Enum(Box::new(MoveEnumLayout { type_, variants })) } /// BCS encode Move value. -fn serialize(value: MoveValue) -> Vec { +pub(crate) fn serialize(value: MoveValue) -> Vec { value.clone().undecorate().simple_serialize().unwrap() } diff --git a/external-crates/move/crates/move-coverage/Cargo.toml b/external-crates/move/crates/move-coverage/Cargo.toml index b3a0ea529af..89c536b64bc 100644 --- a/external-crates/move/crates/move-coverage/Cargo.toml +++ b/external-crates/move/crates/move-coverage/Cargo.toml @@ -17,6 +17,7 @@ serde.workspace = true bcs.workspace = true +indexmap.workspace = true move-abstract-interpreter.workspace = true move-binary-format.workspace = true move-bytecode-source-map.workspace = true diff --git a/external-crates/move/crates/move-coverage/src/source_coverage.rs b/external-crates/move/crates/move-coverage/src/source_coverage.rs index 2d5a5cf5fc9..81f743afbde 100644 --- a/external-crates/move/crates/move-coverage/src/source_coverage.rs +++ b/external-crates/move/crates/move-coverage/src/source_coverage.rs @@ -14,6 +14,7 @@ use std::{ use codespan::{Files, Span}; use colored::*; +use indexmap::IndexSet; use move_binary_format::{ file_format::{CodeOffset, FunctionDefinitionIndex}, CompiledModule, @@ -37,7 +38,7 @@ pub struct SourceCoverageBuilder<'a> { source_map: &'a SourceMap, } -#[derive(Debug, Serialize, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Serialize, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum AbstractSegment { Bounded { start: u32, end: u32 }, BoundedRight { end: u32 }, @@ -154,7 +155,7 @@ impl<'a> SourceCoverageBuilder<'a> { let end_line = end_loc.line.0; let segments = uncovered_segments .entry(start_line) - .or_insert_with(Vec::new); + .or_insert_with(IndexSet::new); if start_line == end_line { let segment = AbstractSegment::Bounded { start: start_loc.column.0, @@ -163,18 +164,20 @@ impl<'a> SourceCoverageBuilder<'a> { // TODO: There is some issue with the source map where we have multiple spans // from different functions. This can be seen in the source map for `Roles.move` if !segments.contains(&segment) { - segments.push(segment); + segments.insert(segment); } } else { - segments.push(AbstractSegment::BoundedLeft { + segments.insert(AbstractSegment::BoundedLeft { start: start_loc.column.0, }); for i in start_line + 1..end_line { - let segment = uncovered_segments.entry(i).or_insert_with(Vec::new); - segment.push(AbstractSegment::BoundedLeft { start: 0 }); + let segment = uncovered_segments.entry(i).or_insert_with(IndexSet::new); + segment.insert(AbstractSegment::BoundedLeft { start: 0 }); } - let last_segment = uncovered_segments.entry(end_line).or_insert_with(Vec::new); - last_segment.push(AbstractSegment::BoundedRight { + let last_segment = uncovered_segments + .entry(end_line) + .or_insert_with(IndexSet::new); + last_segment.insert(AbstractSegment::BoundedRight { end: end_loc.column.0, }); } diff --git a/external-crates/move/crates/move-disassembler/Cargo.toml b/external-crates/move/crates/move-disassembler/Cargo.toml index 4c4fd38e48f..edb036d8e3d 100644 --- a/external-crates/move/crates/move-disassembler/Cargo.toml +++ b/external-crates/move/crates/move-disassembler/Cargo.toml @@ -9,7 +9,7 @@ description = "Print a human-readable version of Move bytecode (.mv files)" [dependencies] anyhow.workspace = true -colored.workspace = true +inline_colorization.workspace = true move-abstract-interpreter.workspace = true move-binary-format.workspace = true diff --git a/external-crates/move/crates/move-disassembler/src/disassembler.rs b/external-crates/move/crates/move-disassembler/src/disassembler.rs index b2533f19b8d..905e427cc70 100644 --- a/external-crates/move/crates/move-disassembler/src/disassembler.rs +++ b/external-crates/move/crates/move-disassembler/src/disassembler.rs @@ -3,33 +3,36 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::collections::HashMap; +use std::{ + collections::{BTreeMap, HashMap}, + fmt::{self, Write}, +}; -use anyhow::{bail, format_err, Result}; +use anyhow::Result; use clap::Parser; -use colored::*; +use inline_colorization as IC; use move_abstract_interpreter::control_flow_graph::{ControlFlowGraph, VMControlFlowGraph}; use move_binary_format::{ + CompiledModule, file_format::{ - Ability, AbilitySet, Bytecode, CodeUnit, Constant, DatatypeTyParameter, EnumDefinition, - EnumDefinitionIndex, FieldHandleIndex, FunctionDefinition, FunctionDefinitionIndex, - FunctionHandle, JumpTableInner, ModuleHandle, Signature, SignatureIndex, SignatureToken, - StructDefinition, StructDefinitionIndex, StructFieldInformation, TableIndex, TypeSignature, - Visibility, + Ability, AbilitySet, Bytecode, CodeUnit, Constant, DatatypeTyParameter, + EnumDefinitionIndex, FieldHandleIndex, FunctionDefinitionIndex, FunctionHandle, + JumpTableInner, ModuleHandle, Signature, SignatureIndex, SignatureToken, + StructDefinitionIndex, StructFieldInformation, TableIndex, TypeSignature, Visibility, }, - CompiledModule, }; use move_bytecode_source_map::{ mapping::SourceMapping, source_map::{FunctionSourceMap, SourceName}, }; -use move_command_line_common::display::{try_render_constant, RenderResult}; +use move_command_line_common::display::{RenderResult, try_render_constant}; use move_compiler::compiled_unit::CompiledUnit; use move_core_types::{identifier::IdentStr, language_storage::ModuleId}; use move_coverage::coverage_map::{ExecCoverageMap, FunctionCoverage}; use move_ir_types::location::Loc; const PREVIEW_LEN: usize = 4; +const MAX_OUTPUT_SIZE: usize = 1024 * 1024; /// Holds the various options that we support while disassembling code. #[derive(Debug, Default, Parser)] @@ -49,6 +52,11 @@ pub struct DisassemblerOptions { /// Print the locals inside each function body. #[clap(long = "print-locals")] pub print_locals: bool, + + /// Maximum size of the output. If the output exceeds this size, the + /// disassembler will return an error. + #[clap(long = "max-output-size")] + pub max_output_size: Option, } impl DisassemblerOptions { @@ -58,6 +66,7 @@ impl DisassemblerOptions { print_code: true, print_basic_blocks: true, print_locals: true, + max_output_size: Some(MAX_OUTPUT_SIZE), } } } @@ -75,6 +84,65 @@ pub struct Disassembler<'a> { module_aliases: HashMap, } +struct BoundedBuffer<'a> { + budget: usize, + buf: &'a mut String, +} + +impl<'a> Write for BoundedBuffer<'a> { + fn write_str(&mut self, s: &str) -> fmt::Result { + if self.budget < s.len() { + return Err(fmt::Error); + } + self.budget -= s.len(); + self.buf.push_str(s); + Ok(()) + } +} + +macro_rules! any_writeln { + ($buf:expr) => { + any_writeln!($buf,) + }; + ($buf:expr, $($args:tt)*) => { + std::writeln!($buf, $($args)*).map_err(anyhow::Error::from) + }; +} + +macro_rules! any_write { + ($buf:expr) => { + any_write!($buf,) + }; + ($buf:expr, $($args:tt)*) => { + std::write!($buf, $($args)*).map_err(anyhow::Error::from) + }; +} + +fn delimited_list( + items: impl IntoIterator, + prefix: &str, + delimiter: &str, + suffix: &str, + buf: &mut W, + printer: F, +) -> Result<()> +where + W: Write, + F: Fn(&mut W, T) -> Result<()>, +{ + let mut first = prefix; + let mut last = ""; + for item in items { + buf.write_str(first)?; + first = delimiter; + last = suffix; + printer(buf, item)?; + } + buf.write_str(last)?; + + Ok(()) +} + impl<'a> Disassembler<'a> { pub fn new(source_mapper: SourceMapping<'a>, options: DisassemblerOptions) -> Self { let mut module_names = HashMap::new(); @@ -103,8 +171,17 @@ impl<'a> Disassembler<'a> { } pub fn from_module(module: &'a CompiledModule, default_loc: Loc) -> Result { + Self::from_module_with_max_size(module, default_loc, None) + } + + pub fn from_module_with_max_size( + module: &'a CompiledModule, + default_loc: Loc, + max_size: Option, + ) -> Result { let mut options = DisassemblerOptions::new(); options.print_code = true; + options.max_output_size = max_size; Ok(Self::new( SourceMapping::new_without_source_map(module, default_loc)?, options, @@ -123,727 +200,751 @@ impl<'a> Disassembler<'a> { self.coverage_map = Some(coverage_map); } - //*************************************************************************** - // Helpers - //*************************************************************************** - - fn get_function_string( - &self, - module_handle: &ModuleHandle, - function_handle: &FunctionHandle, - ) -> String { - let module_id = self - .source_mapper - .bytecode - .module_id_for_handle(module_handle); - let function_name = self - .source_mapper - .bytecode - .identifier_at(function_handle.name) - .to_string(); - if self.is_self_id(&module_id) { - // this is the "self" module. Omit the "module_name::" prefix - function_name + pub fn disassemble(&self) -> Result { + let mut buffer = String::new(); + if let Some(budget) = self.options.max_output_size { + self.print_module(&mut BoundedBuffer { + buf: &mut buffer, + budget, + }) + .map_err(|e| anyhow::anyhow!("{e}: Module exceeded max allowed disassembly size"))?; } else { - let module_name = self - .module_aliases - .get(&module_id) - .cloned() - .unwrap_or_else(|| module_id.name().to_string()); - format!("{}::{}", module_name, function_name) - } + self.print_module(&mut buffer)?; + }; + Ok(buffer) } +} - fn get_import_string(&self, module_handle: &ModuleHandle) -> Option { - let module_id = self - .source_mapper - .bytecode - .module_id_for_handle(module_handle); - if self.is_self_id(&module_id) { - // No need to import self handle - None - } else if let Some(alias) = self.module_aliases.get(&module_id) { - Some(format!( - "use {}::{} as {};", - module_id.address(), - module_id.name(), - alias - )) - } else { - Some(format!( - "use {}::{};", - module_id.address(), - module_id.name() - )) - } +// Note on naming: +// * disassemble_* and print_* functions are functions that output to the buffer +// * format_* functions return a string that can be used in the buffer +impl<'a> Disassembler<'a> { + fn print_module(&self, buffer: &mut impl Write) -> Result<()> { + // NB: The order in which these are called is important as each function is + // effectful. + self.print_header(buffer)?; + self.print_imports(buffer)?; + self.print_user_defined_types(buffer)?; + self.print_function_definitions(buffer)?; + self.print_constants(buffer)?; + self.print_footer(buffer)?; + Ok(()) } - fn is_self_id(&self, mid: &ModuleId) -> bool { - &self.source_mapper.bytecode.self_id() == mid + fn print_header(&self, buffer: &mut impl Write) -> Result<()> { + let (addr, n) = &self.source_mapper.source_map.module_name; + any_writeln!( + buffer, + "// Move bytecode v{version}\nmodule {addr}.{name} {{", + version = self.source_mapper.bytecode.version(), + addr = addr.short_str_lossless(), + name = n, + ) } - fn get_function_def( - &self, - function_definition_index: FunctionDefinitionIndex, - ) -> Result<&FunctionDefinition> { - if function_definition_index.0 as usize >= self.source_mapper.bytecode.function_defs().len() - { - bail!("Invalid function definition index supplied when marking function") + fn print_imports(&self, buffer: &mut impl Write) -> Result<()> { + for h in self.source_mapper.bytecode.module_handles().iter() { + self.disassemble_import(buffer, h)?; } - Ok(self - .source_mapper - .bytecode - .function_def_at(function_definition_index)) - } - fn get_struct_def( - &self, - struct_definition_index: StructDefinitionIndex, - ) -> Result<&StructDefinition> { - if struct_definition_index.0 as usize >= self.source_mapper.bytecode.struct_defs().len() { - bail!("Invalid struct definition index supplied when marking struct") + if !self.source_mapper.bytecode.module_handles().is_empty() { + any_writeln!(buffer)?; } - Ok(self - .source_mapper - .bytecode - .struct_def_at(struct_definition_index)) - } - fn get_enum_def(&self, enum_definition_index: EnumDefinitionIndex) -> Result<&EnumDefinition> { - if enum_definition_index.0 as usize >= self.source_mapper.bytecode.enum_defs().len() { - bail!("Invalid enum definition index supplied when marking enum") - } - Ok(self - .source_mapper - .bytecode - .enum_def_at(enum_definition_index)) + Ok(()) } - //*************************************************************************** - // Code Coverage Helpers - //*************************************************************************** + fn print_user_defined_types(&self, buffer: &mut impl Write) -> Result<()> { + for i in 0..self.source_mapper.bytecode.struct_defs().len() { + self.disassemble_struct_def(buffer, StructDefinitionIndex(i as TableIndex))?; + any_writeln!(buffer)?; + } - fn get_function_coverage(&self, function_name: &IdentStr) -> Option<&FunctionCoverage> { - let module = &self.source_mapper.source_map.module_name; + for i in 0..self.source_mapper.bytecode.enum_defs().len() { + self.disassemble_enum_def(buffer, EnumDefinitionIndex(i as TableIndex))?; + any_writeln!(buffer)?; + } - self.coverage_map.as_ref().and_then(|coverage_map| { - coverage_map - .module_maps - .get(module) - .and_then(|module_map| module_map.get_function_coverage(function_name)) - }) + Ok(()) } - fn is_function_called(&self, function_name: &IdentStr) -> bool { - self.get_function_coverage(function_name).is_some() + fn print_function_definitions(&self, buffer: &mut impl Write) -> Result<()> { + for i in 0..self.source_mapper.bytecode.function_defs().len() { + self.disassemble_function_definition(buffer, FunctionDefinitionIndex(i as TableIndex))?; + any_writeln!(buffer)?; + } + + Ok(()) } - fn format_function_coverage(&self, name: &IdentStr, function_body: String) -> String { - if self.coverage_map.is_none() { - return function_body; - } - if self.is_function_called(name) { - function_body.green() - } else { - function_body.red() - } - .to_string() + fn print_constants(&self, buffer: &mut impl Write) -> Result<()> { + delimited_list( + self.source_mapper + .bytecode + .constant_pool() + .iter() + .enumerate(), + "Constants [\n", + "", + "]\n", + buffer, + |buffer, (idx, constant)| self.disassemble_constant(buffer, idx, constant, false), + ) } - fn format_with_instruction_coverage( - &self, - pc: usize, - function_coverage_map: Option<&FunctionCoverage>, - instruction: String, - ) -> String { - if self.coverage_map.is_none() { - return format!("\t{}: {}", pc, instruction); - } - let coverage = function_coverage_map.and_then(|map| map.get(&(pc as u64))); - match coverage { - Some(coverage) => format!("[{}]\t{}: {}", coverage, pc, instruction).green(), - None => format!("\t{}: {}", pc, instruction).red(), - } - .to_string() + fn print_footer(&self, buffer: &mut impl Write) -> Result<()> { + any_writeln!(buffer, "}}") } //*************************************************************************** - // Formatting Helpers + // Disassemblers (that output directly to the buffer) //*************************************************************************** - fn name_for_field(&self, field_idx: FieldHandleIndex) -> Result { - let field_handle = self.source_mapper.bytecode.field_handle_at(field_idx); - let struct_def = self - .source_mapper - .bytecode - .struct_def_at(field_handle.owner); - let field_def = match &struct_def.field_information { - StructFieldInformation::Native => { - return Err(format_err!("Attempt to access field on a native struct")); - } - StructFieldInformation::Declared(fields) => fields - .get(field_handle.field as usize) - .ok_or_else(|| format_err!("Bad field index"))?, - }; - let field_name = self - .source_mapper - .bytecode - .identifier_at(field_def.name) - .to_string(); + // The struct defs will filter out the structs that we print to only be the ones + // that are defined in the module in question. + fn disassemble_struct_def( + &self, + buffer: &mut impl Write, + struct_def_idx: StructDefinitionIndex, + ) -> Result<()> { + let struct_definition = self.source_mapper.bytecode.struct_def_at(struct_def_idx); let struct_handle = self .source_mapper .bytecode - .datatype_handle_at(struct_def.struct_handle); - let struct_name = self + .datatype_handle_at(struct_definition.struct_handle); + let struct_source_map = self + .source_mapper + .source_map + .get_struct_source_map(struct_def_idx)?; + + let field_info: Option> = + match &struct_definition.field_information { + StructFieldInformation::Native => None, + StructFieldInformation::Declared(fields) => Some( + fields + .iter() + .map(|field_definition| { + let type_sig = &field_definition.signature; + let field_name = self + .source_mapper + .bytecode + .identifier_at(field_definition.name); + (field_name, type_sig) + }) + .collect(), + ), + }; + + let native = if field_info.is_none() { "native " } else { "" }; + let name = self .source_mapper .bytecode .identifier_at(struct_handle.name) .to_string(); - Ok(format!("{}.{}", struct_name, field_name)) - } - fn type_for_field(&self, field_idx: FieldHandleIndex) -> Result { - let field_handle = self.source_mapper.bytecode.field_handle_at(field_idx); - let struct_def = self - .source_mapper - .bytecode - .struct_def_at(field_handle.owner); - let field_def = match &struct_def.field_information { - StructFieldInformation::Native => { - return Err(format_err!("Attempt to access field on a native struct")); + any_write!(buffer, "{native}struct {name}")?; + + Self::disassemble_datatype_type_formals( + buffer, + &struct_source_map.type_parameters, + &struct_handle.type_parameters, + )?; + + Self::disassemble_abilites(buffer, struct_handle.abilities)?; + + any_write!(buffer, " {{")?; + + match field_info { + None => (), + Some(field_info) => { + delimited_list( + &field_info, + "\n", + ",\n", + "", + buffer, + |buffer, (name, ty)| { + any_write!(buffer, "\t{name}: ")?; + self.disassemble_sig_tok( + buffer, + &ty.0, + None, + &struct_source_map.type_parameters, + ) + }, + )?; + any_writeln!(buffer)?; } - StructFieldInformation::Declared(fields) => fields - .get(field_handle.field as usize) - .ok_or_else(|| format_err!("Bad field index"))?, - }; - let struct_source_info = self - .source_mapper - .source_map - .get_struct_source_map(field_handle.owner)?; - let field_type_sig = field_def.signature.0.clone(); - let ty = self.disassemble_sig_tok(field_type_sig, &struct_source_info.type_parameters)?; - Ok(ty) + } + + any_writeln!(buffer, "}}")?; + + Ok(()) } - fn struct_type_info( + fn disassemble_enum_def( &self, - struct_idx: StructDefinitionIndex, - signature: &Signature, - type_param_context: &[SourceName], - ) -> Result<(String, String)> { - let struct_definition = self.get_struct_def(struct_idx)?; - let type_arguments = signature - .0 - .iter() - .map(|sig_tok| self.disassemble_sig_tok(sig_tok.clone(), type_param_context)) - .collect::>>()?; - - let struct_handle = self + buffer: &mut impl Write, + enum_def_idx: EnumDefinitionIndex, + ) -> Result<()> { + let enum_definition = self.source_mapper.bytecode.enum_def_at(enum_def_idx); + let enum_handle = self .source_mapper .bytecode - .datatype_handle_at(struct_definition.struct_handle); + .datatype_handle_at(enum_definition.enum_handle); + let enum_source_map = self + .source_mapper + .source_map + .get_enum_source_map(enum_def_idx)?; + let name = self .source_mapper .bytecode - .identifier_at(struct_handle.name) + .identifier_at(enum_handle.name) .to_string(); - Ok((name, Self::format_type_params(&type_arguments))) - } - fn name_for_parameter_or_local( - &self, - local_idx: usize, - function_source_map: &FunctionSourceMap, - ) -> Result { - let name = function_source_map - .get_parameter_or_local_name(local_idx as u64) - .ok_or_else(|| { - format_err!( - "Unable to get local name at index {} while disassembling location-based instruction", local_idx - ) - })? - .0; - Ok(name) + any_write!(buffer, "enum {name}")?; + + Self::disassemble_datatype_type_formals( + buffer, + &enum_source_map.type_parameters, + &enum_handle.type_parameters, + )?; + + Self::disassemble_abilites(buffer, enum_handle.abilities)?; + + delimited_list( + &enum_definition.variants, + " {", + ",", + "\n}\n", + buffer, + |buffer, variant| { + let variant_name = self + .source_mapper + .bytecode + .identifier_at(variant.variant_name); + + any_write!(buffer, "\n\t{variant_name} {{ ")?; + + delimited_list( + &variant.fields, + "", + ", ", + "", + buffer, + |buffer, field_definition| { + let type_sig = &field_definition.signature; + let field_name = self + .source_mapper + .bytecode + .identifier_at(field_definition.name); + any_write!(buffer, "{field_name}: ")?; + self.disassemble_sig_tok( + buffer, + &type_sig.0, + None, + &enum_source_map.type_parameters, + ) + }, + )?; + + any_write!(buffer, " }}") + }, + )?; + + Ok(()) } - fn type_for_parameter_or_local( + fn disassemble_function_definition( &self, - idx: usize, - parameters: &Signature, - locals: &Signature, - function_source_map: &FunctionSourceMap, - ) -> Result { - let sig_tok = if idx < parameters.len() { - ¶meters.0[idx] - } else if idx < parameters.len() + locals.len() { - &locals.0[idx - parameters.len()] - } else { - bail!("Unable to get type for parameter or local at index {}", idx) + buffer: &mut impl Write, + function_definition_index: FunctionDefinitionIndex, + ) -> Result<()> { + let function_definition = self + .source_mapper + .bytecode + .function_def_at(function_definition_index); + let function_handle = self + .source_mapper + .bytecode + .function_handle_at(function_definition.function); + let function_source_map = self + .source_mapper + .source_map + .get_function_source_map(function_definition_index)?; + let parameters = function_handle.parameters; + let name = self + .source_mapper + .bytecode + .identifier_at(function_handle.name) + .to_owned(); + let function = self + .source_mapper + .bytecode + .function_def_at(function_definition_index); + debug_assert_eq!( + function_source_map.parameters.len(), + self.source_mapper.bytecode.signature_at(parameters).len(), + "Arity mismatch between function source map and bytecode for function {name}", + ); + + let visibility_modifier = match function.visibility { + Visibility::Private => { + if self.options.only_externally_visible { + return Ok(()); + } else { + "" + } + } + Visibility::Friend => "public(friend) ", + Visibility::Public => "public ", }; - self.disassemble_sig_tok(sig_tok.clone(), &function_source_map.type_parameters) - } - fn type_for_local( - &self, - local_idx: usize, - locals: &Signature, - function_source_map: &FunctionSourceMap, - ) -> Result { - let sig_tok = locals - .0 - .get(local_idx) - .ok_or_else(|| format_err!("Unable to get type for local at index {}", local_idx))?; - self.disassemble_sig_tok(sig_tok.clone(), &function_source_map.type_parameters) - } + let entry_modifier = if function.is_entry { "entry " } else { "" }; + let native_modifier = if function.is_native() { "native " } else { "" }; - fn format_ability(a: Ability) -> String { - match a { - Ability::Copy => "copy", - Ability::Drop => "drop", - Ability::Store => "store", - Ability::Key => "key", - } - .to_string() - } + any_write!( + buffer, + "{entry_modifier}{native_modifier}{visibility_modifier}{name}", + )?; - fn format_type_params(ty_params: &[String]) -> String { - if ty_params.is_empty() { - "".to_string() - } else { - format!("<{}>", ty_params.join(", ")) - } - } + Self::disassemble_fun_type_formals( + buffer, + &function_source_map.type_parameters, + &function_handle.type_parameters, + )?; - fn format_ret_type(ty_rets: &[String]) -> String { - if ty_rets.is_empty() { - "".to_string() - } else { - format!(": {}", ty_rets.join(" * ")) - } - } + any_write!(buffer, "(")?; - fn format_function_body( - locals: Vec, - bytecode: Vec, - jump_tables: Vec, - ) -> String { - if locals.is_empty() && bytecode.is_empty() { - "".to_string() - } else { - let body_iter: Vec = locals - .into_iter() - .enumerate() - .map(|(local_idx, local)| format!("L{}:\t{}", local_idx, local)) - .chain(bytecode) - .chain(jump_tables) - .collect(); - format!(" {{\n{}\n}}", body_iter.join("\n")) - } + delimited_list( + self.source_mapper + .bytecode + .signature_at(parameters) + .0 + .iter() + .zip(function_source_map.parameters.iter()), + "", + ", ", + "", + buffer, + |buffer, (tok, (name, _))| { + any_write!(buffer, "{name}: ")?; + self.disassemble_sig_tok(buffer, tok, None, &function_source_map.type_parameters) + }, + )?; + + any_write!(buffer, ")")?; + + delimited_list( + &self + .source_mapper + .bytecode + .signature_at(function_handle.return_) + .0, + ": ", + " * ", + "", + buffer, + |buffer, tok| { + self.disassemble_sig_tok(buffer, tok, None, &function_source_map.type_parameters) + }, + )?; + + let Some(code) = &function.code else { + any_writeln!(buffer, ";")?; + return Ok(()); + }; + + let params_len = self.source_mapper.bytecode.signature_at(parameters).0.len(); + + any_writeln!(buffer, " {{")?; + self.disassemble_locals(buffer, function_source_map, code.locals, params_len)?; + self.disassemble_bytecode(buffer, function_source_map, &name, parameters, code)?; + self.disassemble_jump_tables(buffer, code)?; + any_writeln!(buffer, "}}") } - fn preview_const(slice: &[u8]) -> String { - // Account for the .. in the preview - if slice.len() <= PREVIEW_LEN + 2 { - hex::encode(slice) - } else { - format!("{}..", hex::encode(&slice[..PREVIEW_LEN])) + fn disassemble_locals( + &self, + buffer: &mut impl Write, + function_source_map: &FunctionSourceMap, + locals_idx: SignatureIndex, + parameter_len: usize, + ) -> Result<()> { + if !self.options.print_locals { + return Ok(()); } - } - fn preview_string(s: &str) -> String { - if s.len() <= PREVIEW_LEN + 2 { - s.to_string() - } else { - let mut preview: String = s.chars().take(PREVIEW_LEN).collect(); - preview.push_str(".."); - preview + if function_source_map.locals.len() <= parameter_len { + return Ok(()); } + + let signature = self.source_mapper.bytecode.signature_at(locals_idx); + for (local_idx, (name, _)) in function_source_map + .locals + .iter() + .skip(parameter_len) + .enumerate() + { + any_write!(buffer, "L{local_idx}:\t{name}: ")?; + self.disassemble_type_for_local( + buffer, + function_source_map, + parameter_len + local_idx, + signature, + )?; + any_writeln!(buffer)?; + } + + Ok(()) } - //*************************************************************************** - // Disassemblers - //*************************************************************************** + fn disassemble_jump_tables(&self, buffer: &mut impl Write, code: &CodeUnit) -> Result<()> { + if !self.options.print_code || code.jump_tables.is_empty() { + return Ok(()); + } - // These need to be in the context of a function or a struct definition since - // type parameters can refer to function/struct type parameters. - fn disassemble_sig_tok( - &self, - sig_tok: SignatureToken, - type_param_context: &[SourceName], - ) -> Result { - Ok(match sig_tok { - SignatureToken::Bool => "bool".to_string(), - SignatureToken::U8 => "u8".to_string(), - SignatureToken::U16 => "u16".to_string(), - SignatureToken::U32 => "u32".to_string(), - SignatureToken::U64 => "u64".to_string(), - SignatureToken::U128 => "u128".to_string(), - SignatureToken::U256 => "u256".to_string(), - SignatureToken::Address => "address".to_string(), - SignatureToken::Signer => "signer".to_string(), - SignatureToken::Datatype(struct_handle_idx) => self + any_writeln!(buffer, "Jump tables:")?; + + for (i, jt) in code.jump_tables.iter().enumerate() { + let enum_def = self.source_mapper.bytecode.enum_def_at(jt.head_enum); + let enum_handle = self .source_mapper .bytecode - .identifier_at( - self.source_mapper - .bytecode - .datatype_handle_at(struct_handle_idx) - .name, - ) - .to_string(), - SignatureToken::DatatypeInstantiation(struct_inst) => { - let (struct_handle_idx, instantiation) = *struct_inst; - let instantiation = instantiation - .into_iter() - .map(|tok| self.disassemble_sig_tok(tok, type_param_context)) - .collect::>>()?; - let formatted_instantiation = Self::format_type_params(&instantiation); - let name = self - .source_mapper - .bytecode - .identifier_at( - self.source_mapper - .bytecode - .datatype_handle_at(struct_handle_idx) - .name, - ) - .to_string(); - format!("{}{}", name, formatted_instantiation) + .datatype_handle_at(enum_def.enum_handle); + let enum_source_map = self + .source_mapper + .source_map + .get_enum_source_map(jt.head_enum)?; + let enum_name = self.source_mapper.bytecode.identifier_at(enum_handle.name); + let JumpTableInner::Full(jt) = &jt.jump_table; + any_writeln!(buffer, "[{i}]:\tvariant_switch {enum_name} {{")?; + for (tag, jump_loc) in jt.iter().enumerate() { + let enum_name = enum_source_map + .get_variant_location(tag as u16) + .map(|((name, _), _)| name) + .unwrap_or(format!("Variant{}", tag)); + any_writeln!(buffer, "\t\t{enum_name} => jump {jump_loc}")?; } - SignatureToken::Vector(sig_tok) => format!( - "vector<{}>", - self.disassemble_sig_tok(*sig_tok, type_param_context)? - ), - SignatureToken::Reference(sig_tok) => format!( - "&{}", - self.disassemble_sig_tok(*sig_tok, type_param_context)? - ), - SignatureToken::MutableReference(sig_tok) => format!( - "&mut {}", - self.disassemble_sig_tok(*sig_tok, type_param_context)? - ), - SignatureToken::TypeParameter(ty_param_index) => type_param_context - .get(ty_param_index as usize) - .ok_or_else(|| { - format_err!( - "Type parameter index {} out of bounds while disassembling type signature", - ty_param_index - ) - })? - .0 - .to_string(), - }) + any_writeln!(buffer, "\t}}")?; + } + Ok(()) + } + + fn disassemble_bytecode( + &self, + buffer: &mut impl Write, + function_source_map: &FunctionSourceMap, + function_name: &IdentStr, + parameters: SignatureIndex, + code: &CodeUnit, + ) -> Result<()> { + if !self.options.print_code { + return Ok(()); + } + + let parameters = self.source_mapper.bytecode.signature_at(parameters); + let locals_sigs = self.source_mapper.bytecode.signature_at(code.locals); + let function_code_coverage_map = self.get_function_coverage(function_name).cloned(); + let cfg_opt = if self.options.print_basic_blocks { + let cfg: BTreeMap<_, _> = VMControlFlowGraph::new(&code.code, &code.jump_tables) + .blocks() + .into_iter() + .enumerate() + .map(|(block_number, pc_start)| (pc_start, block_number)) + .collect(); + Some(cfg) + } else { + None + }; + + let coverage_enabled = self.coverage_map.is_some(); + + for (pc, instruction) in code.code.iter().enumerate() { + if let Some(block_number) = cfg_opt.as_ref().and_then(|cfg| cfg.get(&(pc as u16))) { + any_writeln!(buffer, "B{block_number}:")?; + } + + match &function_code_coverage_map { + None => { + any_write!(buffer, "\t{pc}: ")?; + } + Some(coverage_map) => { + let coverage = coverage_map.get(&(pc as u64)); + match coverage { + Some(coverage) => { + any_write!(buffer, "{}[{coverage}]\t{pc}: ", IC::color_green)?; + } + None => { + any_write!(buffer, "{}\t{pc}: ", IC::color_red)?; + } + } + } + } + + self.disassemble_instruction( + buffer, + function_source_map, + parameters, + locals_sigs, + instruction, + )?; + + any_writeln!( + buffer, + "{}", + if coverage_enabled { + IC::color_reset + } else { + "" + } + )?; + } + + Ok(()) + } + + fn disassemble_import( + &self, + buffer: &mut impl Write, + module_handle: &ModuleHandle, + ) -> Result<()> { + let module_id = self + .source_mapper + .bytecode + .module_id_for_handle(module_handle); + if self.is_self_id(&module_id) { + // No need to import self handle + Ok(()) + } else if let Some(alias) = self.module_aliases.get(&module_id) { + any_writeln!( + buffer, + "use {}::{} as {};", + module_id.address(), + module_id.name(), + alias + ) + } else { + any_writeln!(buffer, "use {}::{};", module_id.address(), module_id.name()) + } } fn disassemble_instruction( &self, + buffer: &mut impl Write, + function_source_map: &FunctionSourceMap, parameters: &Signature, - constants: &[(String, String)], - instruction: &Bytecode, locals_sigs: &Signature, - function_source_map: &FunctionSourceMap, - default_location: &Loc, - ) -> Result { + instruction: &Bytecode, + ) -> Result<()> { + macro_rules! parens { + ($($args:tt)*) => {{ + any_write!(buffer, "(")?; + $($args)* + any_write!(buffer, ")") + }}; + } match instruction { Bytecode::LdConst(idx) => { - let constant = constants - .get(idx.0 as usize) - .map(|(ty_str, val_str)| { - format!("{}: {}", ty_str, Self::preview_string(val_str)) - }) - .unwrap_or_else(|| { - let constant = self.source_mapper.bytecode.constant_at(*idx); - format!( - "{:?}: {}", - &constant.type_, - Self::preview_const(&constant.data) - ) - }); - Ok(format!("LdConst[{}]({})", idx, constant,)) + any_write!(buffer, "LdConst[{idx}]")?; + parens! { + let constant = self.source_mapper.bytecode.constant_at(*idx); + self.disassemble_constant(buffer, idx.0 as usize, constant, true)?; + } } Bytecode::CopyLoc(local_idx) => { - let name = - self.name_for_parameter_or_local(usize::from(*local_idx), function_source_map)?; - let ty = self.type_for_parameter_or_local( - usize::from(*local_idx), - parameters, - locals_sigs, - function_source_map, - )?; - Ok(format!("CopyLoc[{}]({}: {})", local_idx, name, ty)) + any_write!(buffer, "CopyLoc[{local_idx}]")?; + parens! { + let name = self.format_name_for_parameter_or_local( + function_source_map, + usize::from(*local_idx), + ); + any_write!(buffer, "{name}: ")?; + self.disassemble_type_for_parameter_or_local( + buffer, + function_source_map, + usize::from(*local_idx), + parameters, + locals_sigs, + )?; + } } Bytecode::MoveLoc(local_idx) => { - let name = - self.name_for_parameter_or_local(usize::from(*local_idx), function_source_map)?; - let ty = self.type_for_parameter_or_local( - usize::from(*local_idx), - parameters, - locals_sigs, - function_source_map, - )?; - Ok(format!("MoveLoc[{}]({}: {})", local_idx, name, ty)) + any_write!(buffer, "MoveLoc[{local_idx}]")?; + parens! { + let name = self.format_name_for_parameter_or_local( + function_source_map, + usize::from(*local_idx), + ); + any_write!(buffer, "{name}: ")?; + self.disassemble_type_for_parameter_or_local( + buffer, + function_source_map, + usize::from(*local_idx), + parameters, + locals_sigs, + )?; + } } Bytecode::StLoc(local_idx) => { - let name = - self.name_for_parameter_or_local(usize::from(*local_idx), function_source_map)?; - let ty = self.type_for_parameter_or_local( - usize::from(*local_idx), - parameters, - locals_sigs, - function_source_map, - )?; - Ok(format!("StLoc[{}]({}: {})", local_idx, name, ty)) + any_write!(buffer, "StLoc[{local_idx}]")?; + parens! { + let name = self.format_name_for_parameter_or_local( + function_source_map, + usize::from(*local_idx), + ); + any_write!(buffer, "{name}: ")?; + self.disassemble_type_for_parameter_or_local( + buffer, + function_source_map, + usize::from(*local_idx), + parameters, + locals_sigs, + )?; + } } Bytecode::MutBorrowLoc(local_idx) => { - let name = - self.name_for_parameter_or_local(usize::from(*local_idx), function_source_map)?; - let ty = self.type_for_parameter_or_local( - usize::from(*local_idx), - parameters, - locals_sigs, - function_source_map, - )?; - Ok(format!("MutBorrowLoc[{}]({}: {})", local_idx, name, ty)) + any_write!(buffer, "MutBorrowLoc[{local_idx}]")?; + parens! { + let name = self.format_name_for_parameter_or_local( + function_source_map, + usize::from(*local_idx), + ); + any_write!(buffer, "{name}: ")?; + self.disassemble_type_for_parameter_or_local( + buffer, + function_source_map, + usize::from(*local_idx), + parameters, + locals_sigs, + )?; + } } Bytecode::ImmBorrowLoc(local_idx) => { - let name = - self.name_for_parameter_or_local(usize::from(*local_idx), function_source_map)?; - let ty = self.type_for_parameter_or_local( - usize::from(*local_idx), - parameters, - locals_sigs, - function_source_map, - )?; - Ok(format!("ImmBorrowLoc[{}]({}: {})", local_idx, name, ty)) + any_write!(buffer, "ImmBorrowLoc[{local_idx}]")?; + parens! { + let name = self.format_name_for_parameter_or_local( + function_source_map, + usize::from(*local_idx), + ); + any_write!(buffer, "{name}: ")?; + self.disassemble_type_for_parameter_or_local( + buffer, + function_source_map, + usize::from(*local_idx), + parameters, + locals_sigs, + )?; + } } Bytecode::MutBorrowField(field_idx) => { - let name = self.name_for_field(*field_idx)?; - let ty = self.type_for_field(*field_idx)?; - Ok(format!("MutBorrowField[{}]({}: {})", field_idx, name, ty)) + any_write!(buffer, "MutBorrowField[{field_idx}]")?; + parens! { + self.disassemble_struct_field_access(buffer, *field_idx)?; + any_write!(buffer, ": ")?; + self.disassemble_type_for_field(buffer, function_source_map, None, *field_idx)?; + } } Bytecode::MutBorrowFieldGeneric(field_idx) => { - let field_inst = self - .source_mapper - .bytecode - .field_instantiation_at(*field_idx); - let name = self.name_for_field(field_inst.handle)?; - let ty = self.type_for_field(field_inst.handle)?; - Ok(format!( - "MutBorrowFieldGeneric[{}]({}: {})", - field_idx, name, ty - )) + any_write!(buffer, "MutBorrowFieldGeneric[{field_idx}]")?; + parens! { + let field_inst = self + .source_mapper + .bytecode + .field_instantiation_at(*field_idx); + self.disassemble_struct_field_access(buffer, field_inst.handle)?; + any_write!(buffer, ": ")?; + let instantiation = self + .source_mapper + .bytecode + .signature_at(field_inst.type_parameters); + self.disassemble_type_for_field(buffer, function_source_map, Some(&instantiation.0), field_inst.handle)?; + } } Bytecode::ImmBorrowField(field_idx) => { - let name = self.name_for_field(*field_idx)?; - let ty = self.type_for_field(*field_idx)?; - Ok(format!("ImmBorrowField[{}]({}: {})", field_idx, name, ty)) + any_write!(buffer, "ImmBorrowField[{field_idx}]")?; + parens! { + self.disassemble_struct_field_access(buffer, *field_idx)?; + any_write!(buffer, ": ")?; + self.disassemble_type_for_field(buffer, function_source_map, None, *field_idx)?; + } } Bytecode::ImmBorrowFieldGeneric(field_idx) => { - let field_inst = self - .source_mapper - .bytecode - .field_instantiation_at(*field_idx); - let name = self.name_for_field(field_inst.handle)?; - let ty = self.type_for_field(field_inst.handle)?; - Ok(format!( - "ImmBorrowFieldGeneric[{}]({}: {})", - field_idx, name, ty - )) + any_write!(buffer, "ImmBorrowFieldGeneric[{field_idx}]")?; + parens! { + let field_inst = self + .source_mapper + .bytecode + .field_instantiation_at(*field_idx); + self.disassemble_struct_field_access(buffer, field_inst.handle)?; + any_write!(buffer, ": ")?; + let instantiation = self + .source_mapper + .bytecode + .signature_at(field_inst.type_parameters); + self.disassemble_type_for_field(buffer, function_source_map, Some(&instantiation.0), field_inst.handle)?; + } } Bytecode::Pack(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!("Pack[{}]({}{})", struct_idx, name, ty_params)) + any_write!(buffer, "Pack[{struct_idx}]")?; + parens! { + self.disassemble_struct_call( + buffer, + function_source_map, + *struct_idx, + &Signature(vec![]), + )?; + } } Bytecode::PackGeneric(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "PackGeneric[{}]({}{})", - struct_idx, name, ty_params - )) + any_write!(buffer, "PackGeneric[{struct_idx}]")?; + parens! { + let struct_inst = self + .source_mapper + .bytecode + .struct_instantiation_at(*struct_idx); + let type_params = self + .source_mapper + .bytecode + .signature_at(struct_inst.type_parameters); + self.disassemble_struct_call( + buffer, + function_source_map, + struct_inst.def, + type_params, + )?; + } } Bytecode::Unpack(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!("Unpack[{}]({}{})", struct_idx, name, ty_params)) + any_write!(buffer, "Unpack[{struct_idx}]")?; + parens! { + self.disassemble_struct_call( + buffer, + function_source_map, + *struct_idx, + &Signature(vec![]), + )?; + } } Bytecode::UnpackGeneric(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "UnpackGeneric[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::ExistsDeprecated(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!("Exists[{}]({}{})", struct_idx, name, ty_params)) - } - Bytecode::ExistsGenericDeprecated(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "ExistsGeneric[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::MutBorrowGlobalDeprecated(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!( - "MutBorrowGlobal[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::MutBorrowGlobalGenericDeprecated(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "MutBorrowGlobalGeneric[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::ImmBorrowGlobalDeprecated(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!( - "ImmBorrowGlobal[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::ImmBorrowGlobalGenericDeprecated(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "ImmBorrowGlobalGeneric[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::MoveFromDeprecated(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!("MoveFrom[{}]({}{})", struct_idx, name, ty_params)) - } - Bytecode::MoveFromGenericDeprecated(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "MoveFromGeneric[{}]({}{})", - struct_idx, name, ty_params - )) - } - Bytecode::MoveToDeprecated(struct_idx) => { - let (name, ty_params) = self.struct_type_info( - *struct_idx, - &Signature(vec![]), - &function_source_map.type_parameters, - )?; - Ok(format!("MoveTo[{}]({}{})", struct_idx, name, ty_params)) - } - Bytecode::MoveToGenericDeprecated(struct_idx) => { - let struct_inst = self - .source_mapper - .bytecode - .struct_instantiation_at(*struct_idx); - let type_params = self - .source_mapper - .bytecode - .signature_at(struct_inst.type_parameters); - let (name, ty_params) = self.struct_type_info( - struct_inst.def, - type_params, - &function_source_map.type_parameters, - )?; - Ok(format!( - "MoveToGeneric[{}]({}{})", - struct_idx, name, ty_params - )) + any_write!(buffer, "UnpackGeneric[{struct_idx}]")?; + parens! { + let struct_inst = self + .source_mapper + .bytecode + .struct_instantiation_at(*struct_idx); + let type_params = self + .source_mapper + .bytecode + .signature_at(struct_inst.type_parameters); + self.disassemble_struct_call( + buffer, + function_source_map, + struct_inst.def, + type_params, + )?; + } } Bytecode::Call(method_idx) => { let function_handle = self.source_mapper.bytecode.function_handle_at(*method_idx); @@ -851,30 +952,32 @@ impl<'a> Disassembler<'a> { .source_mapper .bytecode .module_handle_at(function_handle.module); - let fcall_name = self.get_function_string(module_handle, function_handle); - let type_arguments = self - .source_mapper - .bytecode - .signature_at(function_handle.parameters) - .0 - .iter() - .map(|sig_tok| self.disassemble_sig_tok(sig_tok.clone(), &[])) - .collect::>>()? - .join(", "); - let type_rets = self - .source_mapper - .bytecode - .signature_at(function_handle.return_) - .0 - .iter() - .map(|sig_tok| self.disassemble_sig_tok(sig_tok.clone(), &[])) - .collect::>>()?; - Ok(format!( - "Call {}({}){}", - fcall_name, - type_arguments, - Self::format_ret_type(&type_rets) - )) + any_write!(buffer, "Call ")?; + self.disassemble_function_string(buffer, module_handle, function_handle)?; + parens! { + delimited_list( + self.source_mapper.bytecode.signature_at(function_handle.parameters).0.iter(), + "", + ", ", + "", + buffer, + |buffer, tok| { + self.disassemble_sig_tok(buffer, tok, None, &[]) + }, + )?; + }?; + delimited_list( + &self + .source_mapper + .bytecode + .signature_at(function_handle.return_) + .0, + ": ", + " * ", + "", + buffer, + |buffer, tok| self.disassemble_sig_tok(buffer, tok, None, &[]), + ) } Bytecode::CallGeneric(method_idx) => { let func_inst = self @@ -889,585 +992,462 @@ impl<'a> Disassembler<'a> { .source_mapper .bytecode .module_handle_at(function_handle.module); - let fcall_name = self.get_function_string(module_handle, function_handle); - let ty_params = self + any_write!(buffer, "Call ")?; + self.disassemble_function_string(buffer, module_handle, function_handle)?; + let func_instantiation = &self .source_mapper .bytecode .signature_at(func_inst.type_parameters) - .0 - .iter() - .map(|sig_tok| { - Ok(( - self.disassemble_sig_tok( - sig_tok.clone(), - &function_source_map.type_parameters, - )?, - *default_location, - )) - }) - .collect::>>()?; - let type_arguments = self - .source_mapper - .bytecode - .signature_at(function_handle.parameters) - .0 - .iter() - .map(|sig_tok| self.disassemble_sig_tok(sig_tok.clone(), &ty_params)) - .collect::>>()? - .join(", "); - let type_rets = self - .source_mapper - .bytecode - .signature_at(function_handle.return_) - .0 - .iter() - .map(|sig_tok| self.disassemble_sig_tok(sig_tok.clone(), &ty_params)) - .collect::>>()?; - Ok(format!( - "Call {}{}({}){}", - fcall_name, - Self::format_type_params( - &ty_params.into_iter().map(|(s, _)| s).collect::>() - ), - type_arguments, - Self::format_ret_type(&type_rets) - )) + .0; + delimited_list(func_instantiation, "<", ", ", ">", buffer, |buffer, ty| { + self.disassemble_sig_tok(buffer, ty, None, &function_source_map.type_parameters) + })?; + parens! { + delimited_list( + self.source_mapper.bytecode.signature_at(function_handle.parameters).0.iter(), + "", + ", ", + "", + buffer, + |buffer, tok| { + self.disassemble_sig_tok(buffer, tok, Some(func_instantiation), &function_source_map.type_parameters) + }, + )?; + }?; + delimited_list( + &self + .source_mapper + .bytecode + .signature_at(function_handle.return_) + .0, + ": ", + " * ", + "", + buffer, + |buffer, tok| { + self.disassemble_sig_tok( + buffer, + tok, + Some(func_instantiation), + &function_source_map.type_parameters, + ) + }, + ) + } + Bytecode::ExistsDeprecated(_) + | Bytecode::ExistsGenericDeprecated(_) + | Bytecode::MutBorrowGlobalDeprecated(_) + | Bytecode::MutBorrowGlobalGenericDeprecated(_) + | Bytecode::ImmBorrowGlobalDeprecated(_) + | Bytecode::ImmBorrowGlobalGenericDeprecated(_) + | Bytecode::MoveFromDeprecated(_) + | Bytecode::MoveFromGenericDeprecated(_) + | Bytecode::MoveToDeprecated(_) + | Bytecode::MoveToGenericDeprecated(_) => { + any_write!(buffer, "DEPRECATED BYTECODE: {instruction:?}") } // All other instructions are OK to be printed using the standard debug print. - x => Ok(format!("{:#?}", x)), - } - } - - fn disassemble_jump_tables(&self, code: &CodeUnit) -> Result> { - if !self.options.print_code || code.jump_tables.is_empty() { - return Ok(vec!["".to_string()]); - } - - let mut jump_tables = vec!["Jump tables:".to_string()]; - - for (i, jt) in code.jump_tables.iter().enumerate() { - let enum_def = self.get_enum_def(jt.head_enum)?; - let enum_handle = self - .source_mapper - .bytecode - .datatype_handle_at(enum_def.enum_handle); - let enum_source_map = self - .source_mapper - .source_map - .get_enum_source_map(jt.head_enum)?; - let enum_name = self.source_mapper.bytecode.identifier_at(enum_handle.name); - let JumpTableInner::Full(jt) = &jt.jump_table; - let jt: Vec<_> = jt - .iter() - .enumerate() - .map(|(tag, jump_loc)| { - let enum_name = enum_source_map - .get_variant_location(tag as u16) - .map(|((name, _), _)| name) - .unwrap_or(format!("Variant{}", tag)); - format!("{} => jump {}", enum_name, jump_loc) - }) - .collect(); - jump_tables.push(format!( - "[{i}]:\tvariant_switch {} {{\n\t\t{}\n\t}}", - enum_name, - jt.join("\n\t\t") - )) + x => any_write!(buffer, "{x:#?}"), } - Ok(jump_tables) } - fn disassemble_bytecode( + // These need to be in the context of a function or a struct definition since + // type parameters can refer to function/struct type parameters. + fn disassemble_sig_tok( &self, - function_source_map: &FunctionSourceMap, - function_name: &IdentStr, - parameters: SignatureIndex, - constants: &[(String, String)], - code: &CodeUnit, - ) -> Result> { - if !self.options.print_code { - return Ok(vec!["".to_string()]); - } - - let parameters = self.source_mapper.bytecode.signature_at(parameters); - let locals_sigs = self.source_mapper.bytecode.signature_at(code.locals); - - let function_code_coverage_map = self.get_function_coverage(function_name); - - let decl_location = &function_source_map.definition_location; - let instrs: Vec = code - .code - .iter() - .map(|instruction| { - self.disassemble_instruction( - parameters, - constants, - instruction, - locals_sigs, - function_source_map, - decl_location, - ) - }) - .collect::>>()?; - - let mut instrs: Vec = instrs - .into_iter() - .enumerate() - .map(|(instr_index, dis_instr)| { - self.format_with_instruction_coverage( - instr_index, - function_code_coverage_map, - dis_instr, + buffer: &mut impl Write, + sig_tok: &SignatureToken, + type_instantiation: Option<&[SignatureToken]>, + type_param_name_context: &[SourceName], + ) -> Result<()> { + match sig_tok { + SignatureToken::Bool => any_write!(buffer, "bool"), + SignatureToken::U8 => any_write!(buffer, "u8"), + SignatureToken::U16 => any_write!(buffer, "u16"), + SignatureToken::U32 => any_write!(buffer, "u32"), + SignatureToken::U64 => any_write!(buffer, "u64"), + SignatureToken::U128 => any_write!(buffer, "u128"), + SignatureToken::U256 => any_write!(buffer, "u256"), + SignatureToken::Address => any_write!(buffer, "address"), + SignatureToken::Signer => any_write!(buffer, "signer"), + SignatureToken::Datatype(struct_handle_idx) => any_write!( + buffer, + "{}", + self.source_mapper.bytecode.identifier_at( + self.source_mapper + .bytecode + .datatype_handle_at(*struct_handle_idx) + .name, ) - }) - .collect(); - - if self.options.print_basic_blocks { - let cfg = VMControlFlowGraph::new(&code.code, &code.jump_tables); - for (block_number, block_id) in cfg.blocks().iter().enumerate() { - instrs.insert( - *block_id as usize + block_number, - format!("B{}:", block_number), + ), + SignatureToken::DatatypeInstantiation(struct_inst) => { + let (struct_handle_idx, instantiation) = &**struct_inst; + let name = self.source_mapper.bytecode.identifier_at( + self.source_mapper + .bytecode + .datatype_handle_at(*struct_handle_idx) + .name, ); + any_write!(buffer, "{name}")?; + delimited_list(instantiation, "<", ", ", ">", buffer, |buffer, tok| { + self.disassemble_sig_tok( + buffer, + tok, + type_instantiation, + type_param_name_context, + ) + }) + } + SignatureToken::Vector(sig_tok) => { + any_write!(buffer, "vector<")?; + self.disassemble_sig_tok( + buffer, + sig_tok, + type_instantiation, + type_param_name_context, + )?; + any_write!(buffer, ">") + } + SignatureToken::Reference(sig_tok) => { + any_write!(buffer, "&")?; + self.disassemble_sig_tok( + buffer, + sig_tok, + type_instantiation, + type_param_name_context, + ) + } + SignatureToken::MutableReference(sig_tok) => { + any_write!(buffer, "&mut ")?; + self.disassemble_sig_tok( + buffer, + sig_tok, + type_instantiation, + type_param_name_context, + ) + } + SignatureToken::TypeParameter(ty_param_index) if type_instantiation.is_none() => { + if let Some(name) = type_param_name_context.get(*ty_param_index as usize) { + any_write!(buffer, "{}", name.0) + } else { + any_write!( + buffer, + "ERROR[Type parameter index {ty_param_index} out of bounds while disassembling type signature]", + ) + } + } + SignatureToken::TypeParameter(ty_param_index) => { + match type_instantiation.and_then(|i| i.get(*ty_param_index as usize)) { + Some(tok) => { + self.disassemble_sig_tok(buffer, tok, None, type_param_name_context) + } + None => any_write!( + buffer, + "ERROR[Type parameter index {ty_param_index} out of bounds while disassembling type signature]", + ), + } } } - - Ok(instrs) } fn disassemble_datatype_type_formals( + buffer: &mut impl Write, source_map_ty_params: &[SourceName], type_parameters: &[DatatypeTyParameter], - ) -> String { - let ty_params: Vec = source_map_ty_params - .iter() - .zip(type_parameters) - .map(|((name, _), ty_param)| { - let abilities_str = if ty_param.constraints == AbilitySet::EMPTY { - "".to_string() - } else { - let ability_vec: Vec<_> = ty_param - .constraints - .into_iter() - .map(Self::format_ability) - .collect(); - format!(": {}", ability_vec.join(" + ")) - }; - format!( - "{}{}{}", - if ty_param.is_phantom { "phantom " } else { "" }, - name.as_str(), - abilities_str - ) - }) - .collect(); - Self::format_type_params(&ty_params) + ) -> Result<()> { + delimited_list( + source_map_ty_params.iter().zip(type_parameters), + "<", + ", ", + ">", + buffer, + |buf, ((name, _), ty_param)| { + if ty_param.is_phantom { + buf.write_str("phantom ")?; + } + buf.write_str(name.as_str())?; + delimited_list(ty_param.constraints, ": ", " + ", "", buf, |buf, a| { + buf.write_str(&Self::format_ability(a)) + .map_err(anyhow::Error::from) + }) + }, + ) + } + + fn disassemble_abilites(buffer: &mut impl Write, abilities: AbilitySet) -> Result<()> { + if abilities == AbilitySet::EMPTY { + return Ok(()); + } + delimited_list(abilities, " has ", ", ", "", buffer, |buf, a| { + buf.write_str(&Self::format_ability(a)) + .map_err(anyhow::Error::from) + }) } fn disassemble_fun_type_formals( + buffer: &mut impl Write, source_map_ty_params: &[SourceName], ablities: &[AbilitySet], - ) -> String { - let ty_params: Vec = source_map_ty_params - .iter() - .zip(ablities) - .map(|((name, _), abs)| { - let abilities_str = if *abs == AbilitySet::EMPTY { - "".to_string() - } else { - let ability_vec: Vec<_> = abs.into_iter().map(Self::format_ability).collect(); - format!(": {}", ability_vec.join(" + ")) - }; - format!("{}{}", name.as_str(), abilities_str) - }) - .collect(); - Self::format_type_params(&ty_params) + ) -> Result<()> { + delimited_list( + source_map_ty_params.iter().zip(ablities), + "<", + ", ", + ">", + buffer, + |buffer, ((name, _), abs)| { + any_write!(buffer, "{}", name)?; + delimited_list(*abs, ": ", " + ", "", buffer, |buffer, a| { + any_write!(buffer, "{}", Self::format_ability(a)) + }) + }, + ) } - fn disassemble_locals( + fn disassemble_type_for_local( &self, + buffer: &mut impl Write, function_source_map: &FunctionSourceMap, - locals_idx: SignatureIndex, - parameter_len: usize, - ) -> Result> { - if !self.options.print_locals { - return Ok(vec![]); - } - - let signature = self.source_mapper.bytecode.signature_at(locals_idx); - let locals_names_tys = function_source_map - .locals - .iter() - .skip(parameter_len) - .enumerate() - .map(|(local_idx, (name, _))| { - let ty = - self.type_for_local(parameter_len + local_idx, signature, function_source_map)?; - Ok(format!("{}: {}", name, ty)) - }) - .collect::>>()?; - Ok(locals_names_tys) + local_idx: usize, + locals: &Signature, + ) -> Result<()> { + let Some(sig_tok) = locals.0.get(local_idx) else { + any_write!( + buffer, + "ERROR[Unable to get type for local at index {local_idx}]", + )?; + return Ok(()); + }; + self.disassemble_sig_tok(buffer, sig_tok, None, &function_source_map.type_parameters) } - /// Translates a compiled "function definition" into a disassembled bytecode - /// string. - /// - /// Because a "function definition" can refer to either a function defined - /// in a module or to a script's "main" function (which is not - /// represented by a function definition in the binary format), this - /// method takes a function definition and handle as optional arguments. - /// These are `None` when disassembling a script's "main" function. - pub fn disassemble_function_def( + fn disassemble_type_for_parameter_or_local( &self, + buffer: &mut impl Write, function_source_map: &FunctionSourceMap, - function: Option<(&FunctionDefinition, &FunctionHandle)>, - name: &IdentStr, - type_parameters: &[AbilitySet], - parameters: SignatureIndex, - code: Option<&CodeUnit>, - constants: &[(String, String)], - ) -> Result { - debug_assert_eq!( - function_source_map.parameters.len(), - self.source_mapper.bytecode.signature_at(parameters).len(), - "Arity mismatch between function source map and bytecode for function {}", - name - ); - - let entry_modifier = if function.map(|(f, _)| f.is_entry).unwrap_or(false) { - "entry " + idx: usize, + parameters: &Signature, + locals: &Signature, + ) -> Result<()> { + let sig_tok = if idx < parameters.len() { + ¶meters.0[idx] + } else if idx < parameters.len() + locals.len() { + &locals.0[idx - parameters.len()] } else { - "" - }; - let visibility_modifier = match function { - Some(function) => match function.0.visibility { - Visibility::Private => { - if self.options.only_externally_visible { - return Ok("".to_string()); - } else { - "" - } - } - Visibility::Friend => "public(friend) ", - Visibility::Public => "public ", - }, - None => "", - }; - - let native_modifier = match function { - Some(function) if function.0.is_native() => "native ", - _ => "", + any_write!( + buffer, + "ERROR[Unable to get type for parameter or local at index {idx}]", + )?; + return Ok(()); }; + self.disassemble_sig_tok(buffer, sig_tok, None, &function_source_map.type_parameters) + } - let ty_params = Self::disassemble_fun_type_formals( - &function_source_map.type_parameters, - type_parameters, - ); - let params = &self + fn disassemble_type_for_field( + &self, + buffer: &mut impl Write, + function_source_map: &FunctionSourceMap, + instantiation: Option<&[SignatureToken]>, + field_idx: FieldHandleIndex, + ) -> Result<()> { + let field_handle = self.source_mapper.bytecode.field_handle_at(field_idx); + let struct_def = self .source_mapper .bytecode - .signature_at(parameters) - .0 - .iter() - .zip(function_source_map.parameters.iter()) - .map(|(tok, (name, _))| { - Ok(format!( - "{}: {}", - name, - self.disassemble_sig_tok(tok.clone(), &function_source_map.type_parameters)? - )) - }) - .collect::>>()?; - - let ret_type = match function { - Some(function) => self - .source_mapper - .bytecode - .signature_at(function.1.return_) - .0 - .iter() - .cloned() - .map(|sig_token| { - let sig_tok_str = - self.disassemble_sig_tok(sig_token, &function_source_map.type_parameters)?; - Ok(sig_tok_str) - }) - .collect::>>()?, - None => vec![], - }; - - let body = match code { - Some(code) => { - let locals = - self.disassemble_locals(function_source_map, code.locals, params.len())?; - let bytecode = self.disassemble_bytecode( - function_source_map, - name, - parameters, - constants, - code, - )?; - let jump_tables = self.disassemble_jump_tables(code)?; - Self::format_function_body(locals, bytecode, jump_tables) + .struct_def_at(field_handle.owner); + let field_def = match &struct_def.field_information { + StructFieldInformation::Native => { + return any_write!(buffer, "ERROR[Attempt to access field on a native struct]"); + } + StructFieldInformation::Declared(fields) => { + let Some(fields) = fields.get(field_handle.field as usize) else { + return any_write!(buffer, "ERROR[Bad field index {}]", field_handle.field); + }; + fields } - None => "".to_string(), }; - Ok(self.format_function_coverage( - name, - format!( - "{entry_modifier}{native_modifier}{visibility_modifier}{name}{ty_params}({params}){ret_type}{body}", - params = ¶ms.join(", "), - ret_type = Self::format_ret_type(&ret_type), - ), - )) + let field_type_sig = &field_def.signature.0; + self.disassemble_sig_tok( + buffer, + field_type_sig, + instantiation, + &function_source_map.type_parameters, + ) } - // The struct defs will filter out the structs that we print to only be the ones - // that are defined in the module in question. - pub fn disassemble_struct_def(&self, struct_def_idx: StructDefinitionIndex) -> Result { - let struct_definition = self.get_struct_def(struct_def_idx)?; + fn disassemble_struct_call( + &self, + buffer: &mut impl Write, + function_source_map: &FunctionSourceMap, + struct_idx: StructDefinitionIndex, + signature: &Signature, + ) -> Result<()> { + let struct_definition = self.source_mapper.bytecode.struct_def_at(struct_idx); let struct_handle = self .source_mapper .bytecode .datatype_handle_at(struct_definition.struct_handle); - let struct_source_map = self - .source_mapper - .source_map - .get_struct_source_map(struct_def_idx)?; - - let field_info: Option> = - match &struct_definition.field_information { - StructFieldInformation::Native => None, - StructFieldInformation::Declared(fields) => Some( - fields - .iter() - .map(|field_definition| { - let type_sig = &field_definition.signature; - let field_name = self - .source_mapper - .bytecode - .identifier_at(field_definition.name); - (field_name, type_sig) - }) - .collect(), - ), - }; - - let native = if field_info.is_none() { "native " } else { "" }; - - let abilities = if struct_handle.abilities == AbilitySet::EMPTY { - String::new() - } else { - let ability_vec: Vec<_> = struct_handle - .abilities - .into_iter() - .map(Self::format_ability) - .collect(); - format!(" has {}", ability_vec.join(", ")) - }; - let name = self .source_mapper .bytecode .identifier_at(struct_handle.name) .to_string(); + any_write!(buffer, "{name}")?; + delimited_list(&signature.0, "<", ", ", ">", buffer, |buffer, sig_tok| { + self.disassemble_sig_tok(buffer, sig_tok, None, &function_source_map.type_parameters) + }) + } - let ty_params = Self::disassemble_datatype_type_formals( - &struct_source_map.type_parameters, - &struct_handle.type_parameters, - ); - let mut fields = match field_info { - None => vec![], - Some(field_info) => field_info - .iter() - .map(|(name, ty)| { - let ty_str = - self.disassemble_sig_tok(ty.0.clone(), &struct_source_map.type_parameters)?; - Ok(format!("{}: {}", name, ty_str)) - }) - .collect::>>()?, + fn disassemble_constant( + &self, + buffer: &mut impl Write, + const_idx: usize, + constant: &Constant, + use_inline_formatting: bool, + ) -> Result<()> { + let data_str = match try_render_constant(constant) { + RenderResult::NotRendered => hex::encode(&constant.data), + RenderResult::AsValue(v_str) => v_str, + RenderResult::AsString(s) => "\"".to_owned() + &s + "\" // interpreted as UTF8 string", }; - - if let Some(first_elem) = fields.first_mut() { - first_elem.insert_str(0, "{\n\t"); - } - - if let Some(last_elem) = fields.last_mut() { - last_elem.push_str("\n}"); + if use_inline_formatting { + self.disassemble_sig_tok(buffer, &constant.type_, None, &[])?; + any_write!(buffer, ": {}", Self::preview_string(&data_str)) + } else { + any_write!(buffer, "\t{const_idx} => ")?; + self.disassemble_sig_tok(buffer, &constant.type_, None, &[])?; + any_writeln!(buffer, ": {data_str}") } - - Ok(format!( - "{native}struct {name}{ty_params}{abilities} {fields}", - native = native, - name = name, - ty_params = ty_params, - abilities = abilities, - fields = &fields.join(",\n\t"), - )) } - pub fn disassemble_enum_def(&self, enum_def_idx: EnumDefinitionIndex) -> Result { - let enum_definition = self.get_enum_def(enum_def_idx)?; - let enum_handle = self + fn disassemble_struct_field_access( + &self, + buffer: &mut impl Write, + field_idx: FieldHandleIndex, + ) -> Result<()> { + let field_handle = self.source_mapper.bytecode.field_handle_at(field_idx); + let struct_def = self .source_mapper .bytecode - .datatype_handle_at(enum_definition.enum_handle); - let enum_source_map = self - .source_mapper - .source_map - .get_enum_source_map(enum_def_idx)?; - - let mut variants_formatted = vec![]; - for variant in &enum_definition.variants { - let variant_name = self - .source_mapper - .bytecode - .identifier_at(variant.variant_name); - let mut variant_fields = vec![]; - for field_definition in &variant.fields { - let type_sig = &field_definition.signature; - let field_name = self - .source_mapper - .bytecode - .identifier_at(field_definition.name); - let ty_str = - self.disassemble_sig_tok(type_sig.0.clone(), &enum_source_map.type_parameters)?; - variant_fields.push(format!("{}: {}", field_name, ty_str)) + .struct_def_at(field_handle.owner); + let field_def = match &struct_def.field_information { + StructFieldInformation::Native => { + return any_write!( + buffer, + "ERROR[Attempt to access field on a native struct {}]", + field_idx + ); + } + StructFieldInformation::Declared(fields) => { + let Some(fields) = fields.get(field_handle.field as usize) else { + return any_write!(buffer, "ERROR[Bad field index {}]", field_handle.field); + }; + fields } - variants_formatted.push(format!( - "{} {{ {} }}", - variant_name, - variant_fields.join(", ") - )); - } - - let abilities = if enum_handle.abilities == AbilitySet::EMPTY { - String::new() - } else { - let ability_vec: Vec<_> = enum_handle - .abilities - .into_iter() - .map(Self::format_ability) - .collect(); - format!(" has {}", ability_vec.join(", ")) }; - - let name = self + let field_name = self .source_mapper .bytecode - .identifier_at(enum_handle.name) + .identifier_at(field_def.name) .to_string(); + let struct_handle = self + .source_mapper + .bytecode + .datatype_handle_at(struct_def.struct_handle); + let struct_name = self + .source_mapper + .bytecode + .identifier_at(struct_handle.name) + .to_string(); + any_write!(buffer, "{struct_name}.{field_name}") + } - let ty_params = Self::disassemble_datatype_type_formals( - &enum_source_map.type_parameters, - &enum_handle.type_parameters, - ); - - if let Some(first_elem) = variants_formatted.first_mut() { - first_elem.insert_str(0, "{\n\t"); + fn disassemble_function_string( + &self, + buffer: &mut impl Write, + module_handle: &ModuleHandle, + function_handle: &FunctionHandle, + ) -> Result<()> { + let module_id = self + .source_mapper + .bytecode + .module_id_for_handle(module_handle); + let function_name = self + .source_mapper + .bytecode + .identifier_at(function_handle.name); + if self.is_self_id(&module_id) { + // this is the "self" module. Omit the "module_name::" prefix + any_write!(buffer, "{function_name}") + } else { + let module_name = self + .module_aliases + .get(&module_id) + .cloned() + .unwrap_or_else(|| module_id.name().to_string()); + any_write!(buffer, "{module_name}::{function_name}") } + } +} - if let Some(last_elem) = variants_formatted.last_mut() { - last_elem.push_str("\n}"); - } +impl<'a> Disassembler<'a> { + //*************************************************************************** + // Formatters (that produce formatted strings) + //*************************************************************************** - Ok(format!( - "enum {name}{ty_params}{abilities} {variants}", - name = name, - ty_params = ty_params, - abilities = abilities, - variants = &variants_formatted.join(",\n\t"), - )) + fn format_ability(a: Ability) -> String { + match a { + Ability::Copy => "copy", + Ability::Drop => "drop", + Ability::Store => "store", + Ability::Key => "key", + } + .to_string() } - pub fn disassemble_constant(&self, constant: &Constant) -> Result<(String, String)> { - let data_str = match try_render_constant(constant) { - RenderResult::NotRendered => hex::encode(&constant.data), - RenderResult::AsValue(v_str) => v_str, - RenderResult::AsString(s) => "\"".to_owned() + &s + "\" // interpreted as UTF8 string", + fn format_name_for_parameter_or_local( + &self, + function_source_map: &FunctionSourceMap, + local_idx: usize, + ) -> String { + let Some(name) = function_source_map.get_parameter_or_local_name(local_idx as u64) else { + return format!( + "ERROR[Unable to get local name at index {local_idx} while disassembling location-based instruction]" + ); }; - let type_str = self.disassemble_sig_tok(constant.type_.clone(), &[])?; - Ok((type_str, data_str)) + name.0 } - pub fn disassemble(&self) -> Result { - let (addr, n) = &self.source_mapper.source_map.module_name; - let name = format!("{}.{}", addr.short_str_lossless(), n); - let version = format!("{}", self.source_mapper.bytecode.version()); - let header = format!("module {name}"); + //*************************************************************************** + // Helpers + //*************************************************************************** - let imports = self - .source_mapper - .bytecode - .module_handles() - .iter() - .filter_map(|h| self.get_import_string(h)) - .collect::>(); - let struct_defs: Vec = (0..self.source_mapper.bytecode.struct_defs().len()) - .map(|i| self.disassemble_struct_def(StructDefinitionIndex(i as TableIndex))) - .collect::>>()?; + fn is_self_id(&self, mid: &ModuleId) -> bool { + &self.source_mapper.bytecode.self_id() == mid + } - let enum_defs: Vec = (0..self.source_mapper.bytecode.enum_defs().len()) - .map(|i| self.disassemble_enum_def(EnumDefinitionIndex(i as TableIndex))) - .collect::>>()?; + fn preview_string(s: &str) -> String { + if s.len() <= PREVIEW_LEN + 2 { + s.to_string() + } else { + let mut preview: String = s.chars().take(PREVIEW_LEN).collect(); + preview.push_str(".."); + preview + } + } - let constants: Vec<(String, String)> = self - .source_mapper - .bytecode - .constant_pool() - .iter() - .map(|constant| self.disassemble_constant(constant)) - .collect::>>()?; + //*************************************************************************** + // Code Coverage Helpers + //*************************************************************************** - let function_defs: Vec = (0..self.source_mapper.bytecode.function_defs.len()) - .map(|i| { - let function_definition_index = FunctionDefinitionIndex(i as TableIndex); - let function_definition = self.get_function_def(function_definition_index)?; - let function_handle = self - .source_mapper - .bytecode - .function_handle_at(function_definition.function); - self.disassemble_function_def( - self.source_mapper - .source_map - .get_function_source_map(function_definition_index)?, - Some((function_definition, function_handle)), - self.source_mapper - .bytecode - .identifier_at(function_handle.name), - &function_handle.type_parameters, - function_handle.parameters, - function_definition.code.as_ref(), - &constants, - ) - }) - .collect::>>()?; - let imports_str = if imports.is_empty() { - "".to_string() - } else { - format!("\n{}\n\n", imports.join("\n")) - }; - let constant_pool_string = if constants.is_empty() { - "".to_string() - } else { - format!( - "\nConstants [\n{constants}\n]\n", - constants = constants - .into_iter() - .enumerate() - .map(|(i, (ty, s))| format!("\t{i} => {ty}: {s}")) - .collect::>() - .join("\n") - ) - }; - Ok(format!( - "// Move bytecode v{version}\n{header} {{{imports}\n{struct_defs}\n\n{enum_defs}\n\n{function_defs}\n{constant_pool_string}}}", - version = version, - header = header, - imports = &imports_str, - struct_defs = &struct_defs.join("\n"), - enum_defs = &enum_defs.join("\n"), - function_defs = &function_defs.join("\n"), - )) + fn get_function_coverage(&self, function_name: &IdentStr) -> Option<&FunctionCoverage> { + let module = &self.source_mapper.source_map.module_name; + + self.coverage_map.as_ref().and_then(|coverage_map| { + coverage_map + .module_maps + .get(module) + .and_then(|module_map| module_map.get_function_coverage(function_name)) + }) } } diff --git a/external-crates/move/crates/move-docgen/src/docgen.rs b/external-crates/move/crates/move-docgen/src/docgen.rs index 128e70df83c..37267e9aa26 100644 --- a/external-crates/move/crates/move-docgen/src/docgen.rs +++ b/external-crates/move/crates/move-docgen/src/docgen.rs @@ -20,7 +20,7 @@ use itertools::Itertools; use log::{debug, info, warn}; use move_compiler::parser::keywords::{BUILTINS, CONTEXTUAL_KEYWORDS, KEYWORDS}; use move_model::{ - ast::ModuleName, + ast::{Attribute, ModuleName, Value}, code_writer::{CodeWriter, CodeWriterLabel}, emit, emitln, model::{ @@ -953,14 +953,29 @@ impl<'env> Docgen<'env> { /// Generates declaration for named constant fn named_constant_display(&self, const_env: &NamedConstantEnv<'_>) -> String { let name = self.name_string(const_env.get_name()); + let is_error_const = const_env.get_attributes().iter().any(|attr| + matches!(attr, Attribute::Apply(_, sym, _) if self.name_string(*sym).to_string() == *"error") + ); + let rendered_value = match (is_error_const, const_env.get_value()) { + (true, Value::ByteArray(bytes)) => { + if let Ok(s) = std::str::from_utf8(&bytes) { + format!("b\"{s}\"") + } else { + format!("{bytes:?}") + } + } + (_, value) => value.to_string(), + }; + let error_const_annot = if is_error_const { "#[error]\n" } else { "" }; format!( - "const {}: {} = {};", + "{}const {}: {} = {};", + error_const_annot, name, const_env.get_type().display(&TypeDisplayContext::WithEnv { env: self.env, type_param_names: None, }), - const_env.get_value(), + rendered_value, ) } diff --git a/external-crates/move/crates/move-docgen/tests/sources/const_string_test.move b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.move new file mode 100644 index 00000000000..1e47c84992b --- /dev/null +++ b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.move @@ -0,0 +1,15 @@ +#[allow(unused)] +module 0x42::m { + #[error] + /// This is a doc comment above an error constant that should be rendered as a string + const AString: vector = b"Hello, world 🦀 "; + + #[error] + /// This is a doc comment above an error constant that should not be rendered as a string + const ErrorNotString: u64 = 10; + + const AStringNotError: vector = b"Hello, world 🦀 "; + + const NotAString: vector = vector[1, 2, 3]; +} + diff --git a/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline.md b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline.md new file mode 100644 index 00000000000..2ad75d7192b --- /dev/null +++ b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline.md @@ -0,0 +1,56 @@ + + + +# Module `0x42::m` + + + +- [Constants](#@Constants_0) + + +
+ + + + + +## Constants + + + + +This is a doc comment above an error constant that should be rendered as a string + + +
#[error]
+const AString: vector<u8> = b"Hello, world  🦀   ";
+
+ + + + + + + +
const AStringNotError: vector<u8> = [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 32, 32, 240, 159, 166, 128, 32, 32, 32];
+
+ + + + + +This is a doc comment above an error constant that should not be rendered as a string + + +
#[error]
+const ErrorNotString: u64 = 10;
+
+ + + + + + + +
const NotAString: vector<u8> = [1, 2, 3];
+
diff --git a/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline_no_fold.md b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline_no_fold.md new file mode 100644 index 00000000000..2ad75d7192b --- /dev/null +++ b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_inline_no_fold.md @@ -0,0 +1,56 @@ + + + +# Module `0x42::m` + + + +- [Constants](#@Constants_0) + + +
+ + + + + +## Constants + + + + +This is a doc comment above an error constant that should be rendered as a string + + +
#[error]
+const AString: vector<u8> = b"Hello, world  🦀   ";
+
+ + + + + + + +
const AStringNotError: vector<u8> = [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 32, 32, 240, 159, 166, 128, 32, 32, 32];
+
+ + + + + +This is a doc comment above an error constant that should not be rendered as a string + + +
#[error]
+const ErrorNotString: u64 = 10;
+
+ + + + + + + +
const NotAString: vector<u8> = [1, 2, 3];
+
diff --git a/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_separate.md b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_separate.md new file mode 100644 index 00000000000..2ad75d7192b --- /dev/null +++ b/external-crates/move/crates/move-docgen/tests/sources/const_string_test.spec_separate.md @@ -0,0 +1,56 @@ + + + +# Module `0x42::m` + + + +- [Constants](#@Constants_0) + + +
+ + + + + +## Constants + + + + +This is a doc comment above an error constant that should be rendered as a string + + +
#[error]
+const AString: vector<u8> = b"Hello, world  🦀   ";
+
+ + + + + + + +
const AStringNotError: vector<u8> = [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 32, 32, 240, 159, 166, 128, 32, 32, 32];
+
+ + + + + +This is a doc comment above an error constant that should not be rendered as a string + + +
#[error]
+const ErrorNotString: u64 = 10;
+
+ + + + + + + +
const NotAString: vector<u8> = [1, 2, 3];
+
diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/function.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/function.exp index 5d7c8a1cf7b..e39e61663fc 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/function.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/function.exp @@ -4,12 +4,11 @@ task 0, lines 1-31: //# print-bytecode // Move bytecode v6 module 3d10.Example { + struct Coin { value: u64 } - - public value(Arg0: &Coin): u64 { B0: 0: MoveLoc[0](Arg0: &Coin) @@ -18,8 +17,8 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: ReadRef 5: Ret - } + public deposit(Arg0: &mut Coin, Arg1: Coin) { L0: loc2: &Coin L1: loc3: u64 @@ -48,27 +47,26 @@ B0: 19: Unpack[0](Coin) 20: StLoc[7](loc5: u64) 21: Ret - } + } + task 1, lines 33-46: //# print-bytecode // Move bytecode v6 module 4d10.M { - - - entry public f() { B0: 0: Ret - } + entry public g() { B0: 0: Call f() 1: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.exp index aa7fce81d80..7629fb30974 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.exp @@ -3,19 +3,17 @@ processed 2 tasks task 0, lines 1-9: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 B0: 0: Ret - } + } + task 1, lines 11-20: //# print-bytecode Error: variable redefinition x diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.mvir index 5f699b22e83..2a593eff0cb 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/declarations/let.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // `let` generates a local with the given type. entry foo() { let x: u64; @@ -9,7 +9,7 @@ label b0: } //# print-bytecode -module 0x1.m { +module 0x6.m { // Two `let` cannot use the same name for a local. entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/binary_add.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/binary_add.exp index db621b20def..b7a9a463260 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/binary_add.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/binary_add.exp @@ -5,9 +5,6 @@ task 0, lines 1-13: // Move bytecode v6 module e.Expressions { - - - binary_add() { L0: loc0: u64 L1: loc1: u64 @@ -22,6 +19,7 @@ B0: 6: Add 7: StLoc[2](loc2: u64) 8: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.exp index c69235c0fde..08c0f03af4e 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.exp @@ -3,10 +3,7 @@ processed 9 tasks task 0, lines 1-13: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 @@ -19,17 +16,15 @@ B0: 4: MoveLoc[1](loc1: &u64) 5: Pop 6: Ret - } + } + task 1, lines 15-28: //# print-bytecode // Move bytecode v6 -module 2.m { - - - +module 7.m { entry foo() { L0: loc0: u64 @@ -43,20 +38,20 @@ B0: 4: ImmBorrowLoc[1](loc1: &u64) 5: StLoc[2](loc2: &u64) 6: Ret - } + } + task 2, lines 30-63: //# print-bytecode // Move bytecode v6 module 1d4.M { + struct T { u: u64 } - - f(Arg0: &T) { B0: 0: MoveLoc[0](Arg0: &T) @@ -65,8 +60,8 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: Pop 5: Ret - } + g(Arg0: &mut T) { B0: 0: MoveLoc[0](Arg0: &mut T) @@ -75,8 +70,8 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: Pop 5: Ret - } + public h(Arg0: &mut T) { B0: 0: MoveLoc[0](Arg0: &mut T) @@ -85,42 +80,43 @@ B0: 3: MoveLoc[1](loc0: &mut u64) 4: Pop 5: Ret - } + } + task 3, lines 65-84: //# print-bytecode // Move bytecode v6 module 2d4.M { + struct T { u: Ty0 } - - f(Arg0: &T) { B0: 0: MoveLoc[0](Arg0: &T) - 1: ImmBorrowFieldGeneric[0](T.u: Ty0) + 1: ImmBorrowFieldGeneric[0](T.u: u64) 2: StLoc[1](loc0: &u64) 3: MoveLoc[1](loc0: &u64) 4: Pop 5: Ret - } + g(Arg0: &mut T) { B0: 0: MoveLoc[0](Arg0: &mut T) - 1: ImmBorrowFieldGeneric[1](T.u: Ty0) + 1: ImmBorrowFieldGeneric[1](T.u: u128) 2: StLoc[1](loc0: &u128) 3: MoveLoc[1](loc0: &u128) 4: Pop 5: Ret - } + } + task 5, lines 97-112: //# print-bytecode Error: Unbound struct Self.T diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.mvir index d73a45b61f9..275e6c0fbf9 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // Borrowing a local produces a reference type. entry foo() { let x: u64; @@ -13,7 +13,7 @@ label b0: } //# print-bytecode -module 0x2.m { +module 0x7.m { // Borrowing a local reference produces a reference type. entry foo() { let x: u64; @@ -112,7 +112,7 @@ module 0x3d4.N { } //# print-bytecode -module 0x1.m { +module 0x8.m { import 0x3d4.M; entry foo(account: signer) { let t: M.T; @@ -142,7 +142,7 @@ module 0x3d4.O { } //# print-bytecode -module 0x1.m { +module 0x9.m { entry foo(account: signer) { let t: M.T; let r: &bool; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp index d0f31531995..aa808f4f2f8 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp @@ -3,10 +3,7 @@ processed 3 tasks task 0, lines 1-12: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 @@ -20,20 +17,20 @@ B0: 5: MoveLoc[1](loc1: &mut u64) 6: WriteRef 7: Ret - } + } + task 1, lines 14-25: //# print-bytecode // Move bytecode v6 module 3d.Foobar { + struct FooCoin { value: u64 } - - public borrow_mut_field(Arg0: &mut FooCoin) { B0: 0: MoveLoc[0](Arg0: &mut FooCoin) @@ -42,20 +39,20 @@ B0: 3: MoveLoc[1](loc0: &mut u64) 4: Pop 5: Ret - } + } + task 2, lines 27-38: //# print-bytecode // Move bytecode v6 module 4d.Foobar { + struct FooCoin { value: u64 } - - public borrow_mut_field(Arg0: &mut FooCoin
) { B0: 0: MoveLoc[0](Arg0: &mut FooCoin
) @@ -64,6 +61,7 @@ B0: 3: MoveLoc[1](loc0: &mut u64) 4: Pop 5: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.mvir index ee34b463c58..d72757a32f2 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/borrow_mut.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { entry foo() { let x: u64; let ref_x: &mut u64; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp index 1ac319a8abb..ea4e6d8a7e9 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp @@ -3,10 +3,7 @@ processed 1 task task 0, lines 1-33: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: vector @@ -60,6 +57,7 @@ B0: 41: MoveLoc[0](loc0: vector) 42: VecUnpack(1, 0) 43: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.mvir index 607bb21e07c..32ba979b4e8 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/vector.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { entry foo() { let v: vector; let v_imm: &vector; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.exp index a0053044543..a1d6580d0dd 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.exp @@ -3,10 +3,7 @@ processed 1 task task 0, lines 1-13: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 @@ -26,6 +23,7 @@ B0: 10: Sub 11: StLoc[2](loc2: u64) 12: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.mvir index 103f0b2bd9d..8e825e5a296 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/combined.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { entry foo() { let x: u64; let y: u64; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/pack.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/pack.exp index 9a42c7051e9..f0546e27077 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/pack.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/pack.exp @@ -4,21 +4,21 @@ task 0, lines 1-9: //# print-bytecode // Move bytecode v6 module 2d20.M { + struct T { u: u64 } - - f(): T { B0: 0: LdU64(0) 1: Pack[0](T) 2: Ret - } + } + task 1, lines 11-20: //# print-bytecode Error: Unbound field x diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.exp index b63abb556bd..d5c93a11722 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.exp @@ -4,19 +4,18 @@ task 0, lines 1-18: //# print-bytecode // Move bytecode v6 module 1d12.M { + struct T { b: bool } - - new(): T { B0: 0: LdTrue 1: Pack[0](T) 2: Ret - } + f() { L0: loc0: T L1: loc1: bool @@ -27,10 +26,11 @@ B0: 3: Unpack[0](T) 4: StLoc[1](loc1: bool) 5: Ret - } + } + task 2, lines 31-44: //# print-bytecode Error: Missing struct definition for T diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.mvir index e4521b5c709..85709fb5206 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/unpack.mvir @@ -30,7 +30,7 @@ module 0x2d12.M { //# print-bytecode // An unpack expression cannot reference a struct type defined in a separate module. -module 0x2d12.N { +module 0x2d13.N { import 0x2d12.M; f() { diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.exp index a86934cc2fc..1f175941a35 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.exp @@ -3,10 +3,7 @@ processed 1 task task 0, lines 1-10: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 @@ -23,6 +20,7 @@ B1: 8: Abort B2: 9: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.mvir index b68fffd474d..a5b06fa0c2e 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assert.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assign.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assign.mvir index 01d67d43a7e..46c1aa23ba6 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assign.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/assign.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // Un-declared locals cannot be assigned to. entry foo() { label b0: diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.exp index 47512546601..6f7d4b124d3 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.exp @@ -5,7 +5,6 @@ task 0, lines 1-71: // Move bytecode v7 module 3d8.M { - enum T has drop { X { }, Y { f: u64 } @@ -15,8 +14,8 @@ f(): T { B0: 0: PackVariant(VariantHandleIndex(0)) 1: Ret - } + f1(): T { L0: loc0: T L1: loc1: u64 @@ -29,8 +28,8 @@ B0: 5: StLoc[1](loc1: u64) 6: PackVariant(VariantHandleIndex(0)) 7: Ret - } + f2(): T { L0: loc0: T L1: loc1: u64 @@ -55,6 +54,7 @@ Jump tables: Variant1 => jump 7 } } + f3(): T { L0: loc0: T L1: loc1: u64 @@ -80,6 +80,7 @@ Jump tables: Variant1 => jump 7 } } + f4(): T { L0: loc0: T L1: loc1: u64 @@ -105,4 +106,6 @@ Jump tables: Variant1 => jump 7 } } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.exp index 93db6005b08..93fab82297c 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.exp @@ -3,35 +3,31 @@ processed 3 tasks task 0, lines 1-8: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { B0: 0: Branch(0) - } + } + task 1, lines 10-19: //# print-bytecode // Move bytecode v6 -module 2.m { - - - +module 7.m { entry foo() { B0: 0: Branch(1) B1: 1: Branch(0) - } + } + task 2, lines 21-32: //# print-bytecode Error: Invalid block labels, labels were used without being declared (bar) diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.mvir index 098073027c7..d6111b7079d 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // An endless loop is valid Move IR. entry foo() { label loop: @@ -8,7 +8,7 @@ label loop: } //# print-bytecode -module 0x2.m { +module 0x7.m { // Jumping to a label that is declared after the jump statement itself is valid. entry foo() { label foo: @@ -20,7 +20,7 @@ label bar: //# print-bytecode // Jumping to a label that isn't declared in the same function is invalid. -module 0x1.M { +module 0x6.M { f() { label foo: jump bar; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.exp index fc7789076eb..198484fa077 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.exp @@ -3,10 +3,7 @@ processed 4 tasks task 0, lines 1-24: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 @@ -27,17 +24,15 @@ B3: 10: Branch(11) B4: 11: Ret - } + } + task 1, lines 26-45: //# print-bytecode // Move bytecode v6 -module 2.m { - - - +module 7.m { entry foo() { L0: loc0: u64 @@ -55,17 +50,15 @@ B2: 8: StLoc[0](loc0: u64) B3: 9: Ret - } + } + task 2, lines 47-65: //# print-bytecode // Move bytecode v6 -module 3.m { - - - +module 8.m { entry foo() { L0: loc0: u64 @@ -92,17 +85,15 @@ B4: 15: StLoc[0](loc0: u64) B5: 16: Ret - } + } + task 3, lines 67-82: //# print-bytecode // Move bytecode v6 -module 4.m { - - - +module 9.m { entry foo() { L0: loc0: u64 @@ -121,6 +112,7 @@ B2: 9: Ret B3: 10: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.mvir index f28d2c2cb74..2fa7ef1e7d4 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // This is roughly equivalent to the following Move program: // ``` // if (42 > 0) { x = 1; } else { x = 2; } @@ -24,7 +24,7 @@ label b3: } //# print-bytecode -module 0x2.m { +module 0x7.m { // This is roughly equivalent to the following Move program: // ``` // if (42 > 0) { x = 1; } else { x = 2; } @@ -45,7 +45,7 @@ label b2: } //# print-bytecode -module 0x3.m { +module 0x8.m { // `jump_if` statements can be sequenced, akin to "nested" `if` statements in Move. entry foo() { let x: u64; @@ -65,7 +65,7 @@ label end: } //# print-bytecode -module 0x4.m { +module 0x9.m { // `return` statements can appear anywhere, including within a jump destination's block. entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp index 427c1c557b2..71ffb75afd6 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp @@ -3,10 +3,7 @@ processed 4 tasks task 0, lines 1-20: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { L0: loc0: u64 @@ -26,17 +23,15 @@ B2: 10: Branch(2) B3: 11: Ret - } + } + task 1, lines 22-36: //# print-bytecode // Move bytecode v6 -module 2.m { - - - +module 7.m { entry foo() { L0: loc0: u64 @@ -52,17 +47,15 @@ B3: 5: Branch(2) B4: 6: Ret - } + } + task 2, lines 38-48: //# print-bytecode // Move bytecode v6 -module 3.m { - - - +module 8.m { entry foo() { B0: @@ -72,17 +65,15 @@ B1: 2: Branch(3) B2: 3: Ret - } + } + task 3, lines 50-63: //# print-bytecode // Move bytecode v6 -module 4.m { - - - +module 9.m { entry foo() { B0: @@ -95,6 +86,7 @@ B3: 3: Branch(0) B4: 4: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.mvir index 0df1612cc7f..a112b54aa00 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/jump_if_false.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // This is roughly equivalent to the following Move program: // ``` // let x: u64 = 0; @@ -20,7 +20,7 @@ label b2: } //# print-bytecode -module 0x2.m { +module 0x7.m { // `return` statements can appear anywhere, even within a loop. entry foo() { let x: u64; @@ -36,7 +36,7 @@ label b2: } //# print-bytecode -module 0x3.m { +module 0x8.m { // This is roughly equivalent to the following Move code: `while (true) { break; }`. entry foo() { label b0: @@ -48,7 +48,7 @@ label b2: } //# print-bytecode -module 0x4.m { +module 0x9.m { // This is roughly equivalent to the following Move code: `loop { loop { break; } break; }`. entry foo() { label b0: diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.exp index 65946459735..1d65d393882 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.exp @@ -3,63 +3,55 @@ processed 6 tasks task 0, lines 1-8: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { B0: 0: Ret - } + } + task 1, lines 10-18: //# print-bytecode // Move bytecode v6 -module 2.m { - - - +module 7.m { entry foo() { B0: 0: Ret - } + } + task 2, lines 20-26: //# print-bytecode // Move bytecode v6 -module 3.m { - - - +module 8.m { entry foo() { B0: 0: Ret - } + } + task 3, lines 28-35: //# print-bytecode // Move bytecode v6 -module 4.m { - - - +module 9.m { entry foo() { B0: 0: Ret - } + } + task 4, lines 37-46: //# print-bytecode Error: ParserError: Invalid Token: invalid token kind for statement Slash @@ -67,14 +59,12 @@ Error: ParserError: Invalid Token: invalid token kind for statement Slash task 5, lines 48-58: //# print-bytecode // Move bytecode v6 -module 6.m { - - - +module b.m { entry foo() { B0: 0: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.mvir index 91441a98649..f2e5a139ad1 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/comments.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { entry foo() { label b0: // return; @@ -8,7 +8,7 @@ label b0: } //# print-bytecode -module 0x2.m { +module 0x7.m { entry foo() { label b0: // return; @@ -18,7 +18,7 @@ label b0: } //# print-bytecode -module 0x3.m { +module 0x8.m { entry foo() { label b0: return; // return; @@ -26,7 +26,7 @@ label b0: } //# print-bytecode -module 0x4.m { +module 0x9.m { entry foo() { label b0: // return; @@ -35,7 +35,7 @@ label b0: } //# print-bytecode -module 0x5.m { +module 0xa.m { // In Move, /* */ are block comment delimiters. Not so in Move IR, so the `/*` below // cannot be parsed. entry foo() { @@ -46,7 +46,7 @@ label b0: } //# print-bytecode -module 0x6.m { +module 0xb.m { // Since /* */ are not block comment delimiters, they do not behave in any unique way when // they appear within comments. entry foo() { diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.exp index 65946459735..1d65d393882 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.exp @@ -3,63 +3,55 @@ processed 6 tasks task 0, lines 1-8: //# print-bytecode // Move bytecode v6 -module 1.m { - - - +module 6.m { entry foo() { B0: 0: Ret - } + } + task 1, lines 10-18: //# print-bytecode // Move bytecode v6 -module 2.m { - - - +module 7.m { entry foo() { B0: 0: Ret - } + } + task 2, lines 20-26: //# print-bytecode // Move bytecode v6 -module 3.m { - - - +module 8.m { entry foo() { B0: 0: Ret - } + } + task 3, lines 28-35: //# print-bytecode // Move bytecode v6 -module 4.m { - - - +module 9.m { entry foo() { B0: 0: Ret - } + } + task 4, lines 37-46: //# print-bytecode Error: ParserError: Invalid Token: invalid token kind for statement Slash @@ -67,14 +59,12 @@ Error: ParserError: Invalid Token: invalid token kind for statement Slash task 5, lines 48-58: //# print-bytecode // Move bytecode v6 -module 6.m { - - - +module b.m { entry foo() { B0: 0: Ret - } + } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.mvir index 91441a98649..f2e5a139ad1 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/crlf.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { entry foo() { label b0: // return; @@ -8,7 +8,7 @@ label b0: } //# print-bytecode -module 0x2.m { +module 0x7.m { entry foo() { label b0: // return; @@ -18,7 +18,7 @@ label b0: } //# print-bytecode -module 0x3.m { +module 0x8.m { entry foo() { label b0: return; // return; @@ -26,7 +26,7 @@ label b0: } //# print-bytecode -module 0x4.m { +module 0x9.m { entry foo() { label b0: // return; @@ -35,7 +35,7 @@ label b0: } //# print-bytecode -module 0x5.m { +module 0xa.m { // In Move, /* */ are block comment delimiters. Not so in Move IR, so the `/*` below // cannot be parsed. entry foo() { @@ -46,7 +46,7 @@ label b0: } //# print-bytecode -module 0x6.m { +module 0xb.m { // Since /* */ are not block comment delimiters, they do not behave in any unique way when // they appear within comments. entry foo() { diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/keywords.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/keywords.mvir index b64145bb9c7..4ecfc4cca20 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/keywords.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/keywords.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // `label` is a keyword so it cannot be used as a parameter name. entry foo(label: address) { label b0: diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/named_addresses.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/named_addresses.exp index 37cce18bb1b..0daf94b4f26 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/named_addresses.exp +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/named_addresses.exp @@ -6,25 +6,20 @@ task 2, lines 16-36: module 1.M { use 0000000000000000000000000000000000000000000000000000000000000001::T; - - - - - f(): address { B0: 0: Call T::f() 1: LdConst[0](address: 0x00..) 2: Ret - } + h(): address { B0: 0: LdConst[0](address: 0x00..) 1: Call T::g(address): address 2: Ret - } + l(): address { L0: loc0: address B0: @@ -33,10 +28,10 @@ B0: 2: MoveLoc[0](loc0: address) 3: Call T::g(address): address 4: Ret - } Constants [ 0 => address: 0x0000000000000000000000000000000000000000000000000000000000000001 ] } + diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/types.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/types.mvir index 068ba2dbbf6..2a405f6ebea 100644 --- a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/types.mvir +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/types.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.m { +module 0x6.m { // Struct field specifiers in immutable borrows must not be qualified. entry foo() { label b0: @@ -8,7 +8,7 @@ label b0: } //# print-bytecode -module 0x2.m { +module 0x7.m { // Struct field specifiers in mutable borrows must not be qualified. entry foo() { label b0: diff --git a/external-crates/move/crates/move-ir-to-bytecode-syntax/src/lexer.rs b/external-crates/move/crates/move-ir-to-bytecode-syntax/src/lexer.rs index 262ccbba272..b131fea7eca 100644 --- a/external-crates/move/crates/move-ir-to-bytecode-syntax/src/lexer.rs +++ b/external-crates/move/crates/move-ir-to-bytecode-syntax/src/lexer.rs @@ -155,7 +155,7 @@ impl<'input> Lexer<'input> { loop { // Trim the only whitespace characters we recognize: newline, tab, and space. text = text.trim_start_matches("\r\n"); - text = text.trim_start_matches(|c: char| matches!(c, '\n' | '\t' | ' ')); + text = text.trim_start_matches(['\n', '\t', ' ']); // Trim the only comments we recognize: '// ... \n'. if text.starts_with("//") { text = text.trim_start_matches(|c: char| c != '\n'); diff --git a/external-crates/move/crates/move-ir-to-bytecode-syntax/src/syntax.rs b/external-crates/move/crates/move-ir-to-bytecode-syntax/src/syntax.rs index 40c11f9740f..be6f9c65eae 100644 --- a/external-crates/move/crates/move-ir-to-bytecode-syntax/src/syntax.rs +++ b/external-crates/move/crates/move-ir-to-bytecode-syntax/src/syntax.rs @@ -1334,64 +1334,65 @@ fn parse_ability(tokens: &mut Lexer) -> Result<(Ability, Loc), ParseError Result> { + let start_loc = tokens.start_loc(); let t = match tokens.peek() { Tok::NameValue if matches!(tokens.content(), "address") => { tokens.advance()?; - Type::Address + Type_::Address } Tok::NameValue if matches!(tokens.content(), "u8") => { tokens.advance()?; - Type::U8 + Type_::U8 } Tok::NameValue if matches!(tokens.content(), "u16") => { tokens.advance()?; - Type::U16 + Type_::U16 } Tok::NameValue if matches!(tokens.content(), "u32") => { tokens.advance()?; - Type::U32 + Type_::U32 } Tok::NameValue if matches!(tokens.content(), "u64") => { tokens.advance()?; - Type::U64 + Type_::U64 } Tok::NameValue if matches!(tokens.content(), "u128") => { tokens.advance()?; - Type::U128 + Type_::U128 } Tok::NameValue if matches!(tokens.content(), "u256") => { tokens.advance()?; - Type::U256 + Type_::U256 } Tok::NameValue if matches!(tokens.content(), "bool") => { tokens.advance()?; - Type::Bool + Type_::Bool } Tok::NameValue if matches!(tokens.content(), "signer") => { tokens.advance()?; - Type::Signer + Type_::Signer } Tok::NameBeginTyValue if matches!(tokens.content(), "vector<") => { tokens.advance()?; let ty = parse_type(tokens)?; adjust_token(tokens, &[Tok::Greater])?; consume_token(tokens, Tok::Greater)?; - Type::Vector(Box::new(ty)) + Type_::Vector(Box::new(ty)) } Tok::DotNameValue => { let s = parse_qualified_struct_ident(tokens)?; let tys = parse_type_actuals(tokens)?; - Type::Datatype(s, tys) + Type_::Datatype(s, tys) } Tok::Amp => { tokens.advance()?; - Type::Reference(false, Box::new(parse_type(tokens)?)) + Type_::Reference(false, Box::new(parse_type(tokens)?)) } Tok::AmpMut => { tokens.advance()?; - Type::Reference(true, Box::new(parse_type(tokens)?)) + Type_::Reference(true, Box::new(parse_type(tokens)?)) } - Tok::NameValue => Type::TypeParameter(TypeVar_(parse_name(tokens)?)), + Tok::NameValue => Type_::TypeParameter(TypeVar_(parse_name(tokens)?)), t => { return Err(ParseError::InvalidToken { location: current_token_loc(tokens), @@ -1399,7 +1400,8 @@ fn parse_type(tokens: &mut Lexer) -> Result }); } }; - Ok(t) + let end_loc = tokens.previous_end_loc(); + Ok(spanned(tokens.file_hash(), start_loc, end_loc, t)) } // TypeVar: TypeVar = { @@ -1646,23 +1648,26 @@ fn parse_function_decl( None }; + let body = if is_native { + consume_token(tokens, Tok::Semicolon)?; + FunctionBody::Native + } else { + let (locals, body) = parse_function_block_(tokens)?; + FunctionBody::Move { locals, code: body } + }; + + let end_loc = tokens.previous_end_loc(); let func_name = FunctionName(name); let func = Function_::new( + make_loc(tokens.file_hash(), start_loc, end_loc), visibility, is_entry, args, ret.unwrap_or_default(), type_parameters, - if is_native { - consume_token(tokens, Tok::Semicolon)?; - FunctionBody::Native - } else { - let (locals, body) = parse_function_block_(tokens)?; - FunctionBody::Move { locals, code: body } - }, + body, ); - let end_loc = tokens.previous_end_loc(); Ok(( func_name, spanned(tokens.file_hash(), start_loc, end_loc, func), diff --git a/external-crates/move/crates/move-ir-to-bytecode/src/compiler.rs b/external-crates/move/crates/move-ir-to-bytecode/src/compiler.rs index c94d35d6f90..0a2dc4e2705 100644 --- a/external-crates/move/crates/move-ir-to-bytecode/src/compiler.rs +++ b/external-crates/move/crates/move-ir-to-bytecode/src/compiler.rs @@ -50,6 +50,11 @@ macro_rules! record_src_loc { .source_map .add_parameter_mapping($context.current_function_definition_index(), source_name)?; }}; + (return_: $context:expr, $_type:expr) => {{ + $context + .source_map + .add_return_mapping($context.current_function_definition_index(), $_type.loc)?; + }}; (field: $context:expr, $idx: expr, $field:expr) => {{ $context .source_map @@ -70,11 +75,12 @@ macro_rules! record_src_loc { )?; } }; - (function_decl: $context:expr, $location:expr, $function_index:expr, $is_native:expr) => {{ + (function_decl: $context:expr, $location:expr, $definition_location: expr, $function_index:expr, $is_native:expr) => {{ $context.set_function_index($function_index as TableIndex); $context.source_map.add_top_level_function_mapping( $context.current_function_definition_index(), $location, + $definition_location, $is_native, )?; }}; @@ -349,7 +355,7 @@ fn constant_name_as_constant_value_index( ) -> Result { let name_constant = compile_constant( context, - Type::Vector(Box::new(Type::U8)), + &MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), MoveValue::vector_u8(const_name.to_string().into_bytes()), )?; context.constant_index(name_constant) @@ -418,7 +424,11 @@ pub fn compile_module<'a>( constant_name_as_constant_value_index(&mut context, &ir_constant.name)?; } - let constant = compile_constant(&mut context, ir_constant.signature, ir_constant.value)?; + let constant = compile_constant( + &mut context, + &type_to_constant_type_layout(ir_constant.signature)?, + ir_constant.value, + )?; context.declare_constant(ir_constant.name.clone(), constant.clone())?; let const_idx = context.constant_index(constant)?; record_src_loc!(const_decl: context, const_idx, ir_constant.name); @@ -683,22 +693,22 @@ fn compile_type( type_parameters: &HashMap, ty: &Type, ) -> Result { - Ok(match ty { - Type::Address => SignatureToken::Address, - Type::Signer => SignatureToken::Signer, - Type::U8 => SignatureToken::U8, - Type::U16 => SignatureToken::U16, - Type::U32 => SignatureToken::U32, - Type::U64 => SignatureToken::U64, - Type::U128 => SignatureToken::U128, - Type::U256 => SignatureToken::U256, - Type::Bool => SignatureToken::Bool, - Type::Vector(inner_type) => SignatureToken::Vector(Box::new(compile_type( + Ok(match &ty.value { + Type_::Address => SignatureToken::Address, + Type_::Signer => SignatureToken::Signer, + Type_::U8 => SignatureToken::U8, + Type_::U16 => SignatureToken::U16, + Type_::U32 => SignatureToken::U32, + Type_::U64 => SignatureToken::U64, + Type_::U128 => SignatureToken::U128, + Type_::U256 => SignatureToken::U256, + Type_::Bool => SignatureToken::Bool, + Type_::Vector(inner_type) => SignatureToken::Vector(Box::new(compile_type( context, type_parameters, inner_type, )?)), - Type::Reference(is_mutable, inner_type) => { + Type_::Reference(is_mutable, inner_type) => { let inner_token = Box::new(compile_type(context, type_parameters, inner_type)?); if *is_mutable { SignatureToken::MutableReference(inner_token) @@ -706,7 +716,7 @@ fn compile_type( SignatureToken::Reference(inner_token) } } - Type::Datatype(ident, tys) => { + Type_::Datatype(ident, tys) => { let sh_idx = context.datatype_handle_index(ident.clone())?; if tys.is_empty() { @@ -716,7 +726,7 @@ fn compile_type( SignatureToken::DatatypeInstantiation(Box::new((sh_idx, tokens))) } } - Type::TypeParameter(ty_var) => { + Type_::TypeParameter(ty_var) => { let idx = match type_parameters.get(ty_var) { None => bail!("Unbound type parameter {}", ty_var), Some(idx) => *idx, @@ -889,6 +899,7 @@ fn compile_function_body_impl( context, m, ast_function.signature.formals, + ast_function.signature.return_type, locals, code, )?) @@ -905,6 +916,7 @@ fn compile_function_body_impl( context, m, ast_function.signature.formals, + ast_function.signature.return_type, locals, code, )?) @@ -914,6 +926,9 @@ fn compile_function_body_impl( for (var, _) in ast_function.signature.formals.into_iter() { record_src_loc!(parameter: context, var) } + for _type in ast_function.signature.return_type.into_iter() { + record_src_loc!(return_: context, _type) + } None } }) @@ -928,6 +943,7 @@ fn compile_function( ) -> Result { record_src_loc!( function_decl: context, + ast_function.value.loc, ast_function.loc, function_index, matches!(ast_function.value.body, FunctionBody::Native) @@ -961,6 +977,7 @@ fn compile_function_body( context: &mut Context, type_parameters: HashMap, formals: Vec<(Var, Type)>, + return_type: Vec, locals: Vec<(Var, Type)>, blocks: Vec, ) -> Result { @@ -971,6 +988,9 @@ fn compile_function_body( record_src_loc!(parameter: context, var); } + for _type in return_type { + record_src_loc!(return_: context, _type); + } let mut locals_signature = Signature(vec![]); for (var_, t) in locals { let sig = compile_type(context, function_frame.type_parameters(), &t)?; @@ -1282,7 +1302,7 @@ fn compile_expression( Exp_::Value(cv) => match cv.value { CopyableVal_::Address(address) => { let address_value = MoveValue::Address(address); - let constant = compile_constant(context, Type::Address, address_value)?; + let constant = compile_constant(context, &MoveTypeLayout::Address, address_value)?; let idx = context.constant_index(constant)?; push_instr!(exp.loc, Bytecode::LdConst(idx)); function_frame.push()?; @@ -1313,8 +1333,8 @@ fn compile_expression( } CopyableVal_::ByteArray(buf) => { let vec_value = MoveValue::vector_u8(buf); - let ty = Type::Vector(Box::new(Type::U8)); - let constant = compile_constant(context, ty, vec_value)?; + let ty = MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)); + let constant = compile_constant(context, &ty, vec_value)?; let idx = context.constant_index(constant)?; push_instr!(exp.loc, Bytecode::LdConst(idx)); function_frame.push()?; @@ -1684,30 +1704,38 @@ fn compile_call( Ok(()) } -fn compile_constant(_context: &mut Context, ty: Type, value: MoveValue) -> Result { - fn type_layout(ty: Type) -> Result { - Ok(match ty { - Type::Address => MoveTypeLayout::Address, - Type::Signer => MoveTypeLayout::Signer, - Type::U8 => MoveTypeLayout::U8, - Type::U16 => MoveTypeLayout::U16, - Type::U32 => MoveTypeLayout::U32, - Type::U64 => MoveTypeLayout::U64, - Type::U128 => MoveTypeLayout::U128, - Type::U256 => MoveTypeLayout::U256, - Type::Bool => MoveTypeLayout::Bool, - Type::Vector(inner_type) => MoveTypeLayout::Vector(Box::new(type_layout(*inner_type)?)), - Type::Reference(_, _) => bail!("References are not supported in constant type layouts"), - Type::TypeParameter(_) => { - bail!("Type parameters are not supported in constant type layouts") - } - Type::Datatype(_ident, _tys) => { - bail!("TODO Structs are not *yet* supported in constant type layouts") - } - }) - } +fn type_to_constant_type_layout(ty: Type) -> Result { + Ok(match ty.value { + Type_::Address => MoveTypeLayout::Address, + Type_::Signer => MoveTypeLayout::Signer, + Type_::U8 => MoveTypeLayout::U8, + Type_::U16 => MoveTypeLayout::U16, + Type_::U32 => MoveTypeLayout::U32, + Type_::U64 => MoveTypeLayout::U64, + Type_::U128 => MoveTypeLayout::U128, + Type_::U256 => MoveTypeLayout::U256, + Type_::Bool => MoveTypeLayout::Bool, + Type_::Vector(inner_type) => { + MoveTypeLayout::Vector(Box::new(type_to_constant_type_layout(*inner_type)?)) + } + Type_::Reference(_, _) => { + bail!("References are not supported in constant type layouts") + } + Type_::TypeParameter(_) => { + bail!("Type parameters are not supported in constant type layouts") + } + Type_::Datatype(_ident, _tys) => { + bail!("TODO Structs are not *yet* supported in constant type layouts") + } + }) +} - Constant::serialize_constant(&type_layout(ty)?, &value) +fn compile_constant( + _context: &mut Context, + layout: &MoveTypeLayout, + value: MoveValue, +) -> Result { + Constant::serialize_constant(layout, &value) .ok_or_else(|| format_err!("Could not serialize constant")) } @@ -1719,6 +1747,7 @@ fn compile_function_body_bytecode( context: &mut Context, type_parameters: HashMap, formals: Vec<(Var, Type)>, + return_type: Vec, locals: Vec<(Var, Type)>, blocks: BytecodeBlocks, ) -> Result { @@ -1729,6 +1758,9 @@ fn compile_function_body_bytecode( function_frame.define_local(&var.value, sig.clone())?; record_src_loc!(parameter: context, var); } + for _type in return_type { + record_src_loc!(return_: context, _type); + } for (var_, t) in locals { let sig = compile_type(context, function_frame.type_parameters(), &t)?; function_frame.define_local(&var_.value, sig.clone())?; @@ -1808,7 +1840,7 @@ fn compile_bytecode( IRBytecode_::LdTrue => Bytecode::LdTrue, IRBytecode_::LdFalse => Bytecode::LdFalse, IRBytecode_::LdConst(ty, v) => { - let constant = compile_constant(context, ty, v)?; + let constant = compile_constant(context, &type_to_constant_type_layout(ty)?, v)?; Bytecode::LdConst(context.constant_index(constant)?) } IRBytecode_::LdNamedConst(c) => Bytecode::LdConst(context.named_constant_index(&c)?), diff --git a/external-crates/move/crates/move-ir-types/src/ast.rs b/external-crates/move/crates/move-ir-types/src/ast.rs index 75ee697bfc0..7b3cf99fe14 100644 --- a/external-crates/move/crates/move-ir-types/src/ast.rs +++ b/external-crates/move/crates/move-ir-types/src/ast.rs @@ -144,9 +144,12 @@ pub enum Ability { // Types //************************************************************************************************** +/// The type of a single value coupled with source location information. +pub type Type = Spanned; + /// The type of a single value #[derive(Debug, PartialEq, Clone)] -pub enum Type { +pub enum Type_ { /// `address` Address, /// `signer` @@ -378,6 +381,8 @@ pub enum FunctionBody { /// A Move function/procedure #[derive(PartialEq, Debug, Clone)] pub struct Function_ { + /// Location of the whole function + pub loc: Loc, /// The visibility pub visibility: FunctionVisibility, /// Is entry function @@ -839,33 +844,6 @@ impl Ability { pub const KEY: &'static str = "key"; } -impl Type { - /// Creates a new struct type - pub fn r#struct(ident: QualifiedDatatypeIdent, type_actuals: Vec) -> Type { - Type::Datatype(ident, type_actuals) - } - - /// Creates a new reference type from its mutability and underlying type - pub fn reference(is_mutable: bool, t: Type) -> Type { - Type::Reference(is_mutable, Box::new(t)) - } - - /// Creates a new address type - pub fn address() -> Type { - Type::Address - } - - /// Creates a new u64 type - pub fn u64() -> Type { - Type::U64 - } - - /// Creates a new bool type - pub fn bool() -> Type { - Type::Bool - } -} - impl QualifiedDatatypeIdent { /// Creates a new StructType handle from the name of the module alias and /// the name of the struct @@ -979,6 +957,7 @@ impl Function_ { /// Creates a new function declaration from the components of the function /// See the declaration of the struct `Function` for more details pub fn new( + loc: Loc, visibility: FunctionVisibility, is_entry: bool, formals: Vec<(Var, Type)>, @@ -988,6 +967,7 @@ impl Function_ { ) -> Self { let signature = FunctionSignature::new(formals, return_type, type_parameters); Function_ { + loc, visibility, is_entry, signature, @@ -1464,24 +1444,24 @@ fn format_struct_type_formals(formals: &[DatatypeTypeParameter]) -> String { } } -impl fmt::Display for Type { +impl fmt::Display for Type_ { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Type::U8 => write!(f, "u8"), - Type::U16 => write!(f, "u16"), - Type::U32 => write!(f, "u32"), - Type::U64 => write!(f, "u64"), - Type::U128 => write!(f, "u128"), - Type::U256 => write!(f, "u256"), - Type::Bool => write!(f, "bool"), - Type::Address => write!(f, "address"), - Type::Signer => write!(f, "signer"), - Type::Vector(ty) => write!(f, "vector<{}>", ty), - Type::Datatype(ident, tys) => write!(f, "{}{}", ident, format_type_actuals(tys)), - Type::Reference(is_mutable, t) => { + Type_::U8 => write!(f, "u8"), + Type_::U16 => write!(f, "u16"), + Type_::U32 => write!(f, "u32"), + Type_::U64 => write!(f, "u64"), + Type_::U128 => write!(f, "u128"), + Type_::U256 => write!(f, "u256"), + Type_::Bool => write!(f, "bool"), + Type_::Address => write!(f, "address"), + Type_::Signer => write!(f, "signer"), + Type_::Vector(ty) => write!(f, "vector<{}>", ty), + Type_::Datatype(ident, tys) => write!(f, "{}{}", ident, format_type_actuals(tys)), + Type_::Reference(is_mutable, t) => { write!(f, "&{}{}", if *is_mutable { "mut " } else { "" }, t) } - Type::TypeParameter(s) => write!(f, "{}", s), + Type_::TypeParameter(s) => write!(f, "{}", s), } } } diff --git a/external-crates/move/crates/move-model/src/builder/model_builder.rs b/external-crates/move/crates/move-model/src/builder/model_builder.rs index 848185cae5f..86dc8d848c4 100644 --- a/external-crates/move/crates/move-model/src/builder/model_builder.rs +++ b/external-crates/move/crates/move-model/src/builder/model_builder.rs @@ -77,6 +77,7 @@ pub(crate) struct ConstEntry { pub loc: Loc, pub ty: Type, pub value: Value, + pub attributes: Vec, } impl<'env> ModelBuilder<'env> { diff --git a/external-crates/move/crates/move-model/src/builder/module_builder.rs b/external-crates/move/crates/move-model/src/builder/module_builder.rs index ccfc88d4284..7846f914be5 100644 --- a/external-crates/move/crates/move-model/src/builder/module_builder.rs +++ b/external-crates/move/crates/move-model/src/builder/module_builder.rs @@ -292,13 +292,20 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { let move_value = Constant::deserialize_constant(&compiled_module.constant_pool()[*const_idx as usize]) .unwrap(); + let attributes = self.translate_attributes(&def.attributes); let mut et = ExpTranslator::new(self); let loc = et.to_loc(&def.loc); let ty = et.translate_type(&def.signature); let value = et.translate_from_move_value(&loc, &ty, &move_value); - et.parent - .parent - .define_const(qsym, ConstEntry { loc, ty, value }); + et.parent.parent.define_const( + qsym, + ConstEntry { + loc, + ty, + value, + attributes, + }, + ); } fn decl_ana_struct(&mut self, name: &PA::DatatypeName, def: &EA::StructDefinition) { @@ -631,12 +638,21 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { .iter() .filter(|(name, _)| name.module_name == self.module_name) .map(|(name, const_entry)| { - let ConstEntry { loc, value, ty } = const_entry.clone(); + let ConstEntry { + loc, + value, + ty, + attributes, + } = const_entry.clone(); ( NamedConstantId::new(name.symbol), - self.parent - .env - .create_named_constant_data(name.symbol, loc, ty, value), + self.parent.env.create_named_constant_data( + name.symbol, + loc, + ty, + value, + attributes, + ), ) }) .collect(); diff --git a/external-crates/move/crates/move-model/src/lib.rs b/external-crates/move/crates/move-model/src/lib.rs index b0541a3263a..0515ed5bd60 100644 --- a/external-crates/move/crates/move-model/src/lib.rs +++ b/external-crates/move/crates/move-model/src/lib.rs @@ -22,7 +22,7 @@ use move_binary_format::file_format::{ use move_compiler::{ self, compiled_unit::{self, AnnotatedCompiledUnit}, - diagnostics::{Diagnostics, WarningFilters}, + diagnostics::{warning_filters::WarningFiltersBuilder, Diagnostics}, expansion::ast::{self as E, ModuleIdent, ModuleIdent_, TargetKind}, parser::ast as P, shared::{parse_named_address, unique_map::UniqueMap, NumericalAddress, PackagePaths}, @@ -63,7 +63,7 @@ pub fn run_model_builder< >( move_sources: Vec>, deps: Vec>, - warning_filter: Option, + warning_filter: Option, ) -> anyhow::Result { run_model_builder_with_options( move_sources, @@ -84,7 +84,7 @@ pub fn run_model_builder_with_options< move_sources: Vec>, deps: Vec>, options: ModelBuilderOptions, - warning_filter: Option, + warning_filter: Option, ) -> anyhow::Result { run_model_builder_with_options_and_compilation_flags( move_sources, @@ -106,7 +106,7 @@ pub fn run_model_builder_with_options_and_compilation_flags< deps: Vec>, options: ModelBuilderOptions, flags: Flags, - warning_filter: Option, + warning_filter: Option, ) -> anyhow::Result { let mut env = GlobalEnv::new(); env.set_extension(options); @@ -235,7 +235,10 @@ pub fn run_model_builder_with_options_and_compilation_flags< // Step 3: selective compilation. let expansion_ast = { - let E::Program { modules } = expansion_ast; + let E::Program { + warning_filters_table, + modules, + } = expansion_ast; let modules = modules.filter_map(|mident, mut mdef| { visited_modules.contains(&mident.value).then(|| { mdef.target_kind = TargetKind::Source { @@ -244,10 +247,17 @@ pub fn run_model_builder_with_options_and_compilation_flags< mdef }) }); - E::Program { modules } + E::Program { + warning_filters_table, + modules, + } }; let typing_ast = { - let T::Program { info, modules } = typing_ast; + let T::Program { + info, + warning_filters_table, + modules, + } = typing_ast; let modules = modules.filter_map(|mident, mut mdef| { visited_modules.contains(&mident.value).then(|| { mdef.target_kind = TargetKind::Source { @@ -256,7 +266,11 @@ pub fn run_model_builder_with_options_and_compilation_flags< mdef }) }); - T::Program { info, modules } + T::Program { + info, + warning_filters_table, + modules, + } }; // Run the compiler fully to the compiled units diff --git a/external-crates/move/crates/move-model/src/model.rs b/external-crates/move/crates/move-model/src/model.rs index b66d0bef83a..c6cf21f4062 100644 --- a/external-crates/move/crates/move-model/src/model.rs +++ b/external-crates/move/crates/move-model/src/model.rs @@ -31,13 +31,14 @@ use std::{ use codespan::{ByteIndex, ByteOffset, ColumnOffset, FileId, Files, LineOffset, Location, Span}; use codespan_reporting::{ diagnostic::{Diagnostic, Label, Severity}, - term::{emit, termcolor::WriteColor, Config}, + term::{Config, emit, termcolor::WriteColor}, }; use itertools::Itertools; #[allow(unused_imports)] use log::{info, warn}; pub use move_binary_format::file_format::{AbilitySet, Visibility as FunctionVisibility}; use move_binary_format::{ + CompiledModule, file_format::{ AddressIdentifierIndex, Bytecode, Constant as VMConstant, ConstantPoolIndex, DatatypeHandleIndex, EnumDefinitionIndex, FunctionDefinition, FunctionDefinitionIndex, @@ -45,14 +46,14 @@ use move_binary_format::{ StructDefinitionIndex, StructFieldInformation, VariantJumpTable, Visibility, }, normalized::{FunctionRef, Type as MType}, - CompiledModule, }; use move_bytecode_source_map::{mapping::SourceMapping, source_map::SourceMap}; -use move_command_line_common::{address::NumericalAddress, files::FileHash}; +use move_command_line_common::files::FileHash; use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, language_storage, + parsing::address::NumericalAddress, runtime_value::MoveValue, }; use move_disassembler::disassembler::{Disassembler, DisassemblerOptions}; @@ -965,12 +966,14 @@ impl GlobalEnv { loc: Loc, typ: Type, value: Value, + attributes: Vec, ) -> NamedConstantData { NamedConstantData { name, loc, typ, value, + attributes, } } @@ -1074,15 +1077,12 @@ impl GlobalEnv { None => Loc::default(), Some(smap) => self.to_loc(&smap.variants[tag].0.1), }; - variant_data.insert( - VariantId(variant_name), - VariantData { - name: variant_name, - loc, - tag, - field_data, - }, - ); + variant_data.insert(VariantId(variant_name), VariantData { + name: variant_name, + loc, + tag, + field_data, + }); } EnumData { @@ -2177,6 +2177,7 @@ impl<'env> ModuleEnv<'env> { print_code: true, print_basic_blocks: true, print_locals: true, + max_output_size: None, }, ); disas @@ -3056,6 +3057,9 @@ pub struct NamedConstantData { /// The value of this constant value: Value, + + /// Attributes attached to this constant + attributes: Vec, } #[derive(Debug)] @@ -3096,6 +3100,11 @@ impl<'env> NamedConstantEnv<'env> { pub fn get_value(&self) -> Value { self.data.value.clone() } + + /// Returns the attributes attached to this constant + pub fn get_attributes(&self) -> &[Attribute] { + &self.data.attributes + } } // ================================================================================================= @@ -3721,11 +3730,10 @@ impl<'env> FunctionEnv<'env> { type_parameters, } = module.function_instantiation_at(*fi_idx); let f_ref = FunctionRef::from_idx(module, handle); - if is_framework_function( - &f_ref, - "transfer", - vec!["share_object", "public_share_object"], - ) { + if is_framework_function(&f_ref, "transfer", vec![ + "share_object", + "public_share_object", + ]) { let type_params = module.signature_at(*type_parameters); shared.insert(self.module_env.globalize_signature(&type_params.0[0])); } @@ -3757,11 +3765,10 @@ impl<'env> FunctionEnv<'env> { type_parameters, } = module.function_instantiation_at(*fi_idx); let f_ref = FunctionRef::from_idx(module, handle); - if is_framework_function( - &f_ref, + if is_framework_function(&f_ref, "transfer", vec![ "transfer", - vec!["transfer", "public_transfer"], - ) { + "public_transfer", + ]) { let type_params = module.signature_at(*type_parameters); transferred.insert(self.module_env.globalize_signature(&type_params.0[0])); } @@ -3793,11 +3800,10 @@ impl<'env> FunctionEnv<'env> { type_parameters, } = module.function_instantiation_at(*fi_idx); let f_ref = FunctionRef::from_idx(module, handle); - if is_framework_function( - &f_ref, - "transfer", - vec!["freeze_object", "public_freeze_object"], - ) { + if is_framework_function(&f_ref, "transfer", vec![ + "freeze_object", + "public_freeze_object", + ]) { let type_params = module.signature_at(*type_parameters); frozen.insert(self.module_env.globalize_signature(&type_params.0[0])); } diff --git a/external-crates/move/crates/move-model/src/ty.rs b/external-crates/move/crates/move-model/src/ty.rs index fade724e6a9..f0be05c4626 100644 --- a/external-crates/move/crates/move-model/src/ty.rs +++ b/external-crates/move/crates/move-model/src/ty.rs @@ -1006,6 +1006,9 @@ impl TypeInstantiationDerivation { /// But in anyway, these type parameters no longer participate in type /// unification anymore. /// + /// But in anyway, these type parameters no longer participate in type + /// unification anymore. + /// /// If `target_lhs` is True, derive instantiations for the type parameter /// with `target_param_index` on the `lhs_types`. Otherwise, target the /// `rhs_types`. @@ -1075,6 +1078,9 @@ impl TypeInstantiationDerivation { /// The process continues until all type parameters are analyzed (i.e., /// reaching the type parameter at index `N`). /// + /// The process continues until all type parameters are analyzed (i.e., + /// reaching the type parameter at index `N`). + /// /// If `refine_lhs` is True, refine the `lhs_types` after each round; same /// for `refine_rhs`. /// diff --git a/external-crates/move/crates/move-model/tests/testsuite.rs b/external-crates/move/crates/move-model/tests/testsuite.rs index 07ecaeb67c9..02fd1d2040c 100644 --- a/external-crates/move/crates/move-model/tests/testsuite.rs +++ b/external-crates/move/crates/move-model/tests/testsuite.rs @@ -8,7 +8,7 @@ use std::path::Path; use codespan_reporting::{diagnostic::Severity, term::termcolor::Buffer}; use move_binary_format::file_format::{FunctionDefinitionIndex, StructDefinitionIndex}; use move_command_line_common::testing::EXP_EXT; -use move_compiler::{diagnostics::WarningFilters, shared::PackagePaths}; +use move_compiler::{diagnostics::warning_filters::WarningFiltersBuilder, shared::PackagePaths}; use move_model::{run_bytecode_model_builder, run_model_builder}; use move_prover_test_utils::baseline_test::verify_or_update_baseline; @@ -21,7 +21,7 @@ fn test_runner(path: &Path) -> datatest_stable::Result<()> { let env = run_model_builder( targets, vec![], - Some(WarningFilters::unused_warnings_filter_for_test()), + Some(WarningFiltersBuilder::unused_warnings_filter_for_test()), )?; let diags = if env.diag_count(Severity::Warning) > 0 { let mut writer = Buffer::no_color(); diff --git a/external-crates/move/crates/move-package/src/compilation/compiled_package.rs b/external-crates/move/crates/move-package/src/compilation/compiled_package.rs index c39c3394c96..0529e65c926 100644 --- a/external-crates/move/crates/move-package/src/compilation/compiled_package.rs +++ b/external-crates/move/crates/move-package/src/compilation/compiled_package.rs @@ -9,23 +9,23 @@ use std::{ path::{Path, PathBuf}, }; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; use colored::Colorize; use itertools::{Either, Itertools}; use move_binary_format::file_format::CompiledModule; -use move_bytecode_source_map::utils::source_map_from_file; +use move_bytecode_source_map::utils::{serialize_to_json, source_map_from_file}; use move_bytecode_utils::Modules; use move_command_line_common::files::{ - extension_equals, find_filenames, try_exists, MOVE_COMPILED_EXTENSION, MOVE_EXTENSION, - SOURCE_MAP_EXTENSION, + MOVE_COMPILED_EXTENSION, MOVE_EXTENSION, SOURCE_MAP_EXTENSION, extension_equals, + find_filenames, try_exists, }; use move_compiler::{ + Compiler, compiled_unit::{AnnotatedCompiledUnit, CompiledUnit, NamedCompiledModule}, editions::Flavor, iota_mode::{self}, linters, - shared::{files::MappedFiles, NamedAddressMap, NumericalAddress, PackageConfig, PackagePaths}, - Compiler, + shared::{NamedAddressMap, NumericalAddress, PackageConfig, PackagePaths, files::MappedFiles}, }; use move_docgen::{Docgen, DocgenOptions}; use move_model::{model::GlobalEnv, options::ModelBuilderOptions, run_model_builder_with_options}; @@ -34,13 +34,13 @@ use serde::{Deserialize, Serialize}; use vfs::VfsPath; use crate::{ + BuildConfig, compilation::package_layout::CompiledPackageLayout, resolution::resolution_graph::{Package, Renaming, ResolvedGraph, ResolvedTable}, source_package::{ - layout::{SourcePackageLayout, REFERENCE_TEMPLATE_FILENAME}, + layout::{REFERENCE_TEMPLATE_FILENAME, SourcePackageLayout}, parsed_manifest::{FileName, PackageDigest, PackageName}, }, - BuildConfig, }; #[derive(Debug, Clone)] @@ -329,6 +329,13 @@ impl OnDiskCompiledPackage { .with_extension(SOURCE_MAP_EXTENSION), compiled_unit.unit.serialize_source_map().as_slice(), )?; + self.save_under( + CompiledPackageLayout::SourceMaps + .path() + .join(&file_path) + .with_extension("json"), + &serialize_to_json(&compiled_unit.unit.source_map)?, + )?; self.save_under( CompiledPackageLayout::Sources .path() diff --git a/external-crates/move/crates/move-package/src/lock_file/schema.rs b/external-crates/move/crates/move-package/src/lock_file/schema.rs index 59a2d5a9041..98724498d67 100644 --- a/external-crates/move/crates/move-package/src/lock_file/schema.rs +++ b/external-crates/move/crates/move-package/src/lock_file/schema.rs @@ -12,7 +12,7 @@ use std::{ io::{Read, Seek, Write}, }; -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{Context, Result, anyhow, bail}; use move_compiler::editions::{Edition, Flavor}; use serde::{Deserialize, Serialize}; use tempfile::NamedTempFile; @@ -33,7 +33,9 @@ use super::LockFile; /// V0: Base version. /// V1: Adds toolchain versioning support. /// V2: Adds support for managing addresses on package publish and upgrades. -pub const VERSION: u64 = 2; +/// V3: Renames dependency `name` field to `id` and adds a `name` field to store +/// the name from the manifest. +pub const VERSION: u16 = 3; /// Table for storing package info under an environment. const ENV_TABLE_NAME: &str = "env"; @@ -58,9 +60,8 @@ pub struct Packages { #[derive(Deserialize)] pub struct Package { - /// The name of the package (corresponds to the name field from its source - /// manifest). - pub name: String, + /// Package identifier (as resolved by the package hook). + pub id: String, /// Where to find this dependency. Schema is not described in terms of /// serde-compatible structs, so it is deserialized into a generic data @@ -77,6 +78,9 @@ pub struct Package { #[derive(Deserialize)] pub struct Dependency { + /// Package identifier (as resolved by the package hook). + pub id: String, + /// The name of the dependency (corresponds to the key for the dependency in /// the depending package's source manifest). pub name: String, @@ -115,7 +119,7 @@ pub struct ManagedPackage { #[derive(Serialize, Deserialize)] pub struct Header { - pub version: u64, + pub version: u16, /// A hash of the manifest file content this lock file was generated from /// computed using SHA-256 hashing algorithm. pub manifest_digest: String, @@ -207,9 +211,9 @@ impl Header { let Schema { move_: header } = toml::de::from_str::>(contents).context("Deserializing lock header")?; - if header.version > VERSION { + if header.version != VERSION { bail!( - "Lock file format is too new, expected version {} or below, found {}", + "Lock file format mismatch, expected version {}, found {}", VERSION, header.version ); @@ -260,7 +264,9 @@ pub fn update_dependency_graph( .as_table_mut() .ok_or_else(|| anyhow!("Could not find or create move table in Move.lock"))?; - // Update `manifest_digest` and `deps_digest` in `[move]` table section. + // Update `version`, `manifest_digest`, and `deps_digest` in `[move]` table + // section. + move_table["version"] = value(VERSION as i64); move_table["manifest_digest"] = value(manifest_digest); move_table["deps_digest"] = value(deps_digest); @@ -354,11 +360,11 @@ pub enum ManagedAddressUpdate { }, } -/// Sets the `original-published-id` to a given `id` in the lock file. This is a raw utility -/// for preparing package publishing and package upgrades. Invariant: callers maintain a valid -/// hex `id`. +/// Sets the `original-published-id` to a given `id` in the lock file. This is a +/// raw utility for preparing package publishing and package upgrades. +/// Invariant: callers maintain a valid hex `id`. pub fn set_original_id(file: &mut LockFile, environment: &str, id: &str) -> Result<()> { - use toml_edit::{value, Document}; + use toml_edit::{Document, value}; let mut toml_string = String::new(); file.read_to_string(&mut toml_string)?; let mut toml = toml_string.parse::()?; @@ -385,7 +391,7 @@ pub fn update_managed_address( environment: &str, managed_address_update: ManagedAddressUpdate, ) -> Result<()> { - use toml_edit::{value, Document, Table}; + use toml_edit::{Document, Table, value}; let mut toml_string = String::new(); file.read_to_string(&mut toml_string)?; diff --git a/external-crates/move/crates/move-package/src/migration/mod.rs b/external-crates/move/crates/move-package/src/migration/mod.rs index b158cff51a8..aa84b67cc56 100644 --- a/external-crates/move/crates/move-package/src/migration/mod.rs +++ b/external-crates/move/crates/move-package/src/migration/mod.rs @@ -20,7 +20,7 @@ pub const EDITION_SELECT_PROMPT: &str = "Please select one of the following edit pub static EDITION_OPTIONS: Lazy> = Lazy::new(|| { let mut map = BTreeMap::new(); - map.insert("1".to_string(), Edition::E2024_BETA); + map.insert("1".to_string(), Edition::E2024); map.insert("2".to_string(), Edition::LEGACY); map }); @@ -95,7 +95,7 @@ impl<'a, W: Write, R: BufRead> MigrationContext<'a, W, R> { self.terminal.writeln(EDITION_RECORDED_MSG)?; self.terminal.newline()?; } - Edition::E2024_BETA => { + Edition::E2024 => { self.terminal.newline()?; self.terminal.newline()?; self.perform_upgrade()?; diff --git a/external-crates/move/crates/move-package/src/package_hooks.rs b/external-crates/move/crates/move-package/src/package_hooks.rs index efa304f562d..f3f33b9daca 100644 --- a/external-crates/move/crates/move-package/src/package_hooks.rs +++ b/external-crates/move/crates/move-package/src/package_hooks.rs @@ -8,7 +8,7 @@ use anyhow::bail; use move_symbol_pool::Symbol; use once_cell::sync::Lazy; -use crate::source_package::parsed_manifest::{CustomDepInfo, SourceManifest}; +use crate::source_package::parsed_manifest::{OnChainInfo, SourceManifest}; pub type PackageIdentifier = Symbol; @@ -20,17 +20,13 @@ pub trait PackageHooks { /// Returns custom fields allowed in `PackageInfo`. fn custom_package_info_fields(&self) -> Vec; - /// Returns a custom key for dependencies, if available. This is the string - /// used in dependencies `{ = value, address = addr }`. - fn custom_dependency_key(&self) -> Option; - - /// A resolver for custom dependencies in the manifest. This is called to + /// A resolver for on-chain dependencies in the manifest. This is called to /// download the dependency from the dependency into the /// `info.local_path` location, similar as with git dependencies. - fn resolve_custom_dependency( + fn resolve_on_chain_dependency( &self, dep_name: Symbol, - info: &CustomDepInfo, + info: &OnChainInfo, ) -> anyhow::Result<()>; fn custom_resolve_pkg_id(&self, manifest: &SourceManifest) @@ -48,22 +44,14 @@ pub fn register_package_hooks(hooks: Box) { /// Calls any registered hook to resolve a node dependency. Bails if none is /// registered. -pub(crate) fn resolve_custom_dependency( +pub(crate) fn resolve_on_chain_dependency( dep_name: Symbol, - info: &CustomDepInfo, + info: &OnChainInfo, ) -> anyhow::Result<()> { if let Some(hooks) = &*HOOKS.lock().unwrap() { - hooks.resolve_custom_dependency(dep_name, info) - } else { - bail!("use of unsupported custom dependency in package manifest") - } -} - -pub(crate) fn custom_dependency_key() -> Option { - if let Some(hooks) = &*HOOKS.lock().unwrap() { - hooks.custom_dependency_key() + hooks.resolve_on_chain_dependency(dep_name, info) } else { - None + bail!("use of unsupported on-chain dependency in package manifest") } } diff --git a/external-crates/move/crates/move-package/src/resolution/dependency_cache.rs b/external-crates/move/crates/move-package/src/resolution/dependency_cache.rs index 3190a1c3e31..824a4af8dd7 100644 --- a/external-crates/move/crates/move-package/src/resolution/dependency_cache.rs +++ b/external-crates/move/crates/move-package/src/resolution/dependency_cache.rs @@ -49,12 +49,12 @@ impl DependencyCache { match kind { DependencyKind::Local(_) => Ok(()), - DependencyKind::Custom(node_info) => { + DependencyKind::OnChain(info) => { // check if a give dependency type has already been fetched if !self.fetched_deps.insert(repository_path(kind)) { return Ok(()); } - package_hooks::resolve_custom_dependency(dep_name, node_info) + package_hooks::resolve_on_chain_dependency(dep_name, info) } DependencyKind::Git(GitInfo { @@ -67,6 +67,12 @@ impl DependencyCache { if !self.fetched_deps.insert(repository_path.clone()) { return Ok(()); } + + if Command::new("git").arg("--version").output().is_err() { + writeln!(progress_output, "Git is not installed or not in the PATH.")?; + return Err(anyhow::anyhow!("Git is not installed or not in the PATH.")); + } + let git_path = repository_path; let os_git_url = OsStr::new(git_url.as_str()); let os_git_rev = OsStr::new(git_rev.as_str()); @@ -79,15 +85,25 @@ impl DependencyCache { git_url, )?; // If the cached folder does not exist, download and clone accordingly - Command::new("git") + if let Ok(mut output) = Command::new("git") .args([OsStr::new("clone"), os_git_url, git_path.as_os_str()]) - .output() - .map_err(|_| { + .spawn() + { + output.wait().map_err(|_| { anyhow::anyhow!( "Failed to clone Git repository for package '{}'", dep_name ) })?; + if output.stdout.is_some() { + writeln!(progress_output, "{:?}", output)?; + } + } else { + return Err(anyhow::anyhow!( + "Failed to clone Git repository for package '{}'", + dep_name + )); + } Command::new("git") .args([ @@ -160,31 +176,31 @@ impl DependencyCache { // // NOTE: this means that you must run the package system with a working network // connection. - let status = Command::new("git") + + if let Ok(mut output) = Command::new("git") .args([ OsStr::new("-C"), git_path.as_os_str(), OsStr::new("fetch"), OsStr::new("origin"), ]) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map_err(|_| { + .spawn() + { + output.wait().map_err(|_| { anyhow::anyhow!( "Failed to fetch latest Git state for package '{}', to skip set \ --skip-fetch-latest-git-deps", dep_name ) })?; - - if !status.success() { + if output.stdout.is_some() { + writeln!(progress_output, "{:?}", output)?; + } + } else { return Err(anyhow::anyhow!( - "Failed to fetch to latest Git state for package '{}', to skip set \ - --skip-fetch-latest-git-deps | Exit status: {}", - dep_name, - status + "Failed to fetch latest Git state for package '{}', to skip set \ + --skip-fetch-latest-git-deps", + dep_name )); } diff --git a/external-crates/move/crates/move-package/src/resolution/dependency_graph.rs b/external-crates/move/crates/move-package/src/resolution/dependency_graph.rs index 30aaa1d584b..eca46d6e6ab 100644 --- a/external-crates/move/crates/move-package/src/resolution/dependency_graph.rs +++ b/external-crates/move/crates/move-package/src/resolution/dependency_graph.rs @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 use std::{ - collections::{btree_map::Entry, BTreeMap, BTreeSet, VecDeque}, + collections::{BTreeMap, BTreeSet, VecDeque, btree_map::Entry}, fmt, fs::File, - io::{Read, Write}, + io::{BufRead, BufReader, Read, Write}, path::{Path, PathBuf}, process::Command, }; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use colored::Colorize; use move_symbol_pool::Symbol; -use petgraph::{algo, prelude::DiGraphMap, Direction}; +use petgraph::{Direction, algo, prelude::DiGraphMap}; use super::{ dependency_cache::DependencyCache, @@ -22,8 +22,8 @@ use super::{ local_path, }; use crate::{ - lock_file::{schema, LockFile}, - package_hooks::{self, custom_resolve_pkg_id, resolve_version, PackageIdentifier}, + lock_file::{LockFile, schema}, + package_hooks::{PackageIdentifier, custom_resolve_pkg_id, resolve_version}, source_package::{ layout::SourcePackageLayout, manifest_parser::{ @@ -252,6 +252,8 @@ impl DependencyGraphBuilder { let lock_file = File::open(lock_path); let digest_and_lock_contents = lock_file .map(|mut lock_file| match schema::Header::read(&mut lock_file) { + Ok(header) if header.version < schema::VERSION => None, // outdated lock file - + // regenerate Ok(header) => Some((header.manifest_digest, header.deps_digest, lock_string_opt)), Err(_) => None, // malformed header - regenerate lock file }) @@ -399,8 +401,9 @@ impl DependencyGraphBuilder { let mut resolved_id_deps = BTreeMap::new(); let mut dep_orig_names = BTreeMap::new(); let mut overrides = BTreeMap::new(); + for (dep_pkg_name, dep) in dependencies { - let (pkg_graph, is_override, is_external, resolved_pkg_id, resolved_version) = self + let new_deps = self .new_for_dep( parent, &dep, @@ -416,34 +419,38 @@ impl DependencyGraphBuilder { parent_pkg_name ) })?; - dep_graphs.insert( - resolved_pkg_id, - DependencyGraphInfo::new( - pkg_graph, - mode, - is_override, - is_external, - resolved_version, - ), - ); - resolved_id_deps.insert(resolved_pkg_id, dep.clone()); - dep_orig_names.insert(resolved_pkg_id, dep_pkg_name); - - if is_override { - let kind = match dep { - PM::Dependency::Internal(d) => d.kind, - PM::Dependency::External(_) => { - // external dependencies cannot be overrides - panic!("Unexpected external dependency override") - } - }; - let mut dep_pkg = Package { - kind, - resolver: None, - version: resolved_version, - }; - dep_pkg.kind.reroot(parent)?; - overrides.insert(resolved_pkg_id, dep_pkg); + + for (pkg_graph, is_override, is_external, resolved_pkg_id, resolved_version) in new_deps + { + dep_graphs.insert( + resolved_pkg_id, + DependencyGraphInfo::new( + pkg_graph, + mode, + is_override, + is_external, + resolved_version, + ), + ); + resolved_id_deps.insert(resolved_pkg_id, dep.clone()); + dep_orig_names.insert(resolved_pkg_id, dep_pkg_name); + + if is_override { + let kind = match dep { + PM::Dependency::Internal(ref d) => d.kind.clone(), + PM::Dependency::External(_) => { + // external dependencies cannot be overrides + panic!("Unexpected external dependency override") + } + }; + let mut dep_pkg = Package { + kind, + resolver: None, + version: resolved_version, + }; + dep_pkg.kind.reroot(parent)?; + overrides.insert(resolved_pkg_id, dep_pkg); + } } } Ok((dep_graphs, resolved_id_deps, dep_orig_names, overrides)) @@ -460,8 +467,8 @@ impl DependencyGraphBuilder { parent_pkg_name: PM::PackageName, dep_pkg_name: PM::PackageName, dep_pkg_path: PathBuf, - ) -> Result<(DependencyGraph, bool, bool, Symbol, Option)> { - let (pkg_graph, is_override, is_external, resolved_pkg_name, resolved_version) = match dep { + ) -> Result)>> { + match dep { PM::Dependency::Internal(d) => { self.dependency_cache .download_and_update_if_remote(dep_pkg_name, &d.kind, &mut self.progress_output) @@ -506,16 +513,16 @@ impl DependencyGraphBuilder { p.kind.reroot(&d.kind)?; } } - ( + Ok(vec![( pkg_graph, d.dep_override, false, resolved_pkg_id, resolved_version, - ) + )]) } PM::Dependency::External(resolver) => { - let pkg_graph = DependencyGraph::get_external( + let external_deps = DependencyGraph::get_external( mode, parent_pkg_id, parent_pkg_name, @@ -524,18 +531,21 @@ impl DependencyGraphBuilder { &dep_pkg_path, &mut self.progress_output, )?; - // TODO: support resolved_pkg_name and resolved_version for - // externally resolved deps. - (pkg_graph, false, true, dep_pkg_name, None) + + Ok(external_deps + .into_iter() + .map(|(pkg_graph, _, resolved_pkg_id, resolved_pkg_version)| { + ( + pkg_graph, + false, + true, + resolved_pkg_id, + resolved_pkg_version, + ) + }) + .collect()) } - }; - Ok(( - pkg_graph, - is_override, - is_external, - resolved_pkg_name, - resolved_version, - )) + } } /// Computes dependency hashes. @@ -977,23 +987,19 @@ impl DependencyGraph { pkg.kind.reroot(parent)?; entry.insert(pkg); } - self.package_graph.add_edge( - self.root_package_id, - dep_pkg_id, - Dependency { + self.package_graph + .add_edge(self.root_package_id, dep_pkg_id, Dependency { mode, subst: subst.clone(), digest: *digest, dep_override: *dep_override, dep_name, - }, - ); + }); Ok(true) } PM::Dependency::External(_) => { - // the way that external graphs are constructed, edges between the (root) - // package of the outer graph and dependencies in the sub-graph - // are already present in the sub-graph + // External dependencies exist in the subgraph of the root package and are added + // to the package_graph as such. let d = sub_graph .package_graph .edge_weight(self.root_package_id, dep_pkg_id) @@ -1101,39 +1107,41 @@ impl DependencyGraph { package_graph.add_node(root_package_id); for schema::Dependency { - name, + id: dep_id, + name: dep_name, subst, digest, } in packages.root_dependencies.into_iter().flatten() { package_graph.add_edge( root_package_id, - Symbol::from(name.as_str()), + PackageIdentifier::from(dep_id.as_str()), Dependency { mode: DependencyMode::Always, subst: subst.map(parse_substitution).transpose()?, digest: digest.map(Symbol::from), dep_override: false, - dep_name: PM::PackageName::from(name), + dep_name: PM::PackageName::from(dep_name), }, ); } for schema::Dependency { - name, + id: dep_id, + name: dep_name, subst, digest, } in packages.root_dev_dependencies.into_iter().flatten() { package_graph.add_edge( root_package_id, - Symbol::from(name.as_str()), + PackageIdentifier::from(dep_id.as_str()), Dependency { mode: DependencyMode::DevOnly, subst: subst.map(parse_substitution).transpose()?, digest: digest.map(Symbol::from), dep_override: false, - dep_name: PM::PackageName::from(name.as_str()), + dep_name: PM::PackageName::from(dep_name), }, ); } @@ -1141,30 +1149,30 @@ impl DependencyGraph { // Fill in the remaining dependencies, and the package source information from // the lock file. for schema::Package { - name: pkg_name, + id: pkg_id, source, version, dependencies, dev_dependencies, } in packages.packages.into_iter().flatten() { - let pkg_name = PM::PackageName::from(pkg_name.as_str()); - let source = parse_dependency(pkg_name.as_str(), source) - .with_context(|| format!("Deserializing dependency '{pkg_name}'"))?; + let pkg_id = PackageIdentifier::from(pkg_id.as_str()); + let source = parse_dependency(source) + .with_context(|| format!("Deserializing dependency '{pkg_id}'"))?; let source = match source { PM::Dependency::Internal(source) => source, PM::Dependency::External(resolver) => { - bail!("Unexpected dependency '{pkg_name}' resolved externally by '{resolver}'"); + bail!("Unexpected dependency '{pkg_id}' resolved externally by '{resolver}'"); } }; if source.subst.is_some() { - bail!("Unexpected 'addr_subst' in source for '{pkg_name}'") + bail!("Unexpected 'addr_subst' in source for '{pkg_id}'") } if source.digest.is_some() { - bail!("Unexpected 'digest' in source for '{pkg_name}'") + bail!("Unexpected 'digest' in source for '{pkg_id}'") } let pkg = Package { @@ -1173,7 +1181,7 @@ impl DependencyGraph { version: version.map(Symbol::from), }; - match package_table.entry(pkg_name) { + match package_table.entry(pkg_id) { Entry::Vacant(entry) => { entry.insert(pkg); } @@ -1183,7 +1191,7 @@ impl DependencyGraph { Entry::Occupied(entry) => { bail!( "Conflicting dependencies found:\n{0} = {1}\n{0} = {2}", - pkg_name, + pkg_id, PackageWithResolverTOML(entry.get()), PackageWithResolverTOML(&pkg), ); @@ -1191,14 +1199,15 @@ impl DependencyGraph { }; for schema::Dependency { + id: dep_id, name: dep_name, subst, digest, } in dependencies.into_iter().flatten() { package_graph.add_edge( - pkg_name, - PM::PackageName::from(dep_name.as_str()), + pkg_id, + PackageIdentifier::from(dep_id.as_str()), Dependency { mode: DependencyMode::Always, subst: subst.map(parse_substitution).transpose()?, @@ -1210,14 +1219,15 @@ impl DependencyGraph { } for schema::Dependency { + id: dep_id, name: dep_name, subst, digest, } in dev_dependencies.into_iter().flatten() { package_graph.add_edge( - pkg_name, - PM::PackageName::from(dep_name.as_str()), + pkg_id, + PackageIdentifier::from(dep_id.as_str()), Dependency { mode: DependencyMode::DevOnly, subst: subst.map(parse_substitution).transpose()?, @@ -1269,7 +1279,7 @@ impl DependencyGraph { for (id, pkg) in &self.package_table { writeln!(writer, "\n[[move.package]]")?; - writeln!(writer, "name = {}", str_escape(id.as_str()))?; + writeln!(writer, "id = {}", str_escape(id.as_str()))?; writeln!(writer, "source = {}", PackageTOML(pkg))?; if let Some(version) = &pkg.version { writeln!(writer, "version = {}", str_escape(version.as_str()))?; @@ -1390,14 +1400,18 @@ impl DependencyGraph { .map(|(_, dep_name, dep)| (dep_name, dep, &self.package_table[&dep_name])) } - /// Resolves the packages described at dependency `to` of package `from` - /// with manifest at path `package_path` by running the binary - /// `resolver. `mode` decides whether the resulting packages are added - /// to `self` as dependencies of `package_name` or dev-dependencies. + /// Resolves the packages described at dependency `to` the dependency + /// specified by`from` with manifest at path `package_path` by running + /// the binary `resolver`. `mode` decides whether the resulting packages + /// are added to `self` as dependencies of `package_name` or + /// dev-dependencies. /// /// Sends progress updates to `progress_output`, including stderr from the - /// resolver, and captures stdout, which is assumed to be a lock file - /// containing the result of package resolution. + /// resolver, and captures stdout. The output is expected to be one or + /// more null-separated string content. Each string is interpreted as a + /// dependency graph, as represented by the Move.lock TOML schema. It + /// returns each subgraph to be merged into the whole program dependency + /// graph. fn get_external( mode: DependencyMode, from_id: PackageIdentifier, @@ -1406,7 +1420,14 @@ impl DependencyGraph { resolver: Symbol, package_path: &Path, progress_output: &mut Progress, - ) -> Result { + ) -> Result< + Vec<( + DependencyGraph, + PM::Dependency, + PM::PackageName, + Option, // version + )>, + > { let mode_label = if mode == DependencyMode::DevOnly { "dev-dependencies" } else { @@ -1425,6 +1446,8 @@ impl DependencyGraph { )?; // Call out to the external resolver + // TODO(optimization): this will collect all stdout in memory, but can be + // streamed instead. let output = Command::new(resolver.as_str()) .arg(format!("--resolve-move-{mode_label}")) .arg(to_name.as_str()) @@ -1452,20 +1475,61 @@ impl DependencyGraph { } } - let sub_graph = DependencyGraph::read_from_lock( - package_path.to_path_buf(), - from_id, - from_name, - &mut output.stdout.as_slice(), - Some(resolver), - ) - .with_context(|| { - format!( - "Parsing response from '{resolver}' for dependency '{to_name}' of package '{from_id}'" - ) - })?; + let mut result = Vec::new(); + let mut reader = BufReader::new(output.stdout.as_slice()); + let mut buffer = Vec::new(); + // Loop over null-separated lock file contents, creating the graph and adding it + // to the result. + loop { + match reader.read_until(0, &mut buffer) { + Ok(0) => break, // EOF + Ok(_) => { + // Remove the null byte if it's present + if buffer.last() == Some(&0) { + buffer.pop(); + } - Ok(sub_graph) + let sub_graph = DependencyGraph::read_from_lock( + package_path.to_path_buf(), + from_id, + from_name, + &mut buffer.as_slice(), + Some(resolver), + ).with_context(|| { + format!("Parsing response from '{resolver}' for dependency '{to_name}' of package '{from_id}'") + })?; + + let root_sub_package_id = match sub_graph + .package_graph + .edges(from_id) + .collect::>() + .as_slice() + { + [(_, id, _)] => *id, + // TODO: We can in fact allow allow multiple root packages / graphs and + // relax this constraint. + _ => bail!("Expected a single root dependency but none or multiple found"), + }; + let root_sub_package_version = sub_graph + .package_table + .get(&root_sub_package_id) + .unwrap() + .version; + + let new_dep = PM::Dependency::External(root_sub_package_id); + result.push(( + sub_graph, + new_dep, + root_sub_package_id, + root_sub_package_version, + )); + buffer.clear(); + } + Err(e) => return Err(e.into()), + } + } + + Ok(result) } /// Checks that every dependency in the graph, excluding the root package, @@ -1561,23 +1625,9 @@ impl fmt::Display for Package { f.write_str(&path_escape(subdir)?)?; } - PM::DependencyKind::Custom(PM::CustomDepInfo { - node_url, - package_address, - subdir, - package_name: _, - }) => { - let custom_key = package_hooks::custom_dependency_key().ok_or(fmt::Error)?; - - f.write_str(&custom_key)?; - write!(f, " = ")?; - f.write_str(&str_escape(node_url.as_str()))?; - - write!(f, ", address = ")?; - f.write_str(&str_escape(package_address.as_str()))?; - - write!(f, ", subdir = ")?; - f.write_str(&path_escape(subdir)?)?; + PM::DependencyKind::OnChain(PM::OnChainInfo { id }) => { + write!(f, "id = ")?; + f.write_str(&str_escape(id.as_str()))?; } } @@ -1609,20 +1659,23 @@ impl<'a> fmt::Display for PackageWithResolverTOML<'a> { impl<'a> fmt::Display for DependencyTOML<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let DependencyTOML( - name, + id, Dependency { mode: _, subst, digest, dep_override: _, - dep_name: _, + dep_name, }, ) = self; f.write_str("{ ")?; - write!(f, "name = ")?; - f.write_str(&str_escape(name.as_str()))?; + write!(f, "id = ")?; + f.write_str(&str_escape(id.as_str()))?; + + write!(f, ", name = ")?; + f.write_str(&str_escape(dep_name.as_str()))?; if let Some(digest) = digest { write!(f, ", digest = ")?; diff --git a/external-crates/move/crates/move-package/src/resolution/mod.rs b/external-crates/move/crates/move-package/src/resolution/mod.rs index 753b7d4bab0..d8c5b05eb83 100644 --- a/external-crates/move/crates/move-package/src/resolution/mod.rs +++ b/external-crates/move/crates/move-package/src/resolution/mod.rs @@ -13,7 +13,7 @@ use move_command_line_common::env::MOVE_HOME; use self::dependency_graph::DependencyGraphBuilder; use crate::{ - source_package::parsed_manifest::{CustomDepInfo, DependencyKind, GitInfo}, + source_package::parsed_manifest::{DependencyKind, GitInfo, OnChainInfo}, BuildConfig, }; @@ -94,23 +94,12 @@ fn repository_path(kind: &DependencyKind) -> PathBuf { .iter() .collect(), - // Downloaded packages are of the form _
_ - DependencyKind::Custom(CustomDepInfo { - node_url, - package_address, - package_name, - subdir: _, - }) => [ - &*MOVE_HOME, - &format!( - "{}_{}_{}", - url_to_file_name(node_url.as_str()), - package_address.as_str(), - package_name.as_str(), - ), - ] - .iter() - .collect(), + // Downloaded packages are of the form + DependencyKind::OnChain(OnChainInfo { id }) => { + [&*MOVE_HOME, &url_to_file_name(id.as_str()).to_string()] + .iter() + .collect() + } } } @@ -119,9 +108,7 @@ fn repository_path(kind: &DependencyKind) -> PathBuf { fn local_path(kind: &DependencyKind) -> PathBuf { let mut repo_path = repository_path(kind); - if let DependencyKind::Git(GitInfo { subdir, .. }) - | DependencyKind::Custom(CustomDepInfo { subdir, .. }) = kind - { + if let DependencyKind::Git(GitInfo { subdir, .. }) = kind { repo_path.push(subdir); } diff --git a/external-crates/move/crates/move-package/src/resolution/resolution_graph.rs b/external-crates/move/crates/move-package/src/resolution/resolution_graph.rs index 26d2f4fcc6c..8a1fabae596 100644 --- a/external-crates/move/crates/move-package/src/resolution/resolution_graph.rs +++ b/external-crates/move/crates/move-package/src/resolution/resolution_graph.rs @@ -9,7 +9,7 @@ use move_command_line_common::files::{ }; use move_compiler::command_line::DEFAULT_OUTPUT_DIR; use move_compiler::editions::Edition; -use move_compiler::{diagnostics::WarningFilters, shared::PackageConfig}; +use move_compiler::{diagnostics::warning_filters::WarningFiltersBuilder, shared::PackageConfig}; use move_core_types::account_address::AccountAddress; use move_symbol_pool::Symbol; use std::fs::File; @@ -128,7 +128,7 @@ impl ResolvedGraph { match dep { PM::Dependency::External(_) => continue, PM::Dependency::Internal(internal) => { - if let PM::DependencyKind::Custom(_) = internal.kind { + if let PM::DependencyKind::OnChain(_) = internal.kind { continue; } let dep_path = &resolved_pkg.package_path.join(local_path(&internal.kind)); @@ -564,6 +564,16 @@ impl Package { .collect()) } + pub fn get_bytecodes_bytes(&self) -> Result>> { + let mut ret = vec![]; + for path in self.get_bytecodes()? { + let bytes = std::fs::read(path.to_string())?; + ret.push(bytes); + } + + Ok(ret) + } + pub(crate) fn compiler_config( &self, is_dependency: bool, @@ -583,7 +593,7 @@ impl Package { .edition .or(config.default_edition) .unwrap_or(Edition::LEGACY), // TODO require edition - warning_filter: WarningFilters::new_for_source(), + warning_filter: WarningFiltersBuilder::new_for_source(), } } } @@ -607,6 +617,9 @@ fn source_paths_for_config(package_path: &Path, config: &BuildConfig) -> Vec Result { diff --git a/external-crates/move/crates/move-package/src/resolution/resolving_table.rs b/external-crates/move/crates/move-package/src/resolution/resolving_table.rs index 857f0e23d98..b9e5abd212f 100644 --- a/external-crates/move/crates/move-package/src/resolution/resolving_table.rs +++ b/external-crates/move/crates/move-package/src/resolution/resolving_table.rs @@ -32,6 +32,12 @@ enum Assignment { Linked(usize), } +impl Default for ResolvingTable { + fn default() -> Self { + Self::new() + } +} + impl ResolvingTable { /// A fresh `ResolvingTable` with no bindings. pub fn new() -> ResolvingTable { diff --git a/external-crates/move/crates/move-package/src/source_package/manifest_parser.rs b/external-crates/move/crates/move-package/src/source_package/manifest_parser.rs index 2af64ae15b4..64f18a4cc95 100644 --- a/external-crates/move/crates/move-package/src/source_package/manifest_parser.rs +++ b/external-crates/move/crates/move-package/src/source_package/manifest_parser.rs @@ -27,6 +27,8 @@ const DEV_ADDRESSES_NAME: &str = "dev-addresses"; const DEPENDENCY_NAME: &str = "dependencies"; const DEV_DEPENDENCY_NAME: &str = "dev-dependencies"; +const EXTERNAL_RESOLVER_PREFIX: &str = "r"; + const KNOWN_NAMES: &[&str] = &[ PACKAGE_NAME, BUILD_NAME, @@ -34,6 +36,7 @@ const KNOWN_NAMES: &[&str] = &[ DEV_ADDRESSES_NAME, DEPENDENCY_NAME, DEV_DEPENDENCY_NAME, + EXTERNAL_RESOLVER_PREFIX, ]; const REQUIRED_FIELDS: &[&str] = &[PACKAGE_NAME]; @@ -208,7 +211,7 @@ pub fn parse_dependencies(tval: TV) -> Result { let mut deps = BTreeMap::new(); for (dep_name, dep) in table.into_iter() { let dep_name_ident = PM::PackageName::from(dep_name.clone()); - let dep = parse_dependency(&dep_name, dep)?; + let dep = parse_dependency(dep)?; deps.insert(dep_name_ident, dep); } Ok(deps) @@ -334,27 +337,43 @@ fn parse_address_literal(address_str: &str) -> Result Result { - let Some(table) = tval.as_table_mut() else { - bail!("Malformed dependency {}", tval); +fn parse_external_resolver_name(resolver_val: &TV) -> Result> { + let Some(table) = resolver_val.as_table() else { + bail!("Malformed dependency {}", resolver_val); }; - if let Some(resolver) = table.remove("resolver") { - let Some(resolver) = resolver.as_str().map(Symbol::from) else { - bail!("Resolver name is not a string") - }; + if table.len() != 1 { + bail!("Malformed external resolver declaration for dependency {EXTERNAL_RESOLVER_PREFIX}.{resolver_val}",); + } - // Not relevant except for the external resolver, but remove it to mark it as a - // recognised part of the manifest. - let _ = table.remove("packages"); + let key = table + .keys() + .next() + .expect("Exactly one key by check above") + .as_str(); - // Any fields that are left are unknown - warn_if_unknown_field_names(table, &[]); + let key_value = table.get(key).ok_or_else(|| { + format_err!("Malformed external resolver declaration for dependency {EXTERNAL_RESOLVER_PREFIX}.{resolver_val}",) + })?; - return Ok(PM::Dependency::External(resolver)); + if !key_value.is_str() { + bail!("Malformed external resolver declaration for dependency {EXTERNAL_RESOLVER_PREFIX}.{resolver_val}",); } - let custom_key_opt = &package_hooks::custom_dependency_key(); + Ok(Some(Symbol::from(key))) +} + +pub fn parse_dependency(mut tval: TV) -> Result { + let Some(table) = tval.as_table_mut() else { + bail!("Malformed dependency {}", tval); + }; + + if let Some(external_resolver_binary_name) = table + .get(EXTERNAL_RESOLVER_PREFIX) + .and_then(|e| parse_external_resolver_name(e).transpose()) + { + return Ok(PM::Dependency::External(external_resolver_binary_name?)); + } let subst = table .remove("addr_subst") @@ -371,7 +390,7 @@ pub fn parse_dependency(dep_name: &str, mut tval: TV) -> Result table.remove("local"), table.remove("subdir"), table.remove("git"), - custom_key_opt.as_ref().and_then(|k| table.remove(k)), + table.remove("id"), ) { (Some(local), subdir, None, None) => { if subdir.is_some() { @@ -416,43 +435,16 @@ pub fn parse_dependency(dep_name: &str, mut tval: TV) -> Result }) } - (None, subdir, None, Some(custom_key)) => { - let Some(package_address) = table.remove("address") else { - bail!("Address not supplied for 'node' dependency"); - }; - - let Some(package_address) = package_address.as_str().map(Symbol::from) else { - bail!("Node address not a string") - }; - - let Some(node_url) = custom_key.as_str().map(Symbol::from) else { - bail!("Git URL not a string") - }; - - let subdir = match subdir { - None => PathBuf::new(), - Some(path) => path - .as_str() - .map(PathBuf::from) - .ok_or_else(|| anyhow!("'subdir' not a string"))?, + (None, None, None, Some(id)) => { + let Some(id) = id.as_str().map(Symbol::from) else { + bail!("ID not a string") }; - let package_name = Symbol::from(dep_name); - - PM::DependencyKind::Custom(PM::CustomDepInfo { - node_url, - package_address, - package_name, - subdir, - }) + PM::DependencyKind::OnChain(PM::OnChainInfo { id }) } _ => { - let mut keys = vec!["'local'", "'git'", "'resolver'"]; - let quoted_custom_key = custom_key_opt.as_ref().map(|k| format!("'{}'", k)); - if let Some(k) = "ed_custom_key { - keys.push(k.as_str()) - } + let keys = ["'local'", "'git'", "'r.'"]; bail!( "must provide exactly one of {} for dependency.", keys.join(" or ") @@ -540,7 +532,7 @@ fn parse_dep_override(tval: TV) -> Result { Ok(tval.as_bool().unwrap()) } -// check that only recognized names are provided at the top-level +// Check that only recognized names are provided at the top-level. fn warn_if_unknown_field_names(table: &toml::map::Map, known_names: &[&str]) { let mut unknown_names = BTreeSet::new(); for key in table.keys() { diff --git a/external-crates/move/crates/move-package/src/source_package/parsed_manifest.rs b/external-crates/move/crates/move-package/src/source_package/parsed_manifest.rs index caf37cd2e3b..7ddf3a423c2 100644 --- a/external-crates/move/crates/move-package/src/source_package/parsed_manifest.rs +++ b/external-crates/move/crates/move-package/src/source_package/parsed_manifest.rs @@ -65,7 +65,7 @@ pub struct InternalDependency { pub enum DependencyKind { Local(PathBuf), Git(GitInfo), - Custom(CustomDepInfo), + OnChain(OnChainInfo), } #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] @@ -80,16 +80,8 @@ pub struct GitInfo { } #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] -pub struct CustomDepInfo { - /// The url of the node to download from - pub node_url: Symbol, - /// The address where the package is published. The representation depends - /// on the registered node resolver. - pub package_address: Symbol, - /// The package's name (i.e. the dependency name). - pub package_name: Symbol, - /// The path under this repo where the move package can be found - pub subdir: PathBuf, +pub struct OnChainInfo { + pub id: Symbol, } #[derive(Default, Debug, Clone, Eq, PartialEq)] @@ -120,7 +112,7 @@ impl DependencyKind { // If `self` is a git or custom dependency kind, it does not need to be re-rooted // because its URI is already absolute. (i.e. the location of an absolute URI does not // change if referenced relative to some other URI). - (_, DependencyKind::Git(_) | DependencyKind::Custom(_)) => return Ok(()), + (_, DependencyKind::Git(_) | DependencyKind::OnChain(_)) => return Ok(()), (DependencyKind::Local(parent), DependencyKind::Local(subdir)) => { parent.push(subdir); @@ -132,10 +124,7 @@ impl DependencyKind { git.subdir = normalize_path(&git.subdir, /* allow_cwd_parent */ false)?; } - (DependencyKind::Custom(custom), DependencyKind::Local(subdir)) => { - custom.subdir.push(subdir); - custom.subdir = normalize_path(&custom.subdir, /* allow_cwd_parent */ false)?; - } + (DependencyKind::OnChain(_), _) => return Ok(()), }; *self = parent; diff --git a/external-crates/move/crates/move-package/tests/test_dependency_graph.rs b/external-crates/move/crates/move-package/tests/test_dependency_graph.rs index ac33a10d6f9..6275d5779b6 100644 --- a/external-crates/move/crates/move-package/tests/test_dependency_graph.rs +++ b/external-crates/move/crates/move-package/tests/test_dependency_graph.rs @@ -129,7 +129,11 @@ fn lock_file_missing_dependency() { .expect("Creating new lock file"); // Write a reference to a dependency that there isn't package information for. - writeln!(&*lock, r#"dependencies = [{{ name = "OtherDep" }}]"#).unwrap(); + writeln!( + &*lock, + r#"dependencies = [{{ id = "OtherDep", name = "OtherDep" }}]"# + ) + .unwrap(); lock.commit(&commit).expect("Writing partial lock file"); let Err(err) = DependencyGraph::read_from_lock( @@ -634,61 +638,61 @@ fn dev_dep_test_package() -> PathBuf { const EMPTY_LOCK: &str = r#" [move] -version = 0 +version = 3 manifest_digest = "42" deps_digest = "" "#; const A_LOCK: &str = r#" [move] -version = 0 +version = 3 manifest_digest = "42" deps_digest = "7" dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "./A" } "#; const AB_LOCK: &str = r#" [move] -version = 0 +version = 3 manifest_digest = "42" deps_digest = "7" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "A" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "./A" } [[move.package]] -name = "B" +id = "B" source = { local = "./B" } "#; const A_DEP_B_LOCK: &str = r#" [move] -version = 0 +version = 3 manifest_digest = "42" deps_digest = "7" dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "./A" } dependencies = [ - { name = "B" }, + { id = "B", name = "A" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "./B" } "#; diff --git a/external-crates/move/crates/move-package/tests/test_lock_file.rs b/external-crates/move/crates/move-package/tests/test_lock_file.rs index 25a3f0e6f20..419eb623c14 100644 --- a/external-crates/move/crates/move-package/tests/test_lock_file.rs +++ b/external-crates/move/crates/move-package/tests/test_lock_file.rs @@ -102,16 +102,16 @@ flavor = "iota" # @generated by Move, please check-in and do not edit manually. [move] - version = 1 + version = 3 manifest_digest = "0" deps_digest = "0" dependencies = [ - { name = "Dep" } + { id = "Dep", name = "Dep" } ] [[move.package]] - name = "Dep" + id = "Dep" source = { local = "some/path" } "#; fs::write(lock_path_with_graph.clone(), lock_graph_contents).unwrap(); @@ -141,15 +141,15 @@ flavor = "iota" # @generated by Move, please check-in and do not edit manually. [move] - version = 1 + version = 3 manifest_digest = "0" deps_digest = "0" dependencies = [ - { name = "Dep" }, + { id = "Dep", name = "Dep" }, ] [[move.package]] - name = "Dep" + id = "Dep" source = { local = "some/path" } [move.toolchain-version] diff --git a/external-crates/move/crates/move-package/tests/test_runner.rs b/external-crates/move/crates/move-package/tests/test_runner.rs index 47d8896beab..fb0ff48044a 100644 --- a/external-crates/move/crates/move-package/tests/test_runner.rs +++ b/external-crates/move/crates/move-package/tests/test_runner.rs @@ -20,7 +20,7 @@ use move_package::{ package_hooks, package_hooks::{PackageHooks, PackageIdentifier}, resolution::resolution_graph::Package, - source_package::parsed_manifest::{CustomDepInfo, PackageDigest, SourceManifest}, + source_package::parsed_manifest::{OnChainInfo, PackageDigest, SourceManifest}, BuildConfig, ModelConfig, }; use move_symbol_pool::Symbol; @@ -204,23 +204,12 @@ impl PackageHooks for TestHooks { vec!["test_hooks_field".to_owned(), "version".to_owned()] } - fn custom_dependency_key(&self) -> Option { - Some("custom".to_owned()) - } - - fn resolve_custom_dependency( + fn resolve_on_chain_dependency( &self, dep_name: Symbol, - info: &CustomDepInfo, + info: &OnChainInfo, ) -> anyhow::Result<()> { - bail!( - "TestHooks resolve dep {:?} = {:?} {:?} {:?} {:?}", - dep_name, - info.node_url, - info.package_name, - info.package_address, - info.subdir.to_string_lossy(), - ) + bail!("TestHooks resolve dep {:?} = {:?}", dep_name, info.id,) } fn custom_resolve_pkg_id( diff --git a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/Move.locked index f9e4c5cb2c1..0532d57b759 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/Move.locked @@ -1,6 +1,6 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "919A5B078B47AD46674F36E1605578927D5BC4536A7646D78D1320A25DDD57CC" deps_digest = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" diff --git a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/sources/A.move b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/sources/A.move index 925cbe1fef9..93f3094bd55 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/sources/A.move +++ b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps/sources/A.move @@ -1,3 +1,3 @@ -module 0x1::M { +module 0x6::M { public fun foo() { } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_address_assigned/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_address_assigned/Move.locked index 53a4e43bc8d..1f5b1eca3f5 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_address_assigned/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_address_assigned/Move.locked @@ -1,6 +1,6 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "151286C56FC37AEF93D980A892F558C8EE65FBF062991BDF23C9FC88478D3648" deps_digest = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" diff --git a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/A.move b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/A.move index 925cbe1fef9..93f3094bd55 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/A.move +++ b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/A.move @@ -1,3 +1,3 @@ -module 0x1::M { +module 0x6::M { public fun foo() { } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/ATest.move b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/ATest.move index 63f212d0efd..70c725c733e 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/ATest.move +++ b/external-crates/move/crates/move-package/tests/test_sources/basic_no_deps_test_mode/sources/ATest.move @@ -1,4 +1,4 @@ #[test_only] -module 0x1::MTest { +module 0x6::MTest { public fun foo() { } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/Set.move b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/Set.move index be1b4344598..9c2e23466fb 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/Set.move +++ b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/Set.move @@ -1,3 +1,3 @@ -module 0x1::Set { +module 0x6::Set { public fun foo() { } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/a.move b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/a.move index da5a1b5ec5c..f4ebb20a82c 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/a.move +++ b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/a.move @@ -1 +1 @@ -module 0x1::A { } +module 0x6::A { } diff --git a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/foo.move b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/foo.move index e8c3657afcc..2124b3a3262 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/foo.move +++ b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/foo.move @@ -1,3 +1,3 @@ -module 0x1::set { +module 0x6::set { public fun foo() { } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/otherModule.move b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/otherModule.move index 1e6c517d0c7..57951cd4257 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/otherModule.move +++ b/external-crates/move/crates/move-package/tests/test_sources/case_insensitive_check/sources/otherModule.move @@ -1,2 +1,2 @@ -module 0x2::seT { +module 0x7::seT { } diff --git a/external-crates/move/crates/move-package/tests/test_sources/dep_dev_dep_diamond/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/dep_dev_dep_diamond/Move.locked index c3237740cfe..ef3a0e9ee9c 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/dep_dev_dep_diamond/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/dep_dev_dep_diamond/Move.locked @@ -1,41 +1,41 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "98BBCE8D1C29472825E598691218A0CBC5BDA1A56C4429F5C2311C245DEC28CE" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "C" }, + { id = "A", name = "A" }, + { id = "C", name = "C" }, ] dev-dependencies = [ - { name = "B" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "B" }, + { id = "B", name = "B" }, ] dev-dependencies = [ - { name = "D" }, + { id = "D", name = "D" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dev-dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/dep_good_digest/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/dep_good_digest/Move.locked index 28aa5aadeff..ae2d44821a2 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/dep_good_digest/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/dep_good_digest/Move.locked @@ -1,13 +1,13 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "C6033F8270450BDBC0314A1FDDB201609C2E41579138D1CB4C2D453428A43634" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "OtherDep", digest = "A666AE1AFDBA7E287476E851C0011503D19EE73E89CBDB307D4E0067E8BBA22C", addr_subst = { "A" = "B" } }, + { id = "OtherDep", name = "OtherDep", digest = "A666AE1AFDBA7E287476E851C0011503D19EE73E89CBDB307D4E0067E8BBA22C", addr_subst = { "A" = "B" } }, ] [[move.package]] -name = "OtherDep" +id = "OtherDep" source = { local = "deps_only/other_dep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_backflow_resolution/deps_only/B/sources/AA.move b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_backflow_resolution/deps_only/B/sources/AA.move index 411a75ce7d3..bd117ac2865 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_backflow_resolution/deps_only/B/sources/AA.move +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_backflow_resolution/deps_only/B/sources/AA.move @@ -1,3 +1,3 @@ -module 0x1::AAA { +module 0x6::AAA { public fun foo() {} } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_dev_override_with_reg/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_dev_override_with_reg/Move.locked index 42c70993e34..b0bbb4fd01a 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_dev_override_with_reg/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_dev_override_with_reg/Move.locked @@ -1,33 +1,33 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "CB01A8B6F9859E70A0A5DA10F8547C13EDDD63E9EDF72E930DD37C8EFC41F3F3" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] dev-dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dev-dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dev-dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C-v1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_conflict/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_conflict/Move.toml index 057b0f70d4b..5e1b47bd85e 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_conflict/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_conflict/Move.toml @@ -3,10 +3,4 @@ name = "Root" [dependencies] B = { local = "./deps_only/B" } - -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v1/deps_only/C/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v1/deps_only/C/Move.toml index 0778ff14641..84247e7fb0c 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v1/deps_only/C/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v1/deps_only/C/Move.toml @@ -1,9 +1,5 @@ [package] name = "C" -[dependencies.A] -resolver = "../../../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +[dependencies] +A = { r."../../../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v2/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v2/Move.toml index 4db3ca63a27..aca91556f2b 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v2/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_incorrect_override_v2/Move.toml @@ -18,10 +18,4 @@ name = "Root" [dependencies] B = { local = "./deps_only/B" } - -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.locked index 4926f3c4720..c4b22862f35 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.locked @@ -1,30 +1,30 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "B06FCED8E0EF6B62EC0B572DC233C0D70206B1C10EEDEA0403CA64AFBB3E439B" +version = 3 +manifest_digest = "1A19D99A36EA0D72B36FC64B2108B42452C99FF87E9DF6E0E54A38AD8679D431" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.resolved index d17a7b94d3e..e59c52416df 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.resolved @@ -78,7 +78,7 @@ ResolvedGraph { "B", "Root", }, - manifest_digest: "B06FCED8E0EF6B62EC0B572DC233C0D70206B1C10EEDEA0403CA64AFBB3E439B", + manifest_digest: "1A19D99A36EA0D72B36FC64B2108B42452C99FF87E9DF6E0E54A38AD8679D431", deps_digest: "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600", }, build_options: BuildConfig { diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.toml index 057b0f70d4b..5e1b47bd85e 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_no_conflict/Move.toml @@ -3,10 +3,4 @@ name = "Root" [dependencies] B = { local = "./deps_only/B" } - -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.locked index 7896e12c4aa..e71addc3e71 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.locked @@ -1,31 +1,31 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "82E01E336DD3374BDC42CA355AB6ACA69E44DB65E36DC0A831F36B06F6832574" +version = 3 +manifest_digest = "962A6DC626FF53896265D6D3CECA6A95E461EA4C97B32A8527807F7225BFF183" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "ADep" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "ADep", name = "ADep" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep-v1" } [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.resolved index a2cfba467ba..0585fff693f 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.resolved @@ -84,7 +84,7 @@ ResolvedGraph { "B", "Root", }, - manifest_digest: "82E01E336DD3374BDC42CA355AB6ACA69E44DB65E36DC0A831F36B06F6832574", + manifest_digest: "962A6DC626FF53896265D6D3CECA6A95E461EA4C97B32A8527807F7225BFF183", deps_digest: "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3", }, build_options: BuildConfig { diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.toml index 030330425bd..55b8398e5f3 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override/Move.toml @@ -4,10 +4,4 @@ name = "Root" [dependencies] B = { local = "./deps_only/B" } ADep = { local = "./deps_only/ADep-v1", override = true } - -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/Move.locked index 9bdc1d2d2e5..31247485a96 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/Move.locked @@ -1,39 +1,39 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "E1BD09BE802FCCF437672321DEBFD0C8000F9D4A0AC5E54ED432087ABACA9667" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "B" }, - { name = "C" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A-v1" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/deps_only/C/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/deps_only/C/Move.toml index 0778ff14641..84247e7fb0c 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/deps_only/C/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_external_override_root/deps_only/C/Move.toml @@ -1,9 +1,5 @@ [package] name = "C" -[dependencies.A] -resolver = "../../../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +[dependencies] +A = { r."../../../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_dep_conflict/deps_only/C/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_dep_conflict/deps_only/C/Move.toml index 5c8747777c8..e7c7e31433d 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_dep_conflict/deps_only/C/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_dep_conflict/deps_only/C/Move.toml @@ -1,9 +1,5 @@ [package] name = "C" -[dependencies.A] -resolver = "../../../resolvers/successful_subst.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +[dependencies] +A = { r."../../../resolvers/successful_subst.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_override/Move.locked index 31954ffc4c2..57b12d457a0 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_nested_override/Move.locked @@ -1,48 +1,48 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "86DBE490660052E70AF19AEB6DB3CDFE90F770D67E008E12C753575AB346B43C" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "B" }, - { name = "E" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "C" }, - { name = "D" }, + { id = "C", name = "C" }, + { id = "D", name = "D" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "E" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } dependencies = [ - { name = "E" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D" } dependencies = [ - { name = "E" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "E" +id = "E" source = { local = "deps_only/E-v1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_override/Move.locked index 203629a5322..d5429696133 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_override/Move.locked @@ -1,31 +1,31 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "F64B7E3BA42923C4AFD7490B03D34813BA434044DC83D46F869DD5BB9A6052B2" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "B" }, - { name = "C" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C-v1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_transitive_nested_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_transitive_nested_override/Move.locked index e99fb2cf047..edd0baa8b13 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_transitive_nested_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_transitive_nested_override/Move.locked @@ -1,44 +1,44 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "B2F5516D0E0D7FC1D1A91EF42181BC28609979CA8D75F7EF01B473AF22303C1D" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "B" }, - { name = "C" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "B" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B1" } [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } dependencies = [ - { name = "D" }, - { name = "E" }, + { id = "D", name = "D" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D-v3" } [[move.package]] -name = "E" +id = "E" source = { local = "deps_only/E" } dependencies = [ - { name = "D" }, + { id = "D", name = "D" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_two_nested_overrides/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_two_nested_overrides/Move.locked index ed33e57cb7b..25fd4a8e570 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_two_nested_overrides/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_dep_two_nested_overrides/Move.locked @@ -1,49 +1,49 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "88451CA3B87F330C2224714E02829B02787D5AEA4F9CCD9FF239ED0344CF0632" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "B" }, - { name = "E" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "C" }, - { name = "D" }, - { name = "E" }, + { id = "C", name = "C" }, + { id = "D", name = "D" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "E" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } dependencies = [ - { name = "E" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D" } dependencies = [ - { name = "E" }, + { id = "E", name = "E" }, ] [[move.package]] -name = "E" +id = "E" source = { local = "deps_only/E-v1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/Move.locked index 50e7097ccae..5179dcebc03 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/Move.locked @@ -1,30 +1,30 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "2CE4CA7B1785FEAE60C59A993DB1182E09DB665E694C6104DF566E065752C030" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A", addr_subst = { "AA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, - { name = "B", addr_subst = { "BA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, + { id = "A", name = "A", addr_subst = { "AA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, + { id = "B", name = "B", addr_subst = { "BA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "C", addr_subst = { "AA" = "A" } }, + { id = "C", name = "C", addr_subst = { "AA" = "A" } }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "C", addr_subst = { "BA" = "A" } }, + { id = "C", name = "C", addr_subst = { "BA" = "A" } }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/deps_only/B/sources/AA.move b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/deps_only/B/sources/AA.move index 411a75ce7d3..bd117ac2865 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/deps_only/B/sources/AA.move +++ b/external-crates/move/crates/move-package/tests/test_sources/diamond_problem_no_conflict/deps_only/B/sources/AA.move @@ -1,3 +1,3 @@ -module 0x1::AAA { +module 0x6::AAA { public fun foo() {} } diff --git a/external-crates/move/crates/move-package/tests/test_sources/direct_and_indirect_dep/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/direct_and_indirect_dep/Move.locked index 13413683eb2..26bf01775d5 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/direct_and_indirect_dep/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/direct_and_indirect_dep/Move.locked @@ -1,30 +1,30 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "373B3598A66D05FBD7DE398D2F588C9C79C9F38757140E8717C1D851CBC5C15F" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external/Move.locked index 07bcc6f99d1..9f5f2fccc4b 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/external/Move.locked @@ -1,21 +1,21 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "8D09D19521F36950C0698F14ED09FE4F6175C022796F1E401F2F5A1BCA6FCE98" +version = 3 +manifest_digest = "0B6E0EF231AAF334D40D1FE28680D7A9B8939FCEF885743368FAF858533CD0E2" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external/Move.resolved index 8df7c4efb4c..0237bb21e49 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/external/Move.resolved @@ -52,7 +52,7 @@ ResolvedGraph { "ADep", "Root", }, - manifest_digest: "8D09D19521F36950C0698F14ED09FE4F6175C022796F1E401F2F5A1BCA6FCE98", + manifest_digest: "0B6E0EF231AAF334D40D1FE28680D7A9B8939FCEF885743368FAF858533CD0E2", deps_digest: "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082", }, build_options: BuildConfig { diff --git a/external-crates/move/crates/move-package/tests/test_sources/external/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external/Move.toml index 4f483386be0..81642bf65ef 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external/Move.toml @@ -1,9 +1,5 @@ [package] name = "Root" -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +[dependencies] +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.locked index 78482d3c915..59d149a9ef8 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.locked @@ -1,21 +1,21 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "725168ABE1A1677C13C020BCA80D7C059B53A9C7E2E4D15FD0BE671E0D2A87B0" +version = 3 +manifest_digest = "6CC399FE60217A66068CDC5CCDBB3518CC81C965A4B093EEA0C8FFC55B77D8DA" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.toml index b6df3e40a03..f380f8035d3 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_bad_dep/Move.toml @@ -1,7 +1,7 @@ [package] name = "Root" -[dependencies.A] +[dependencies] # The resolver will introduce Root -> A -> ADep into the dependency # graph, but ADep doesn't exist, so it will fail. -resolver = "../resolvers/successful.sh" +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_broken/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_broken/Move.toml index b328da1ae00..42ab475506e 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_broken/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_broken/Move.toml @@ -1,7 +1,7 @@ [package] name = "Root" -[dependencies.A] # This resolver exits with success but returns bad output (not a lock # file), so resolution fails. -resolver = "../resolvers/broken.sh" +[dependencies] +A = { r."../resolvers/broken.sh" = "a" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.locked index f685ef0302c..044f15ff8ae 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.locked @@ -1,36 +1,36 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "84A0B503BE9F9B341AC66860713D12704876E5C2425891E3B94626B12E4313E5" +version = 3 +manifest_digest = "A0EB64199385F1312BF72CA00B135B4C6CB0531F538FFCF9156C6D96FBE10F39" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] dev-dependencies = [ - { name = "B" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "BDep" }, + { id = "BDep", name = "BDep" }, ] [[move.package]] -name = "BDep" +id = "BDep" source = { local = "deps_only/BDep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.resolved index 4052c2f5bfb..aaa0fc6dc3e 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.resolved @@ -90,7 +90,7 @@ ResolvedGraph { "ADep", "Root", }, - manifest_digest: "84A0B503BE9F9B341AC66860713D12704876E5C2425891E3B94626B12E4313E5", + manifest_digest: "A0EB64199385F1312BF72CA00B135B4C6CB0531F538FFCF9156C6D96FBE10F39", deps_digest: "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600", }, build_options: BuildConfig { diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.toml index 11cf3c5d76c..1e142c9b643 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_dev_dep/Move.toml @@ -1,10 +1,10 @@ [package] name = "Root" -[dependencies.A] -resolver = "../resolvers/successful.sh" +[dependencies] +A = { r."../resolvers/successful.sh" = "A" } -[dev-dependencies.B] +[dev-dependencies] # External resolvers can be used for dev dependencies as well as # regular dependencies -resolver = "../resolvers/successful.sh" +B = { r."../resolvers/successful.sh" = "B" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_failing/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_failing/Move.toml index 1d9b52f42c4..bd7c2528329 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_failing/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_failing/Move.toml @@ -1,7 +1,7 @@ [package] name = "Root" -[dependencies.A] +[dependencies] # This resolver returns a non-zero exit code, which should cause # resolution to fail. -resolver = "../resolvers/failing.sh" +A = { r."../resolvers/failing.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_no_resolver/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_no_resolver/Move.toml index 46932071dec..ecb31b3fa29 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_no_resolver/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_no_resolver/Move.toml @@ -1,6 +1,6 @@ [package] name = "Root" -[dependencies.A] # This resolver doesn't exist, so calling out to it will fail. -resolver = "../resolvers/doesnt_exist.sh" +[dependencies] +A = { r."../resolvers/doesnt_exist.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.locked index 8c12f846a93..e969130b349 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.locked @@ -1,22 +1,22 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "2B4FEA0B5D338A2EDB2A81621AB1A0477D98DC5B8CE02638646C8C2233A3E735" +version = 3 +manifest_digest = "3C00856A73D8B2898F203EF00930C3FEC2071277EEF041CE99CB1073B54C7A00" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "ADep" }, + { id = "A", name = "A" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.resolved index d60751d60dc..5ce9fc90692 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.resolved @@ -60,7 +60,7 @@ ResolvedGraph { "ADep", "Root", }, - manifest_digest: "2B4FEA0B5D338A2EDB2A81621AB1A0477D98DC5B8CE02638646C8C2233A3E735", + manifest_digest: "3C00856A73D8B2898F203EF00930C3FEC2071277EEF041CE99CB1073B54C7A00", deps_digest: "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600", }, build_options: BuildConfig { diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.toml index 7c17d6bbf6a..368cd2d12d3 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_overlap/Move.toml @@ -5,10 +5,4 @@ name = "Root" # This should succeed even though the external resolver will also return # `ADep` as a transitive dependency as `ADep` has the same dependencies in both cases. ADep = { local = "./deps_only/ADep" } - -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail/Move.toml index 0b62d72844f..e5243f90a98 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail/Move.toml @@ -6,10 +6,4 @@ name = "Root" # and the set of `ADep`s own dependencies is empty in the "external" case and non-empty in the # "internal" one. ADep = { local = "./deps_only/ADep" } - -[dependencies.A] -resolver = "../resolvers/successful.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail_symmetric/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail_symmetric/Move.toml index d5bfeafc0eb..29c9f69ffbd 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail_symmetric/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_overlap_fail_symmetric/Move.toml @@ -6,10 +6,4 @@ name = "Root" # `ADep` as a transitive dependency and the set of `ADep`s own # dependencies is different in both cases. ADep = { local = "./deps_only/ADep" } - -[dependencies.A] -resolver = "../resolvers/successful_dep.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +A = { r."../resolvers/successful_dep.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.locked new file mode 100644 index 00000000000..ee0b78596d3 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.locked @@ -0,0 +1,19 @@ +# @generated by Move, please check-in and do not edit manually. + +[move] +version = 3 +manifest_digest = "C998DF0F473DF6AB3E7B06E0E596FDE9836950D07EDED905464AA1337F176738" +deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" +dependencies = [ + { id = "bar", name = "bar" }, + { id = "foo", name = "foo" }, +] + +[[move.package]] +id = "bar" +source = { local = "deps_only/bar" } +version = "5" + +[[move.package]] +id = "foo" +source = { local = "deps_only/foo" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.progress b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.progress new file mode 100644 index 00000000000..76b6523ded0 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.progress @@ -0,0 +1,6 @@ +RESOLVING DEPENDENCIES IN Anything FROM Root WITH ../resolvers/successful_package_batch_response.sh +../resolvers/successful_package_batch_response.sh stderr: +Successful External Resolver +PWD: $ROOT/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response +Type: dependencies +Package: Anything diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.resolved new file mode 100644 index 00000000000..dd5a8f90cd2 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.resolved @@ -0,0 +1,180 @@ +ResolvedGraph { + graph: DependencyGraph { + root_path: "tests/test_sources/external_package_batch_response", + root_package_id: "Root", + root_package_name: "Root", + package_graph: { + "Root": [ + ( + "bar", + Outgoing, + ), + ( + "foo", + Outgoing, + ), + ], + "bar": [ + ( + "Root", + Incoming, + ), + ], + "foo": [ + ( + "Root", + Incoming, + ), + ], + }, + package_table: { + "bar": Package { + kind: Local( + "deps_only/bar", + ), + version: Some( + "5", + ), + resolver: Some( + "../resolvers/successful_package_batch_response.sh", + ), + }, + "foo": Package { + kind: Local( + "deps_only/foo", + ), + version: None, + resolver: Some( + "../resolvers/successful_package_batch_response.sh", + ), + }, + }, + always_deps: { + "Root", + "bar", + "foo", + }, + manifest_digest: "C998DF0F473DF6AB3E7B06E0E596FDE9836950D07EDED905464AA1337F176738", + deps_digest: "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600", + }, + build_options: BuildConfig { + dev_mode: true, + test_mode: false, + generate_docs: false, + install_dir: Some( + "ELIDED_FOR_TEST", + ), + force_recompilation: false, + lock_file: Some( + "ELIDED_FOR_TEST", + ), + fetch_deps_only: false, + skip_fetch_latest_git_deps: false, + default_flavor: None, + default_edition: None, + deps_as_root: false, + silence_warnings: false, + warnings_are_errors: false, + json_errors: false, + additional_named_addresses: {}, + lint_flag: LintFlag { + no_lint: false, + lint: false, + }, + }, + package_table: { + "Root": Package { + source_package: SourceManifest { + package: PackageInfo { + name: "Root", + authors: [], + license: None, + edition: None, + flavor: None, + custom_properties: {}, + }, + addresses: Some( + { + "root": Some( + 0000000000000000000000000000000000000000000000000000000000000000, + ), + }, + ), + dev_address_assignments: None, + build: None, + dependencies: { + "Anything": External( + "../resolvers/successful_package_batch_response.sh", + ), + }, + dev_dependencies: {}, + }, + package_path: "ELIDED_FOR_TEST", + renaming: {}, + resolved_table: { + "bar": 0000000000000000000000000000000000000000000000000000000000000000, + "foo": 0000000000000000000000000000000000000000000000000000000000000000, + "root": 0000000000000000000000000000000000000000000000000000000000000000, + }, + source_digest: "ELIDED_FOR_TEST", + }, + "bar": Package { + source_package: SourceManifest { + package: PackageInfo { + name: "bar", + authors: [], + license: None, + edition: None, + flavor: None, + custom_properties: {}, + }, + addresses: Some( + { + "bar": Some( + 0000000000000000000000000000000000000000000000000000000000000000, + ), + }, + ), + dev_address_assignments: None, + build: None, + dependencies: {}, + dev_dependencies: {}, + }, + package_path: "ELIDED_FOR_TEST", + renaming: {}, + resolved_table: { + "bar": 0000000000000000000000000000000000000000000000000000000000000000, + }, + source_digest: "ELIDED_FOR_TEST", + }, + "foo": Package { + source_package: SourceManifest { + package: PackageInfo { + name: "foo", + authors: [], + license: None, + edition: None, + flavor: None, + custom_properties: {}, + }, + addresses: Some( + { + "foo": Some( + 0000000000000000000000000000000000000000000000000000000000000000, + ), + }, + ), + dev_address_assignments: None, + build: None, + dependencies: {}, + dev_dependencies: {}, + }, + package_path: "ELIDED_FOR_TEST", + renaming: {}, + resolved_table: { + "foo": 0000000000000000000000000000000000000000000000000000000000000000, + }, + source_digest: "ELIDED_FOR_TEST", + }, + }, +} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.toml new file mode 100644 index 00000000000..d6dc943246d --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/Move.toml @@ -0,0 +1,8 @@ +[package] +name = "Root" + +[dependencies] +Anything = { r."../resolvers/successful_package_batch_response.sh" = "AlsoAnything" } + +[addresses] +root = "0x0" diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/Move.toml new file mode 100644 index 00000000000..008ac4dab92 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/Move.toml @@ -0,0 +1,5 @@ +[package] +name = "bar" + +[addresses] +bar = "0x0" diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/sources/bar.move b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/sources/bar.move new file mode 100644 index 00000000000..e1eb4beaae9 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/bar/sources/bar.move @@ -0,0 +1 @@ +module bar::bar {} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/Move.toml new file mode 100644 index 00000000000..a739d8d4608 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/Move.toml @@ -0,0 +1,5 @@ +[package] +name = "foo" + +[addresses] +foo = "0x0" diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/sources/foo.move b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/sources/foo.move new file mode 100644 index 00000000000..28436d11ecb --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/deps_only/foo/sources/foo.move @@ -0,0 +1 @@ +module foo::foo {} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/sources/root.move b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/sources/root.move new file mode 100644 index 00000000000..1a16facc09f --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_package_batch_response/sources/root.move @@ -0,0 +1 @@ +module root::root {} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.locked new file mode 100644 index 00000000000..027ed6a5037 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.locked @@ -0,0 +1,6 @@ +# @generated by Move, please check-in and do not edit manually. + +[move] +version = 3 +manifest_digest = "D0A99B6D19946036C7A76C46B5B13EC9E47ED5FB3B8940036A0B93D627225A8A" +deps_digest = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.resolved new file mode 100644 index 00000000000..7bcee822c4b --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.resolved @@ -0,0 +1,64 @@ +ResolvedGraph { + graph: DependencyGraph { + root_path: "tests/test_sources/external_resolver_config", + root_package_id: "Root", + root_package_name: "Root", + package_graph: { + "Root": [], + }, + package_table: {}, + always_deps: { + "Root", + }, + manifest_digest: "D0A99B6D19946036C7A76C46B5B13EC9E47ED5FB3B8940036A0B93D627225A8A", + deps_digest: "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + }, + build_options: BuildConfig { + dev_mode: true, + test_mode: false, + generate_docs: false, + install_dir: Some( + "ELIDED_FOR_TEST", + ), + force_recompilation: false, + lock_file: Some( + "ELIDED_FOR_TEST", + ), + fetch_deps_only: false, + skip_fetch_latest_git_deps: false, + default_flavor: None, + default_edition: None, + deps_as_root: false, + silence_warnings: false, + warnings_are_errors: false, + json_errors: false, + additional_named_addresses: {}, + lint_flag: LintFlag { + no_lint: false, + lint: false, + }, + }, + package_table: { + "Root": Package { + source_package: SourceManifest { + package: PackageInfo { + name: "Root", + authors: [], + license: None, + edition: None, + flavor: None, + custom_properties: {}, + }, + addresses: None, + dev_address_assignments: None, + build: None, + dependencies: {}, + dev_dependencies: {}, + }, + package_path: "ELIDED_FOR_TEST", + renaming: {}, + resolved_table: {}, + source_digest: "ELIDED_FOR_TEST", + }, + }, +} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.toml new file mode 100644 index 00000000000..0a64e2e10e7 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "Root" + +[r.foo] +network = "something" +other_thing = "hmmm" diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/sources/Root.move b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/sources/Root.move new file mode 100644 index 00000000000..b3d738219c9 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_config/sources/Root.move @@ -0,0 +1,11 @@ +module AA::Root { + use AA::A; + use BA::B; + use BA::C; + + public fun foo() { + A::foo(); + B::foo(); + C::foo(); + } +} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.resolved new file mode 100644 index 00000000000..6866147064b --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.resolved @@ -0,0 +1,3 @@ +Error parsing '[dependencies]' section of manifest: Malformed external resolver declaration for dependency r.baz = "quz" +foo = "bar" + diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.toml new file mode 100644 index 00000000000..207e1bd33d5 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/Move.toml @@ -0,0 +1,5 @@ +[package] +name = "Root" + +[dependencies] +A = { r = { foo = "bar", baz = "quz" } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/sources/Root.move b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/sources/Root.move new file mode 100644 index 00000000000..b3d738219c9 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver/sources/Root.move @@ -0,0 +1,11 @@ +module AA::Root { + use AA::A; + use BA::B; + use BA::C; + + public fun foo() { + A::foo(); + B::foo(); + C::foo(); + } +} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.resolved new file mode 100644 index 00000000000..cf2f91775d1 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.resolved @@ -0,0 +1,3 @@ +Error parsing '[dependencies]' section of manifest: Malformed external resolver declaration for dependency r.[foo] +bar = "baz" + diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.toml new file mode 100644 index 00000000000..97b61858099 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/Move.toml @@ -0,0 +1,5 @@ +[package] +name = "Root" + +[dependencies] +B = { r.foo.bar = "baz" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/sources/Root.move b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/sources/Root.move new file mode 100644 index 00000000000..b3d738219c9 --- /dev/null +++ b/external-crates/move/crates/move-package/tests/test_sources/external_resolver_invalid_resolver_invalid_target/sources/Root.move @@ -0,0 +1,11 @@ +module AA::Root { + use AA::A; + use BA::B; + use BA::C; + + public fun foo() { + A::foo(); + B::foo(); + C::foo(); + } +} diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.locked index 22d98b61905..357f6c5ce6b 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.locked @@ -1,21 +1,21 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "C5119AF40DAACF1DF25E8E9DE830EC0EA839A29E62D7081BF217B49B10BD6980" +version = 3 +manifest_digest = "33DC15844925BAA2A89C51EC6604D5C5756C75124306422A18CA5D33E507DC6F" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "A" }, + { id = "A", name = "A" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.toml index 4ba3e12e91d..13dbb0609c9 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/external_silent/Move.toml @@ -1,5 +1,5 @@ [package] name = "Root" -[dependencies.A] -resolver = "../resolvers/silent.sh" +[dependencies] +A = { r."../resolvers/silent.sh" = "a" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/multiple_deps_no_rename/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/multiple_deps_no_rename/Move.locked index cdcc66f3955..6223fbab28b 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/multiple_deps_no_rename/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/multiple_deps_no_rename/Move.locked @@ -1,18 +1,18 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "846084292F5A72B3CFE28402E76C1F3F172C3001C90FAAC19221D4B178A84EDB" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "C" }, - { name = "D" }, + { id = "C", name = "C" }, + { id = "D", name = "D" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C" } [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_git_local/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_git_local/Move.locked index 4459fabc843..2dff990a1ee 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_git_local/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_git_local/Move.locked @@ -1,21 +1,21 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "E8A0B8E5BE21A2E2341236BF8B787FA329C7956F8E33E3E5E7D97A5504A7E2FA" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "MoveNursery" }, + { id = "MoveNursery", name = "MoveNursery" }, ] [[move.package]] -name = "MoveNursery" +id = "MoveNursery" source = { git = "https://github.com/iotaledger/iota", rev = "5d8a867", subdir = "external-crates/move/crates/move-stdlib/nursery" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { git = "https://github.com/iotaledger/iota", rev = "5d8a867", subdir = "external-crates/move/crates/move-stdlib" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_local_local/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_local_local/Move.locked index 2690dab6473..c3513005b31 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_local_local/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_local_local/Move.locked @@ -1,21 +1,21 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "CD8925BBAAE2A64C347B3D48466097B55E04876C226546516D83EDC58C0BBB3A" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Nested" }, + { id = "Nested", name = "Nested" }, ] [[move.package]] -name = "More" +id = "More" source = { local = "deps_only/nested/more" } [[move.package]] -name = "Nested" +id = "Nested" source = { local = "deps_only/nested" } dependencies = [ - { name = "More" }, + { id = "More", name = "More" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_override/Move.locked index 2690dab6473..c3513005b31 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_override/Move.locked @@ -1,21 +1,21 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "CD8925BBAAE2A64C347B3D48466097B55E04876C226546516D83EDC58C0BBB3A" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Nested" }, + { id = "Nested", name = "Nested" }, ] [[move.package]] -name = "More" +id = "More" source = { local = "deps_only/nested/more" } [[move.package]] -name = "Nested" +id = "Nested" source = { local = "deps_only/nested" } dependencies = [ - { name = "More" }, + { id = "More", name = "More" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_shared_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_shared_override/Move.locked index e9a3c5e449a..f6e88c84891 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/nested_deps_shared_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/nested_deps_shared_override/Move.locked @@ -1,32 +1,32 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "5005BF461ECC5281FE314371B38D8C163C5395D7455B91BEA0F63C1BCFD57551" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "More" }, - { name = "Nested" }, - { name = "Shared" }, + { id = "More", name = "More" }, + { id = "Nested", name = "Nested" }, + { id = "Shared", name = "Shared" }, ] [[move.package]] -name = "More" +id = "More" source = { local = "deps_only/more" } dependencies = [ - { name = "Shared" }, + { id = "Shared", name = "Shared" }, ] [[move.package]] -name = "Nested" +id = "Nested" source = { local = "deps_only/nested" } dependencies = [ - { name = "More" }, - { name = "Shared" }, + { id = "More", name = "More" }, + { id = "Shared", name = "Shared" }, ] [[move.package]] -name = "Shared" +id = "Shared" source = { local = "deps_only/shared" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/one_dep/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/one_dep/Move.locked index 8bc86b54e57..ba3039f5d00 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/one_dep/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/one_dep/Move.locked @@ -1,13 +1,13 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "0C66C2C067539518C3189E86B5A09D478C872C0F97ACE6D707AE9753319E56AA" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "OtherDep", addr_subst = { "A" = "B" } }, + { id = "OtherDep", name = "OtherDep", addr_subst = { "A" = "B" } }, ] [[move.package]] -name = "OtherDep" +id = "OtherDep" source = { local = "deps_only/other_dep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/one_dep_bad_digest/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/one_dep_bad_digest/Move.locked index c20d3d58f89..71e9585e5dc 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/one_dep_bad_digest/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/one_dep_bad_digest/Move.locked @@ -1,13 +1,13 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "FF14D56377603271FD9E5F6C5210F49834586500B7F85D11D1D37543E0F78AEE" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "OtherDep", digest = "BAD_DIGEST", addr_subst = { "A" = "B" } }, + { id = "OtherDep", name = "OtherDep", digest = "BAD_DIGEST", addr_subst = { "A" = "B" } }, ] [[move.package]] -name = "OtherDep" +id = "OtherDep" source = { local = "deps_only/other_dep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/one_dep_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/one_dep_override/Move.locked index 650bc797bd2..e329435a00d 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/one_dep_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/one_dep_override/Move.locked @@ -1,13 +1,13 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "340302CAC58F9844D483E9F19F08D9578B90043E621D953A62A4B679F8D98896" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "OtherDep", addr_subst = { "A" = "B" } }, + { id = "OtherDep", name = "OtherDep", addr_subst = { "A" = "B" } }, ] [[move.package]] -name = "OtherDep" +id = "OtherDep" source = { local = "deps_only/other_dep" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.resolved index c942874984d..0e0c36951c5 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.resolved @@ -1 +1 @@ -Failed to resolve dependencies for package 'test': Fetching 'Pkg': TestHooks resolve dep "Pkg" = "localhost:8080" "Pkg" "0x1" "" +Failed to resolve dependencies for package 'test': Fetching 'Pkg': TestHooks resolve dep "Pkg" = "0x1" diff --git a/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.toml index a8d6d6d3fb0..f666cd756f7 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/package_hooks/Move.toml @@ -2,4 +2,4 @@ name = "test" [dependencies] -Pkg = { custom = "localhost:8080", address = "0x1" } +Pkg = { id = "0x1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.resolved deleted file mode 100644 index f855ef689ac..00000000000 --- a/external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.resolved +++ /dev/null @@ -1 +0,0 @@ -Failed to resolve dependencies for package 'test': Fetching 'Pkg': TestHooks resolve dep "Pkg" = "localhost:8080" "Pkg" "0x1" "foo/bar" diff --git a/external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.toml deleted file mode 100644 index 540b6f9b0f6..00000000000 --- a/external-crates/move/crates/move-package/tests/test_sources/package_hooks_subdir/Move.toml +++ /dev/null @@ -1,5 +0,0 @@ -[package] -name = "test" - -[dependencies] -Pkg = { custom = "localhost:8080", address = "0x1", subdir = "foo/bar" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_2024/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_2024/Move.resolved index 07b9edb6413..8158e05781c 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_2024/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_2024/Move.resolved @@ -1 +1,73 @@ -Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "2024". Current supported editions include: "legacy", "2024.alpha", and "2024.beta" +ResolvedGraph { + graph: DependencyGraph { + root_path: "tests/test_sources/parsing_edition_2024", + root_package_id: "name", + root_package_name: "name", + package_graph: { + "name": [], + }, + package_table: {}, + always_deps: { + "name", + }, + manifest_digest: "9CA39D4DF2F4A9804A698BA06940004E030B6C5611DAC594177C63B68F6440D5", + deps_digest: "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + }, + build_options: BuildConfig { + dev_mode: true, + test_mode: false, + generate_docs: false, + install_dir: Some( + "ELIDED_FOR_TEST", + ), + force_recompilation: false, + lock_file: Some( + "ELIDED_FOR_TEST", + ), + fetch_deps_only: false, + skip_fetch_latest_git_deps: false, + default_flavor: None, + default_edition: None, + deps_as_root: false, + silence_warnings: false, + warnings_are_errors: false, + json_errors: false, + additional_named_addresses: {}, + lint_flag: LintFlag { + no_lint: false, + lint: false, + }, + }, + package_table: { + "name": Package { + source_package: SourceManifest { + package: PackageInfo { + name: "name", + authors: [ + "some author", + ], + license: Some( + "\"license\"", + ), + edition: Some( + Edition { + edition: "2024", + release: None, + }, + ), + flavor: None, + custom_properties: {}, + }, + addresses: None, + dev_address_assignments: None, + build: None, + dependencies: {}, + dev_dependencies: {}, + }, + package_path: "ELIDED_FOR_TEST", + renaming: {}, + resolved_table: {}, + source_digest: "ELIDED_FOR_TEST", + }, + }, +} diff --git a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_invalid_suffix/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_invalid_suffix/Move.resolved index ea28488cd0f..c8db1b9f175 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_invalid_suffix/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_invalid_suffix/Move.resolved @@ -1 +1 @@ -Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "2024;alpha". Current supported editions include: "legacy", "2024.alpha", and "2024.beta" +Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "2024;alpha". Current supported editions include: "legacy", "2024.alpha", "2024.beta", and "2024" diff --git a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown/Move.resolved index 3fac85c88c9..29f0db3a3ec 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown/Move.resolved @@ -1 +1 @@ -Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "foobar". Current supported editions include: "legacy", "2024.alpha", and "2024.beta" +Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "foobar". Current supported editions include: "legacy", "2024.alpha", "2024.beta", and "2024" diff --git a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown_suffix/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown_suffix/Move.resolved index d64d40b6b26..3546b729a57 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown_suffix/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/parsing_edition_unknown_suffix/Move.resolved @@ -1 +1 @@ -Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "2024.final". Current supported editions include: "legacy", "2024.alpha", and "2024.beta" +Error parsing '[package]' section of manifest: Invalid 'edition'. Unsupported edition "2024.final". Current supported editions include: "legacy", "2024.alpha", "2024.beta", and "2024" diff --git a/external-crates/move/crates/move-package/tests/test_sources/parsing_no_path_set_for_dependency/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/parsing_no_path_set_for_dependency/Move.resolved index 173327fe862..c11f6354da5 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/parsing_no_path_set_for_dependency/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/parsing_no_path_set_for_dependency/Move.resolved @@ -1 +1 @@ -Error parsing '[dependencies]' section of manifest: must provide exactly one of 'local' or 'git' or 'resolver' or 'custom' for dependency. +Error parsing '[dependencies]' section of manifest: must provide exactly one of 'local' or 'git' or 'r.' for dependency. diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/Move.locked index f8ea0a78c8a..27cec68c7eb 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/Move.locked @@ -1,30 +1,30 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "6F18190939664D7ECC8F2DC327E079037A743E0CFF3FA5F72DABD2B6B5C3D200" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A-resolved", addr_subst = { "AA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, - { name = "B-resolved", addr_subst = { "BA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, + { id = "A-resolved", name = "A-rename", addr_subst = { "AA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, + { id = "B-resolved", name = "B-rename", addr_subst = { "BA" = "0000000000000000000000000000000000000000000000000000000000000001" } }, ] [[move.package]] -name = "A-resolved" +id = "A-resolved" source = { local = "deps_only/A-rename" } dependencies = [ - { name = "C-resolved", addr_subst = { "AA" = "A" } }, + { id = "C-resolved", name = "C-rename", addr_subst = { "AA" = "A" } }, ] [[move.package]] -name = "B-resolved" +id = "B-resolved" source = { local = "deps_only/B-rename" } dependencies = [ - { name = "C-resolved", addr_subst = { "BA" = "A" } }, + { id = "C-resolved", name = "C-rename", addr_subst = { "BA" = "A" } }, ] [[move.package]] -name = "C-resolved" +id = "C-resolved" source = { local = "deps_only/C-rename" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/deps_only/B-rename/sources/AA.move b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/deps_only/B-rename/sources/AA.move index 411a75ce7d3..bd117ac2865 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/deps_only/B-rename/sources/AA.move +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name/deps_only/B-rename/sources/AA.move @@ -1,3 +1,3 @@ -module 0x1::AAA { +module 0x6::AAA { public fun foo() {} } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/Move.resolved index 220e2bdd225..186e1fe1178 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/Move.resolved @@ -1,5 +1,5 @@ -When resolving dependencies for package Root-rename, conflicting versions of package C-resolved found: -At A-rename -> C-resolved - C-resolved = { local = "deps_only/C-rename-v2" } -At B -> C-resolved - C-resolved = { local = "deps_only/C-rename-v1" } +When resolving dependencies for package Root-rename, conflicting versions of package C-rename found: +At A-rename -> C-rename + C-rename = { local = "deps_only/C-rename-v2" } +At B -> C-rename + C-rename = { local = "deps_only/C-rename-v1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/A-rename/Move.lock b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/A-rename/Move.lock index 5a92bc29440..b6825dd9ea9 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/A-rename/Move.lock +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/A-rename/Move.lock @@ -1,14 +1,14 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "EB5AB2DFC86E6D3D2FE98D626C2162A4C7344F2A3C485FE58DD6C339CD5E73CF" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "C-resolved" }, + { id = "C-resolved", name = "C-rename" }, ] [[move.package]] -name = "C-resolved" +id = "C-resolved" source = { local = "../C-rename-v2" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/B/Move.lock b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/B/Move.lock index f7ebf2752eb..538dda6f5aa 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/B/Move.lock +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/B/Move.lock @@ -1,14 +1,14 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "9C1FF13CFBAECFDB6402A2E0952FDA85BE3719E6D1FD0682D63A6CD7A8E92ED6" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "C-resolved" }, + { id = "C-resolved", name = "C-rename" }, ] [[move.package]] -name = "C-resolved" +id = "C-resolved" source = { local = "../C-rename-v1" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v1/Move.lock b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v1/Move.lock index d255a73a57e..00fbe255cd9 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v1/Move.lock +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v1/Move.lock @@ -1,6 +1,6 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "60A5B7F88A83F5697F7B9AC059CB9680BD351F68B8EB80AFA13294BBB97A47C3" deps_digest = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v2/Move.lock b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v2/Move.lock index d255a73a57e..00fbe255cd9 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v2/Move.lock +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_conflict_lockfile/deps_only/C-rename-v2/Move.lock @@ -1,6 +1,6 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "60A5B7F88A83F5697F7B9AC059CB9680BD351F68B8EB80AFA13294BBB97A47C3" deps_digest = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/Move.resolved index 1c17de6f22a..b8a0ddf42ba 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/Move.resolved @@ -2,4 +2,4 @@ When resolving dependencies for package Root-rename, conflicting dependencies fo At B -> A ADep-rename = { local = "deps_only/ADep", addr_subst = { "A" = "0000000000000000000000000000000000000000000000000000000000000007" } } At C -> A - ADep-resolved = { local = "deps_only/ADep", addr_subst = { "A" = "0000000000000000000000000000000000000000000000000000000000000042" } } + ADep-rename = { local = "deps_only/ADep", addr_subst = { "A" = "0000000000000000000000000000000000000000000000000000000000000042" } } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/deps_only/C/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/deps_only/C/Move.toml index e1529c9b74d..9331862cbbf 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/deps_only/C/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_pkg_name_nested_dep_conflict/deps_only/C/Move.toml @@ -1,9 +1,5 @@ [package] name = "C" -[dependencies.A] -resolver = "../../../resolvers/successful_subst_name_resolution.sh" - -[dependencies.A.packages] -Contains = "Anything" -Has = { No = "Schema" } +[dependencies] +A = { r."../../../resolvers/successful_subst_name_resolution.sh" = "A" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_version/Move.locked index 28ba915ae54..ab2fe914513 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version/Move.locked @@ -1,20 +1,20 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "A152DBB11C386226B7A6435D66090103E0CC19330A38251784E4D2D0C0EF57A5" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } version = "3" [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } version = "2" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond/Move.locked index ae74581c8ef..e61df4416c4 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond/Move.locked @@ -1,33 +1,33 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "88C81CA573217383E355274A37F0C6171DDE43ED835A166B0D6446C294788F65" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } version = "3" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } version = "1" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C-loc-1" } version = "2" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep/Move.locked index adc0e9410da..cc3741e65f8 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep/Move.locked @@ -1,41 +1,41 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "235CCCF728441FCE4689C41E5E5C950FC0EA7EEEB81DE1A5E9C0F00C1758C078" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } version = "3" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } version = "1" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C-loc-1" } version = "2" dependencies = [ - { name = "D" }, + { id = "D", name = "D" }, ] [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep_success/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep_success/Move.locked index 7c09742037c..6d9c76a52da 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep_success/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_deep_success/Move.locked @@ -1,42 +1,42 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "0D120F1BD1E19D683116F2F61E20CAE4DACBA71CB0109100260A8D78FCCAF3D3" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } version = "3" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } version = "1" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C-loc-1" } version = "2" dependencies = [ - { name = "D" }, + { id = "D", name = "D" }, ] [[move.package]] -name = "D" +id = "D" source = { local = "deps_only/D-loc-1" } version = "1" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.locked index 9b5a3c11625..6dbf16f4b19 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.locked @@ -1,31 +1,31 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 -manifest_digest = "85C5D0CFB16CD0F61F3E1A03C84A0D30C3F8470349BD6EFF361F2D35E1BA46B5" +version = 3 +manifest_digest = "E82339BB4E184D331375D7A54B87E8A8F1927735A3C8944FD3F719A6D569CF97" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "A" }, - { name = "B" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] [[move.package]] -name = "ADep" +id = "ADep" source = { local = "deps_only/ADep" } version = "4" [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } dependencies = [ - { name = "ADep" }, + { id = "ADep", name = "ADep" }, ] diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.resolved b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.resolved index 6da82918fb1..3e5b35e98ab 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.resolved +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.resolved @@ -80,7 +80,7 @@ ResolvedGraph { "B", "Root", }, - manifest_digest: "85C5D0CFB16CD0F61F3E1A03C84A0D30C3F8470349BD6EFF361F2D35E1BA46B5", + manifest_digest: "E82339BB4E184D331375D7A54B87E8A8F1927735A3C8944FD3F719A6D569CF97", deps_digest: "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600", }, build_options: BuildConfig { diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.toml b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.toml index 0b3d8ba64da..16296ac3ed9 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.toml +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_external/Move.toml @@ -19,5 +19,5 @@ name = "Root" version = "1" [dependencies] -A = { resolver = "../resolvers/successful_version.sh", packages = { Contains = "Anything", Has = { No = "Schema" } } } +A = { r."../resolvers/successful_version.sh" = "A" } B = { local = "./deps_only/B" } diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_override/Move.locked b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_override/Move.locked index 44c96746f9e..3232a1c08fa 100644 --- a/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_override/Move.locked +++ b/external-crates/move/crates/move-package/tests/test_sources/resolve_version_diamond_override/Move.locked @@ -1,34 +1,34 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 2 +version = 3 manifest_digest = "C310D483FD54E50A72F6739DA1BA0280E2AFDD9BDDE8BEF771ACFD78F052524A" deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ - { name = "A" }, - { name = "B" }, - { name = "C" }, + { id = "A", name = "A" }, + { id = "B", name = "B" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "A" +id = "A" source = { local = "deps_only/A" } version = "3" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "B" +id = "B" source = { local = "deps_only/B" } version = "1" dependencies = [ - { name = "C" }, + { id = "C", name = "C" }, ] [[move.package]] -name = "C" +id = "C" source = { local = "deps_only/C-loc-2" } version = "2" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolvers/silent.sh b/external-crates/move/crates/move-package/tests/test_sources/resolvers/silent.sh index b7ca61b7dc7..8c26faf7a16 100755 --- a/external-crates/move/crates/move-package/tests/test_sources/resolvers/silent.sh +++ b/external-crates/move/crates/move-package/tests/test_sources/resolvers/silent.sh @@ -10,21 +10,21 @@ PACKAGE="$2" # Print lock file cat <&2 +Successful External Resolver +PWD: $(pwd | sed "s,^$ROOT,\$ROOT,") +Type: $TYPE +Package: $PACKAGE +EOF + +foo=$(cat <<'EOF' +[move] +version = 3 +manifest_digest = "42" +deps_digest = "7" +dependencies = [ + { id = "foo", name = "foo" }, +] + +[[move.package]] +id = "foo" +source = { local = "./deps_only/foo" } +EOF +) + +bar=$(cat <<'EOF' +[move] +version = 3 +manifest_digest = "42" +deps_digest = "7" +dependencies = [ + { id = "bar", name = "bar" }, +] + +[[move.package]] +id = "bar" +version = "5" +source = { local = "./deps_only/bar" } +EOF +) + +# Echo the two separate graph contents twice with a null separator in between +printf "$foo\0$bar" diff --git a/external-crates/move/crates/move-package/tests/test_sources/resolvers/successful_subst.sh b/external-crates/move/crates/move-package/tests/test_sources/resolvers/successful_subst.sh index dfb43466884..9c9c9479afb 100755 --- a/external-crates/move/crates/move-package/tests/test_sources/resolvers/successful_subst.sh +++ b/external-crates/move/crates/move-package/tests/test_sources/resolvers/successful_subst.sh @@ -18,21 +18,21 @@ EOF # Print lock file cat < Functi } if options.prover.dump_bytecode { let dump_file = output_dir.join(format!("{}.mv.disas", output_prefix)); - fs::write(&dump_file, &module_env.disassemble()).expect("dumping disassembled module"); + fs::write(&dump_file, module_env.disassemble()).expect("dumping disassembled module"); } for func_env in module_env.get_functions() { targets.add_target(&func_env) diff --git a/external-crates/move/crates/move-stackless-bytecode/src/inconsistency_check.rs b/external-crates/move/crates/move-stackless-bytecode/src/inconsistency_check.rs index 980217780e3..5ae39f143fa 100644 --- a/external-crates/move/crates/move-stackless-bytecode/src/inconsistency_check.rs +++ b/external-crates/move/crates/move-stackless-bytecode/src/inconsistency_check.rs @@ -18,6 +18,9 @@ //! In this way, if the instrumented `assert false` can be proved, it means we //! have an inconsistency in the specifications. //! +//! In this way, if the instrumented `assert false` can be proved, it means we +//! have an inconsistency in the specifications. +//! //! A function that unconditionally abort might be considered as some form of //! inconsistency as well. Consider the function `fun always_abort() { abort 0 //! }`, it might seem surprising that the prover can prove that `spec diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.exp b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.exp index 0559d224118..cdbe8a5f079 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.exp +++ b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.exp @@ -2444,102 +2444,90 @@ public fun string::bytes($t0|s: &string::String): &vector { [variant baseline] public fun string::substring($t0|s: &string::String, $t1|i: u64, $t2|j: u64): string::String { var $t3|tmp#$3: bool - var $t4|tmp#$4: bool - var $t5|tmp#$5: bool - var $t6|bytes#1#0: &vector - var $t7|l#1#0: u64 - var $t8: &string::String - var $t9: &vector - var $t10: &vector + var $t4|bytes#1#0: &vector + var $t5|l#1#0: u64 + var $t6: &string::String + var $t7: &vector + var $t8: &vector + var $t9: u64 + var $t10: u64 var $t11: u64 - var $t12: u64 + var $t12: bool var $t13: u64 - var $t14: bool - var $t15: u64 - var $t16: u64 - var $t17: bool + var $t14: u64 + var $t15: bool + var $t16: &vector + var $t17: u64 var $t18: bool - var $t19: bool - var $t20: &vector - var $t21: u64 + var $t19: &vector + var $t20: u64 + var $t21: bool var $t22: bool var $t23: bool var $t24: bool - var $t25: &vector - var $t26: u64 - var $t27: bool - var $t28: bool - var $t29: bool - var $t30: &vector - var $t31: u64 - var $t32: &vector - var $t33: u64 - var $t34: u64 - var $t35: vector - var $t36: string::String - 0: $t8 := move($t0) - 1: $t9 := borrow_field.bytes($t8) - 2: $t6 := $t9 - 3: $t10 := copy($t6) - 4: $t11 := vector::length($t10) - 5: $t7 := $t11 - 6: $t12 := copy($t2) - 7: $t13 := move($t7) - 8: $t14 := <=($t12, $t13) - 9: if ($t14) goto 10 else goto 16 + var $t25: bool + var $t26: &vector + var $t27: u64 + var $t28: &vector + var $t29: u64 + var $t30: u64 + var $t31: vector + var $t32: string::String + 0: $t6 := move($t0) + 1: $t7 := borrow_field.bytes($t6) + 2: $t4 := $t7 + 3: $t8 := copy($t4) + 4: $t9 := vector::length($t8) + 5: $t5 := $t9 + 6: $t10 := copy($t2) + 7: $t11 := move($t5) + 8: $t12 := <=($t10, $t11) + 9: if ($t12) goto 10 else goto 34 10: label L1 - 11: $t15 := copy($t1) - 12: $t16 := copy($t2) - 13: $t17 := <=($t15, $t16) - 14: $t3 := $t17 - 15: goto 20 - 16: label L0 - 17: $t18 := false - 18: $t3 := $t18 - 19: goto 20 - 20: label L2 - 21: $t19 := move($t3) - 22: if ($t19) goto 23 else goto 29 - 23: label L4 - 24: $t20 := copy($t6) - 25: $t21 := copy($t1) - 26: $t22 := string::internal_is_char_boundary($t20, $t21) - 27: $t4 := $t22 - 28: goto 33 - 29: label L3 - 30: $t23 := false - 31: $t4 := $t23 - 32: goto 33 - 33: label L5 - 34: $t24 := move($t4) - 35: if ($t24) goto 36 else goto 42 - 36: label L7 - 37: $t25 := copy($t6) - 38: $t26 := copy($t2) - 39: $t27 := string::internal_is_char_boundary($t25, $t26) - 40: $t5 := $t27 - 41: goto 46 - 42: label L6 - 43: $t28 := false - 44: $t5 := $t28 - 45: goto 46 - 46: label L8 - 47: $t29 := move($t5) - 48: if ($t29) goto 49 else goto 51 - 49: label L10 - 50: goto 56 - 51: label L9 - 52: $t30 := move($t6) - 53: destroy($t30) - 54: $t31 := 2 - 55: abort($t31) - 56: label L11 - 57: $t32 := move($t6) - 58: $t33 := move($t1) - 59: $t34 := move($t2) - 60: $t35 := string::internal_sub_string($t32, $t33, $t34) - 61: $t36 := pack string::String($t35) - 62: return $t36 + 11: $t13 := copy($t1) + 12: $t14 := copy($t2) + 13: $t15 := <=($t13, $t14) + 14: if ($t15) goto 15 else goto 30 + 15: label L3 + 16: $t16 := copy($t4) + 17: $t17 := copy($t1) + 18: $t18 := string::internal_is_char_boundary($t16, $t17) + 19: if ($t18) goto 20 else goto 26 + 20: label L5 + 21: $t19 := copy($t4) + 22: $t20 := copy($t2) + 23: $t21 := string::internal_is_char_boundary($t19, $t20) + 24: $t3 := $t21 + 25: goto 38 + 26: label L4 + 27: $t22 := false + 28: $t3 := $t22 + 29: goto 38 + 30: label L2 + 31: $t23 := false + 32: $t3 := $t23 + 33: goto 38 + 34: label L0 + 35: $t24 := false + 36: $t3 := $t24 + 37: goto 38 + 38: label L6 + 39: $t25 := move($t3) + 40: if ($t25) goto 41 else goto 43 + 41: label L8 + 42: goto 48 + 43: label L7 + 44: $t26 := move($t4) + 45: destroy($t26) + 46: $t27 := 2 + 47: abort($t27) + 48: label L9 + 49: $t28 := move($t4) + 50: $t29 := move($t1) + 51: $t30 := move($t2) + 52: $t31 := string::internal_sub_string($t28, $t29, $t30) + 53: $t32 := pack string::String($t31) + 54: return $t32 } @@ -4236,12 +4224,12 @@ public fun string::bytes($t0|s: string::String): vector { [variant baseline] public fun string::substring($t0|s: string::String, $t1|i: u64, $t2|j: u64): string::String { var $t3|tmp#$3: bool - var $t4|tmp#$4: bool - var $t5|tmp#$5: bool - var $t6|bytes#1#0: vector - var $t7|l#1#0: u64 - var $t8: vector - var $t9: u64 + var $t4|bytes#1#0: vector + var $t5|l#1#0: u64 + var $t6: vector + var $t7: u64 + var $t8: bool + var $t9: bool var $t10: bool var $t11: bool var $t12: bool @@ -4249,43 +4237,41 @@ public fun string::substring($t0|s: string::String, $t1|i: u64, $t2|j: u64): str var $t14: u64 var $t15: vector var $t16: string::String - 0: $t8 := get_field.bytes($t0) - 1: $t9 := vector::length($t8) - 2: $t10 := <=($t2, $t9) - 3: if ($t10) goto 4 else goto 7 + 0: $t6 := get_field.bytes($t0) + 1: $t7 := vector::length($t6) + 2: $t8 := <=($t2, $t7) + 3: if ($t8) goto 4 else goto 21 4: label L1 - 5: $t3 := <=($t1, $t2) - 6: goto 10 - 7: label L0 - 8: $t11 := false - 9: $t3 := $t11 - 10: label L2 - 11: if ($t3) goto 12 else goto 15 - 12: label L4 - 13: $t4 := string::internal_is_char_boundary($t8, $t1) - 14: goto 18 - 15: label L3 - 16: $t12 := false - 17: $t4 := $t12 - 18: label L5 - 19: if ($t4) goto 20 else goto 23 - 20: label L7 - 21: $t5 := string::internal_is_char_boundary($t8, $t2) - 22: goto 26 - 23: label L6 - 24: $t13 := false - 25: $t5 := $t13 + 5: $t9 := <=($t1, $t2) + 6: if ($t9) goto 7 else goto 17 + 7: label L3 + 8: $t10 := string::internal_is_char_boundary($t6, $t1) + 9: if ($t10) goto 10 else goto 13 + 10: label L5 + 11: $t3 := string::internal_is_char_boundary($t6, $t2) + 12: goto 24 + 13: label L4 + 14: $t11 := false + 15: $t3 := $t11 + 16: goto 24 + 17: label L2 + 18: $t12 := false + 19: $t3 := $t12 + 20: goto 24 + 21: label L0 + 22: $t13 := false + 23: $t3 := $t13 + 24: label L6 + 25: if ($t3) goto 26 else goto 28 26: label L8 - 27: if ($t5) goto 28 else goto 30 - 28: label L10 - 29: goto 33 - 30: label L9 - 31: $t14 := 2 - 32: abort($t14) - 33: label L11 - 34: $t15 := string::internal_sub_string($t8, $t1, $t2) - 35: $t16 := pack string::String($t15) - 36: return $t16 + 27: goto 31 + 28: label L7 + 29: $t14 := 2 + 30: abort($t14) + 31: label L9 + 32: $t15 := string::internal_sub_string($t6, $t1, $t2) + 33: $t16 := pack string::String($t15) + 34: return $t16 } diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.move b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.move index b2f766c47e8..ed1d73a0aa3 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.move +++ b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/function_call.move @@ -5,7 +5,7 @@ // dep: ../move-stdlib/sources/string.move // dep: ../move-stdlib/sources/vector.move -module 0x2::MultiLayerCalling { +module 0x7::MultiLayerCalling { public struct HasVector { v: vector, diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.exp b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.exp index f3986a7ff74..1642ebd5360 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.exp +++ b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.exp @@ -2444,102 +2444,90 @@ public fun string::bytes($t0|s: &string::String): &vector { [variant baseline] public fun string::substring($t0|s: &string::String, $t1|i: u64, $t2|j: u64): string::String { var $t3|tmp#$3: bool - var $t4|tmp#$4: bool - var $t5|tmp#$5: bool - var $t6|bytes#1#0: &vector - var $t7|l#1#0: u64 - var $t8: &string::String - var $t9: &vector - var $t10: &vector + var $t4|bytes#1#0: &vector + var $t5|l#1#0: u64 + var $t6: &string::String + var $t7: &vector + var $t8: &vector + var $t9: u64 + var $t10: u64 var $t11: u64 - var $t12: u64 + var $t12: bool var $t13: u64 - var $t14: bool - var $t15: u64 - var $t16: u64 - var $t17: bool + var $t14: u64 + var $t15: bool + var $t16: &vector + var $t17: u64 var $t18: bool - var $t19: bool - var $t20: &vector - var $t21: u64 + var $t19: &vector + var $t20: u64 + var $t21: bool var $t22: bool var $t23: bool var $t24: bool - var $t25: &vector - var $t26: u64 - var $t27: bool - var $t28: bool - var $t29: bool - var $t30: &vector - var $t31: u64 - var $t32: &vector - var $t33: u64 - var $t34: u64 - var $t35: vector - var $t36: string::String - 0: $t8 := move($t0) - 1: $t9 := borrow_field.bytes($t8) - 2: $t6 := $t9 - 3: $t10 := copy($t6) - 4: $t11 := vector::length($t10) - 5: $t7 := $t11 - 6: $t12 := copy($t2) - 7: $t13 := move($t7) - 8: $t14 := <=($t12, $t13) - 9: if ($t14) goto 10 else goto 16 + var $t25: bool + var $t26: &vector + var $t27: u64 + var $t28: &vector + var $t29: u64 + var $t30: u64 + var $t31: vector + var $t32: string::String + 0: $t6 := move($t0) + 1: $t7 := borrow_field.bytes($t6) + 2: $t4 := $t7 + 3: $t8 := copy($t4) + 4: $t9 := vector::length($t8) + 5: $t5 := $t9 + 6: $t10 := copy($t2) + 7: $t11 := move($t5) + 8: $t12 := <=($t10, $t11) + 9: if ($t12) goto 10 else goto 34 10: label L1 - 11: $t15 := copy($t1) - 12: $t16 := copy($t2) - 13: $t17 := <=($t15, $t16) - 14: $t3 := $t17 - 15: goto 20 - 16: label L0 - 17: $t18 := false - 18: $t3 := $t18 - 19: goto 20 - 20: label L2 - 21: $t19 := move($t3) - 22: if ($t19) goto 23 else goto 29 - 23: label L4 - 24: $t20 := copy($t6) - 25: $t21 := copy($t1) - 26: $t22 := string::internal_is_char_boundary($t20, $t21) - 27: $t4 := $t22 - 28: goto 33 - 29: label L3 - 30: $t23 := false - 31: $t4 := $t23 - 32: goto 33 - 33: label L5 - 34: $t24 := move($t4) - 35: if ($t24) goto 36 else goto 42 - 36: label L7 - 37: $t25 := copy($t6) - 38: $t26 := copy($t2) - 39: $t27 := string::internal_is_char_boundary($t25, $t26) - 40: $t5 := $t27 - 41: goto 46 - 42: label L6 - 43: $t28 := false - 44: $t5 := $t28 - 45: goto 46 - 46: label L8 - 47: $t29 := move($t5) - 48: if ($t29) goto 49 else goto 51 - 49: label L10 - 50: goto 56 - 51: label L9 - 52: $t30 := move($t6) - 53: destroy($t30) - 54: $t31 := 2 - 55: abort($t31) - 56: label L11 - 57: $t32 := move($t6) - 58: $t33 := move($t1) - 59: $t34 := move($t2) - 60: $t35 := string::internal_sub_string($t32, $t33, $t34) - 61: $t36 := pack string::String($t35) - 62: return $t36 + 11: $t13 := copy($t1) + 12: $t14 := copy($t2) + 13: $t15 := <=($t13, $t14) + 14: if ($t15) goto 15 else goto 30 + 15: label L3 + 16: $t16 := copy($t4) + 17: $t17 := copy($t1) + 18: $t18 := string::internal_is_char_boundary($t16, $t17) + 19: if ($t18) goto 20 else goto 26 + 20: label L5 + 21: $t19 := copy($t4) + 22: $t20 := copy($t2) + 23: $t21 := string::internal_is_char_boundary($t19, $t20) + 24: $t3 := $t21 + 25: goto 38 + 26: label L4 + 27: $t22 := false + 28: $t3 := $t22 + 29: goto 38 + 30: label L2 + 31: $t23 := false + 32: $t3 := $t23 + 33: goto 38 + 34: label L0 + 35: $t24 := false + 36: $t3 := $t24 + 37: goto 38 + 38: label L6 + 39: $t25 := move($t3) + 40: if ($t25) goto 41 else goto 43 + 41: label L8 + 42: goto 48 + 43: label L7 + 44: $t26 := move($t4) + 45: destroy($t26) + 46: $t27 := 2 + 47: abort($t27) + 48: label L9 + 49: $t28 := move($t4) + 50: $t29 := move($t1) + 51: $t30 := move($t2) + 52: $t31 := string::internal_sub_string($t28, $t29, $t30) + 53: $t32 := pack string::String($t31) + 54: return $t32 } @@ -4248,12 +4236,12 @@ public fun string::bytes($t0|s: string::String): vector { [variant baseline] public fun string::substring($t0|s: string::String, $t1|i: u64, $t2|j: u64): string::String { var $t3|tmp#$3: bool - var $t4|tmp#$4: bool - var $t5|tmp#$5: bool - var $t6|bytes#1#0: vector - var $t7|l#1#0: u64 - var $t8: vector - var $t9: u64 + var $t4|bytes#1#0: vector + var $t5|l#1#0: u64 + var $t6: vector + var $t7: u64 + var $t8: bool + var $t9: bool var $t10: bool var $t11: bool var $t12: bool @@ -4261,43 +4249,41 @@ public fun string::substring($t0|s: string::String, $t1|i: u64, $t2|j: u64): str var $t14: u64 var $t15: vector var $t16: string::String - 0: $t8 := get_field.bytes($t0) - 1: $t9 := vector::length($t8) - 2: $t10 := <=($t2, $t9) - 3: if ($t10) goto 4 else goto 7 + 0: $t6 := get_field.bytes($t0) + 1: $t7 := vector::length($t6) + 2: $t8 := <=($t2, $t7) + 3: if ($t8) goto 4 else goto 21 4: label L1 - 5: $t3 := <=($t1, $t2) - 6: goto 10 - 7: label L0 - 8: $t11 := false - 9: $t3 := $t11 - 10: label L2 - 11: if ($t3) goto 12 else goto 15 - 12: label L4 - 13: $t4 := string::internal_is_char_boundary($t8, $t1) - 14: goto 18 - 15: label L3 - 16: $t12 := false - 17: $t4 := $t12 - 18: label L5 - 19: if ($t4) goto 20 else goto 23 - 20: label L7 - 21: $t5 := string::internal_is_char_boundary($t8, $t2) - 22: goto 26 - 23: label L6 - 24: $t13 := false - 25: $t5 := $t13 + 5: $t9 := <=($t1, $t2) + 6: if ($t9) goto 7 else goto 17 + 7: label L3 + 8: $t10 := string::internal_is_char_boundary($t6, $t1) + 9: if ($t10) goto 10 else goto 13 + 10: label L5 + 11: $t3 := string::internal_is_char_boundary($t6, $t2) + 12: goto 24 + 13: label L4 + 14: $t11 := false + 15: $t3 := $t11 + 16: goto 24 + 17: label L2 + 18: $t12 := false + 19: $t3 := $t12 + 20: goto 24 + 21: label L0 + 22: $t13 := false + 23: $t3 := $t13 + 24: label L6 + 25: if ($t3) goto 26 else goto 28 26: label L8 - 27: if ($t5) goto 28 else goto 30 - 28: label L10 - 29: goto 33 - 30: label L9 - 31: $t14 := 2 - 32: abort($t14) - 33: label L11 - 34: $t15 := string::internal_sub_string($t8, $t1, $t2) - 35: $t16 := pack string::String($t15) - 36: return $t16 + 27: goto 31 + 28: label L7 + 29: $t14 := 2 + 30: abort($t14) + 31: label L9 + 32: $t15 := string::internal_sub_string($t6, $t1, $t2) + 33: $t16 := pack string::String($t15) + 34: return $t16 } diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.move b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.move index a0f97ccdc06..74b62f00829 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.move +++ b/external-crates/move/crates/move-stackless-bytecode/tests/borrow/hyper_edge.move @@ -5,7 +5,7 @@ // dep: ../move-stdlib/sources/string.move // dep: ../move-stdlib/sources/vector.move -module 0x2::Collection { +module 0x7::Collection { public struct Collection has drop { items: vector, owner: address, @@ -23,8 +23,8 @@ module 0x2::Collection { } } -module 0x2::Test { - use 0x2::Collection; +module 0x8::Test { + use 0x7::Collection; public struct Token has drop { value: u64 } diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_internal_refs.move b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_internal_refs.move index 15df8e2cbee..69664580c89 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_internal_refs.move +++ b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_internal_refs.move @@ -1,4 +1,4 @@ -module 0x1::LeakInternalRefs { +module 0x6::LeakInternalRefs { public struct S { f: u64, g: u64 } diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.exp b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.exp index 30333879c28..a12c7aae4d3 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.exp +++ b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.exp @@ -831,30 +831,6 @@ public fun vector::swap_remove<#0>($t0|v: &mut vector<#0>, $t1|i: u64): #0 { } -[variant baseline] -fun ReturnRefsIntoVec::return_vec_index_immut($t0|v: &vector): &u64 { - var $t1: &vector - var $t2: u64 - var $t3: &u64 - 0: $t1 := move($t0) - 1: $t2 := 0 - 2: $t3 := vector::borrow($t1, $t2) - 3: return $t3 -} - - -[variant baseline] -fun ReturnRefsIntoVec::return_vec_index_mut($t0|v: &mut vector): &mut u64 { - var $t1: &mut vector - var $t2: u64 - var $t3: &mut u64 - 0: $t1 := move($t0) - 1: $t2 := 0 - 2: $t3 := vector::borrow_mut($t1, $t2) - 3: return $t3 -} - - [variant baseline] public fun option::borrow<#0>($t0|t: &option::Option<#0>): � { var $t1: &option::Option<#0> @@ -2468,102 +2444,90 @@ public fun string::bytes($t0|s: &string::String): &vector { [variant baseline] public fun string::substring($t0|s: &string::String, $t1|i: u64, $t2|j: u64): string::String { var $t3|tmp#$3: bool - var $t4|tmp#$4: bool - var $t5|tmp#$5: bool - var $t6|bytes#1#0: &vector - var $t7|l#1#0: u64 - var $t8: &string::String - var $t9: &vector - var $t10: &vector + var $t4|bytes#1#0: &vector + var $t5|l#1#0: u64 + var $t6: &string::String + var $t7: &vector + var $t8: &vector + var $t9: u64 + var $t10: u64 var $t11: u64 - var $t12: u64 + var $t12: bool var $t13: u64 - var $t14: bool - var $t15: u64 - var $t16: u64 - var $t17: bool + var $t14: u64 + var $t15: bool + var $t16: &vector + var $t17: u64 var $t18: bool - var $t19: bool - var $t20: &vector - var $t21: u64 + var $t19: &vector + var $t20: u64 + var $t21: bool var $t22: bool var $t23: bool var $t24: bool - var $t25: &vector - var $t26: u64 - var $t27: bool - var $t28: bool - var $t29: bool - var $t30: &vector - var $t31: u64 - var $t32: &vector - var $t33: u64 - var $t34: u64 - var $t35: vector - var $t36: string::String - 0: $t8 := move($t0) - 1: $t9 := borrow_field.bytes($t8) - 2: $t6 := $t9 - 3: $t10 := copy($t6) - 4: $t11 := vector::length($t10) - 5: $t7 := $t11 - 6: $t12 := copy($t2) - 7: $t13 := move($t7) - 8: $t14 := <=($t12, $t13) - 9: if ($t14) goto 10 else goto 16 + var $t25: bool + var $t26: &vector + var $t27: u64 + var $t28: &vector + var $t29: u64 + var $t30: u64 + var $t31: vector + var $t32: string::String + 0: $t6 := move($t0) + 1: $t7 := borrow_field.bytes($t6) + 2: $t4 := $t7 + 3: $t8 := copy($t4) + 4: $t9 := vector::length($t8) + 5: $t5 := $t9 + 6: $t10 := copy($t2) + 7: $t11 := move($t5) + 8: $t12 := <=($t10, $t11) + 9: if ($t12) goto 10 else goto 34 10: label L1 - 11: $t15 := copy($t1) - 12: $t16 := copy($t2) - 13: $t17 := <=($t15, $t16) - 14: $t3 := $t17 - 15: goto 20 - 16: label L0 - 17: $t18 := false - 18: $t3 := $t18 - 19: goto 20 - 20: label L2 - 21: $t19 := move($t3) - 22: if ($t19) goto 23 else goto 29 - 23: label L4 - 24: $t20 := copy($t6) - 25: $t21 := copy($t1) - 26: $t22 := string::internal_is_char_boundary($t20, $t21) - 27: $t4 := $t22 - 28: goto 33 - 29: label L3 - 30: $t23 := false - 31: $t4 := $t23 - 32: goto 33 - 33: label L5 - 34: $t24 := move($t4) - 35: if ($t24) goto 36 else goto 42 - 36: label L7 - 37: $t25 := copy($t6) - 38: $t26 := copy($t2) - 39: $t27 := string::internal_is_char_boundary($t25, $t26) - 40: $t5 := $t27 - 41: goto 46 - 42: label L6 - 43: $t28 := false - 44: $t5 := $t28 - 45: goto 46 - 46: label L8 - 47: $t29 := move($t5) - 48: if ($t29) goto 49 else goto 51 - 49: label L10 - 50: goto 56 - 51: label L9 - 52: $t30 := move($t6) - 53: destroy($t30) - 54: $t31 := 2 - 55: abort($t31) - 56: label L11 - 57: $t32 := move($t6) - 58: $t33 := move($t1) - 59: $t34 := move($t2) - 60: $t35 := string::internal_sub_string($t32, $t33, $t34) - 61: $t36 := pack string::String($t35) - 62: return $t36 + 11: $t13 := copy($t1) + 12: $t14 := copy($t2) + 13: $t15 := <=($t13, $t14) + 14: if ($t15) goto 15 else goto 30 + 15: label L3 + 16: $t16 := copy($t4) + 17: $t17 := copy($t1) + 18: $t18 := string::internal_is_char_boundary($t16, $t17) + 19: if ($t18) goto 20 else goto 26 + 20: label L5 + 21: $t19 := copy($t4) + 22: $t20 := copy($t2) + 23: $t21 := string::internal_is_char_boundary($t19, $t20) + 24: $t3 := $t21 + 25: goto 38 + 26: label L4 + 27: $t22 := false + 28: $t3 := $t22 + 29: goto 38 + 30: label L2 + 31: $t23 := false + 32: $t3 := $t23 + 33: goto 38 + 34: label L0 + 35: $t24 := false + 36: $t3 := $t24 + 37: goto 38 + 38: label L6 + 39: $t25 := move($t3) + 40: if ($t25) goto 41 else goto 43 + 41: label L8 + 42: goto 48 + 43: label L7 + 44: $t26 := move($t4) + 45: destroy($t26) + 46: $t27 := 2 + 47: abort($t27) + 48: label L9 + 49: $t28 := move($t4) + 50: $t29 := move($t1) + 51: $t30 := move($t2) + 52: $t31 := string::internal_sub_string($t28, $t29, $t30) + 53: $t32 := pack string::String($t31) + 54: return $t32 } @@ -2684,6 +2648,30 @@ public fun string::utf8($t0|bytes: vector): string::String { 11: return $t5 } + +[variant baseline] +fun ReturnRefsIntoVec::return_vec_index_immut($t0|v: &vector): &u64 { + var $t1: &vector + var $t2: u64 + var $t3: &u64 + 0: $t1 := move($t0) + 1: $t2 := 0 + 2: $t3 := vector::borrow($t1, $t2) + 3: return $t3 +} + + +[variant baseline] +fun ReturnRefsIntoVec::return_vec_index_mut($t0|v: &mut vector): &mut u64 { + var $t1: &mut vector + var $t2: u64 + var $t3: &mut u64 + 0: $t1 := move($t0) + 1: $t2 := 0 + 2: $t3 := vector::borrow_mut($t1, $t2) + 3: return $t3 +} + ============ after pipeline `escape_analysis` ================ [variant baseline] @@ -3517,30 +3505,6 @@ public fun vector::swap_remove<#0>($t0|v: &mut vector<#0>, $t1|i: u64): #0 { } -[variant baseline] -fun ReturnRefsIntoVec::return_vec_index_immut($t0|v: &vector): &u64 { - var $t1: &vector - var $t2: u64 - var $t3: &u64 - 0: $t1 := move($t0) - 1: $t2 := 0 - 2: $t3 := vector::borrow($t1, $t2) - 3: return $t3 -} - - -[variant baseline] -fun ReturnRefsIntoVec::return_vec_index_mut($t0|v: &mut vector): &mut u64 { - var $t1: &mut vector - var $t2: u64 - var $t3: &mut u64 - 0: $t1 := move($t0) - 1: $t2 := 0 - 2: $t3 := vector::borrow_mut($t1, $t2) - 3: return $t3 -} - - [variant baseline] public fun option::borrow<#0>($t0|t: &option::Option<#0>): � { var $t1: &option::Option<#0> @@ -5154,102 +5118,90 @@ public fun string::bytes($t0|s: &string::String): &vector { [variant baseline] public fun string::substring($t0|s: &string::String, $t1|i: u64, $t2|j: u64): string::String { var $t3|tmp#$3: bool - var $t4|tmp#$4: bool - var $t5|tmp#$5: bool - var $t6|bytes#1#0: &vector - var $t7|l#1#0: u64 - var $t8: &string::String - var $t9: &vector - var $t10: &vector + var $t4|bytes#1#0: &vector + var $t5|l#1#0: u64 + var $t6: &string::String + var $t7: &vector + var $t8: &vector + var $t9: u64 + var $t10: u64 var $t11: u64 - var $t12: u64 + var $t12: bool var $t13: u64 - var $t14: bool - var $t15: u64 - var $t16: u64 - var $t17: bool + var $t14: u64 + var $t15: bool + var $t16: &vector + var $t17: u64 var $t18: bool - var $t19: bool - var $t20: &vector - var $t21: u64 + var $t19: &vector + var $t20: u64 + var $t21: bool var $t22: bool var $t23: bool var $t24: bool - var $t25: &vector - var $t26: u64 - var $t27: bool - var $t28: bool - var $t29: bool - var $t30: &vector - var $t31: u64 - var $t32: &vector - var $t33: u64 - var $t34: u64 - var $t35: vector - var $t36: string::String - 0: $t8 := move($t0) - 1: $t9 := borrow_field.bytes($t8) - 2: $t6 := $t9 - 3: $t10 := copy($t6) - 4: $t11 := vector::length($t10) - 5: $t7 := $t11 - 6: $t12 := copy($t2) - 7: $t13 := move($t7) - 8: $t14 := <=($t12, $t13) - 9: if ($t14) goto 10 else goto 16 + var $t25: bool + var $t26: &vector + var $t27: u64 + var $t28: &vector + var $t29: u64 + var $t30: u64 + var $t31: vector + var $t32: string::String + 0: $t6 := move($t0) + 1: $t7 := borrow_field.bytes($t6) + 2: $t4 := $t7 + 3: $t8 := copy($t4) + 4: $t9 := vector::length($t8) + 5: $t5 := $t9 + 6: $t10 := copy($t2) + 7: $t11 := move($t5) + 8: $t12 := <=($t10, $t11) + 9: if ($t12) goto 10 else goto 34 10: label L1 - 11: $t15 := copy($t1) - 12: $t16 := copy($t2) - 13: $t17 := <=($t15, $t16) - 14: $t3 := $t17 - 15: goto 20 - 16: label L0 - 17: $t18 := false - 18: $t3 := $t18 - 19: goto 20 - 20: label L2 - 21: $t19 := move($t3) - 22: if ($t19) goto 23 else goto 29 - 23: label L4 - 24: $t20 := copy($t6) - 25: $t21 := copy($t1) - 26: $t22 := string::internal_is_char_boundary($t20, $t21) - 27: $t4 := $t22 - 28: goto 33 - 29: label L3 - 30: $t23 := false - 31: $t4 := $t23 - 32: goto 33 - 33: label L5 - 34: $t24 := move($t4) - 35: if ($t24) goto 36 else goto 42 - 36: label L7 - 37: $t25 := copy($t6) - 38: $t26 := copy($t2) - 39: $t27 := string::internal_is_char_boundary($t25, $t26) - 40: $t5 := $t27 - 41: goto 46 - 42: label L6 - 43: $t28 := false - 44: $t5 := $t28 - 45: goto 46 - 46: label L8 - 47: $t29 := move($t5) - 48: if ($t29) goto 49 else goto 51 - 49: label L10 - 50: goto 56 - 51: label L9 - 52: $t30 := move($t6) - 53: destroy($t30) - 54: $t31 := 2 - 55: abort($t31) - 56: label L11 - 57: $t32 := move($t6) - 58: $t33 := move($t1) - 59: $t34 := move($t2) - 60: $t35 := string::internal_sub_string($t32, $t33, $t34) - 61: $t36 := pack string::String($t35) - 62: return $t36 + 11: $t13 := copy($t1) + 12: $t14 := copy($t2) + 13: $t15 := <=($t13, $t14) + 14: if ($t15) goto 15 else goto 30 + 15: label L3 + 16: $t16 := copy($t4) + 17: $t17 := copy($t1) + 18: $t18 := string::internal_is_char_boundary($t16, $t17) + 19: if ($t18) goto 20 else goto 26 + 20: label L5 + 21: $t19 := copy($t4) + 22: $t20 := copy($t2) + 23: $t21 := string::internal_is_char_boundary($t19, $t20) + 24: $t3 := $t21 + 25: goto 38 + 26: label L4 + 27: $t22 := false + 28: $t3 := $t22 + 29: goto 38 + 30: label L2 + 31: $t23 := false + 32: $t3 := $t23 + 33: goto 38 + 34: label L0 + 35: $t24 := false + 36: $t3 := $t24 + 37: goto 38 + 38: label L6 + 39: $t25 := move($t3) + 40: if ($t25) goto 41 else goto 43 + 41: label L8 + 42: goto 48 + 43: label L7 + 44: $t26 := move($t4) + 45: destroy($t26) + 46: $t27 := 2 + 47: abort($t27) + 48: label L9 + 49: $t28 := move($t4) + 50: $t29 := move($t1) + 51: $t30 := move($t2) + 52: $t31 := string::internal_sub_string($t28, $t29, $t30) + 53: $t32 := pack string::String($t31) + 54: return $t32 } @@ -5369,3 +5321,27 @@ public fun string::utf8($t0|bytes: vector): string::String { 10: $t5 := pack string::String($t4) 11: return $t5 } + + +[variant baseline] +fun ReturnRefsIntoVec::return_vec_index_immut($t0|v: &vector): &u64 { + var $t1: &vector + var $t2: u64 + var $t3: &u64 + 0: $t1 := move($t0) + 1: $t2 := 0 + 2: $t3 := vector::borrow($t1, $t2) + 3: return $t3 +} + + +[variant baseline] +fun ReturnRefsIntoVec::return_vec_index_mut($t0|v: &mut vector): &mut u64 { + var $t1: &mut vector + var $t2: u64 + var $t3: &mut u64 + 0: $t1 := move($t0) + 1: $t2 := 0 + 2: $t3 := vector::borrow_mut($t1, $t2) + 3: return $t3 +} diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.move b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.move index 7c6ac51c537..353de1931b7 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.move +++ b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_into_vec.move @@ -5,7 +5,7 @@ // dep: ../move-stdlib/sources/string.move // dep: ../move-stdlib/sources/vector.move -module 0x1::ReturnRefsIntoVec { +module 0x6::ReturnRefsIntoVec { // should not complain fun return_vec_index_immut(v: &vector): &u64 { diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_safe.move b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_safe.move index 0398e90191b..00c5c69b3cc 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_safe.move +++ b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/return_refs_safe.move @@ -1,4 +1,4 @@ -module 0x1::ReturnRefsSafe { +module 0x6::ReturnRefsSafe { // Make sure the analysis doesn't complain about returning // refs to formals or their children diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/struct_eq.move b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/struct_eq.move index 216c7b3074f..49d4ed5fd4e 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/struct_eq.move +++ b/external-crates/move/crates/move-stackless-bytecode/tests/escape_analysis/struct_eq.move @@ -1,4 +1,4 @@ -module 0x1::StructEq { +module 0x6::StructEq { public struct S { f: u64 } diff --git a/external-crates/move/crates/move-stackless-bytecode/tests/testsuite.rs b/external-crates/move/crates/move-stackless-bytecode/tests/testsuite.rs index 5b02a12d062..b24f169a24e 100644 --- a/external-crates/move/crates/move-stackless-bytecode/tests/testsuite.rs +++ b/external-crates/move/crates/move-stackless-bytecode/tests/testsuite.rs @@ -8,7 +8,7 @@ use std::path::Path; use anyhow::anyhow; use codespan_reporting::{diagnostic::Severity, term::termcolor::Buffer}; use move_command_line_common::testing::EXP_EXT; -use move_compiler::{diagnostics::WarningFilters, shared::PackagePaths}; +use move_compiler::{diagnostics::warning_filters::WarningFiltersBuilder, shared::PackagePaths}; use move_model::{model::GlobalEnv, options::ModelBuilderOptions, run_model_builder_with_options}; use move_prover_test_utils::{baseline_test::verify_or_update_baseline, extract_test_directives}; use move_stackless_bytecode::{ @@ -120,7 +120,7 @@ fn test_runner(path: &Path) -> datatest_stable::Result<()> { }], vec![], ModelBuilderOptions::default(), - Some(WarningFilters::unused_warnings_filter_for_test()), + Some(WarningFiltersBuilder::unused_warnings_filter_for_test()), )?; let out = if env.has_errors() { let mut error_writer = Buffer::no_color(); diff --git a/external-crates/move/crates/move-stdlib/src/lib.rs b/external-crates/move/crates/move-stdlib/src/lib.rs index 96d99544f7f..4609edfd2e2 100644 --- a/external-crates/move/crates/move-stdlib/src/lib.rs +++ b/external-crates/move/crates/move-stdlib/src/lib.rs @@ -6,10 +6,8 @@ use std::{collections::BTreeMap, path::PathBuf}; use log::LevelFilter; -use move_command_line_common::{ - address::NumericalAddress, - files::{extension_equals, find_filenames, MOVE_EXTENSION}, -}; +use move_command_line_common::files::{MOVE_EXTENSION, extension_equals, find_filenames}; +use move_core_types::parsing::address::NumericalAddress; #[cfg(test)] mod tests; diff --git a/external-crates/move/crates/move-trace-format/Cargo.toml b/external-crates/move/crates/move-trace-format/Cargo.toml new file mode 100644 index 00000000000..1df80526546 --- /dev/null +++ b/external-crates/move/crates/move-trace-format/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "move-trace-format" +version = "0.0.1" +authors = ["Move Core Contributors"] +edition = "2021" +license = "Apache-2.0" +description = "Move Trace Format" + +[dependencies] +anyhow.workspace = true +arbitrary = { workspace = true, optional = true, features = ["derive"] } +move-binary-format.workspace = true +move-core-types.workspace = true +move-proc-macros.workspace = true +proptest = { workspace = true, optional = true } +proptest-derive = { workspace = true, optional = true } +ref-cast.workspace = true +serde.workspace = true +variant_count.workspace = true + +# wasm support (requires js feature of getrandom) +getrandom = { workspace = true, features = ["js"], optional = true } +serde_json = { workspace = true, features = ["arbitrary_precision"] } + +[dev-dependencies] +move-core-types = { workspace = true, features = ["fuzzing"] } +proptest.workspace = true +proptest-derive.workspace = true + +[features] +default = [] +fuzzing = [ + "proptest", + "proptest-derive", + "arbitrary", + "move-core-types/fuzzing", +] +wasm = ["getrandom"] diff --git a/external-crates/move/crates/move-trace-format/src/format.rs b/external-crates/move/crates/move-trace-format/src/format.rs new file mode 100644 index 00000000000..8c228798816 --- /dev/null +++ b/external-crates/move/crates/move-trace-format/src/format.rs @@ -0,0 +1,389 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// IDEA: Post trace analysis -- report when values are dropped. + +use crate::interface::{NopTracer, Tracer, Writer}; +use move_binary_format::{ + file_format::{Bytecode, FunctionDefinitionIndex as BinaryFunctionDefinitionIndex}, + file_format_common::instruction_opcode, +}; +use move_core_types::{ + annotated_value::MoveValue, + language_storage::{ModuleId, TypeTag}, +}; +use serde::Serialize; +use std::fmt::Display; + +/// An index into the trace. This should be used when referring to locations in the trace. +/// Otherwise, a `usize` should be used when referring to indices that are not in the trace. +pub type TraceIndex = usize; +pub type TraceVersion = u64; + +/// The current version of the trace format. +const TRACE_VERSION: TraceVersion = 1; + +/// A Location is a valid root for a reference. This can either be a local in a frame, a stack +/// value, or a reference into another location (e.g., vec[0][2]). +/// +/// Note that we track aliasing through the locations so you can always trace back to the root +/// value for the reference. +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +pub enum Location { + // Local index in a frame. The frame is identified by the index in the trace where it was created. + // The `usize` is the index into the locals of the frame. + Local(TraceIndex, usize), + // An indexed location. This is a reference into another location (e.g., due to a borrow field, + // or a reference into a vector). + Indexed(Box, usize), + // A global reference. + // Identified by the location in the trace where it was introduced. + Global(TraceIndex), +} + +/// A Read event. This represents a read from a location, with the value read and whether the value +/// was moved or not. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct Read { + pub location: Location, + pub root_value_read: TraceValue, + pub moved: bool, +} + +/// A Write event. This represents a write to a location with the value written and a snapshot of +/// the value that was written. Note that the `root_value_after_write` is a snapshot of the +/// _entire_ (root) value that was written after the write. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct Write { + pub location: Location, + pub root_value_after_write: TraceValue, +} + +/// A TraceValue is a value in the standard MoveValue domain + references. +/// References hold their own snapshot of the root value they point to, along with the rooted path to +/// the value that they reference within that snapshot. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub enum TraceValue { + RuntimeValue { + value: MoveValue, + }, + ImmRef { + location: Location, + // Snapshot of the root value. + snapshot: Box, + }, + MutRef { + location: Location, + // Snapshot of the root value. + snapshot: Box, + }, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub enum RefType { + Imm, + Mut, +} + +/// Type tag with references. This is a type tag that also supports references. +/// if ref_type is None, this is a value type. If ref_type is Some, this is a reference type of the +/// given reference type. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct TypeTagWithRefs { + pub type_: TypeTag, + pub ref_type: Option, +} + +/// A `Frame` represents a stack frame in the Move VM and a given instantiation of a function. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct Frame { + // The frame id is the offset in the trace where this frame was opened. + pub frame_id: TraceIndex, + pub function_name: String, + pub module: ModuleId, + // External pointer out into the module -- the `FunctionDefinitionIndex` in the module. + pub binary_member_index: u16, + pub type_instantiation: Vec, + pub parameters: Vec, + pub return_types: Vec, + pub locals_types: Vec, + pub is_native: bool, +} + +/// An instruction effect is a single effect of an instruction. This can be a push/pop of a value +/// or a reference to a value, or a read/write of a value. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub enum Effect { + // Pop a value off the stack (pre-effect only) + Pop(TraceValue), + // Read a value from a location (pre-effect only) + Read(Read), + + // Push a value on the stack (post-effect only) + Push(TraceValue), + // Write a value to a location (post-effect only) + Write(Write), + + // A data load Effect + DataLoad(DataLoad), + + // An execution error occured + ExecutionError(String), +} + +/// Represent a data load event. This is a load of a value from storage. We only record loads by +/// reference in the trace, and we snapshot the value at the reference location at the time of load +/// and record its global reference ID (i.e., the location in the trace at which it was loaded). +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct DataLoad { + pub ref_type: RefType, + pub location: Location, + pub snapshot: MoveValue, +} + +/// A TraceEvent is a single event in the Move VM, external events can also be interleaved in the +/// trace. MoveVM events, are well structured, and can be a frame event or an instruction event. +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +pub enum TraceEvent { + OpenFrame { + frame: Box, + gas_left: u64, + }, + CloseFrame { + frame_id: TraceIndex, + return_: Vec, + gas_left: u64, + }, + Instruction { + type_parameters: Vec, + pc: u16, + gas_left: u64, + instruction: Box, + }, + Effect(Box), + External(Box), +} + +#[derive(Serialize, Debug, Clone, Eq, PartialEq)] +pub struct MoveTrace { + pub version: TraceVersion, + pub events: Vec, +} + +/// The Move trace format. The custom tracer is not serialized, but the events are. +/// This is the format that the Move VM will output traces in, and the `tracer` can output +/// additional events to the trace. +pub struct MoveTraceBuilder { + pub tracer: Box, + + pub trace: MoveTrace, +} + +impl TraceValue { + pub fn snapshot(&self) -> &MoveValue { + match self { + TraceValue::ImmRef { snapshot, .. } | TraceValue::MutRef { snapshot, .. } => snapshot, + TraceValue::RuntimeValue { value } => value, + } + } + + pub fn value_mut(&mut self) -> Option<&mut MoveValue> { + match self { + TraceValue::RuntimeValue { value, .. } => Some(value), + _ => None, + } + } + + pub fn location(&self) -> Option<&Location> { + match self { + TraceValue::ImmRef { location, .. } | TraceValue::MutRef { location, .. } => { + Some(location) + } + _ => None, + } + } +} + +impl MoveTrace { + pub fn new() -> Self { + Self { + version: TRACE_VERSION, + events: vec![], + } + } + + pub fn to_json(&self) -> serde_json::Value { + serde_json::to_value(self).unwrap() + } +} + +impl MoveTraceBuilder { + /// Create a new `MoveTraceBuilder` with no additional tracing. + pub fn new() -> Self { + Self { + tracer: Box::new(NopTracer), + trace: MoveTrace::new(), + } + } + + /// Create a new `MoveTraceBuilder` with a custom `tracer`. + pub fn new_with_tracer(tracer: Box) -> Self { + Self { + tracer, + trace: MoveTrace::new(), + } + } + + /// Consume the `MoveTraceBuilder` and return the `MoveTrace` that has been built by it. + pub fn into_trace(self) -> MoveTrace { + self.trace + } + + /// Get the current offset in the `MoveTrace` that is being built. + pub fn current_trace_offset(&self) -> TraceIndex { + self.trace.events.len() + } + + /// Record an `OpenFrame` event in the trace. + pub fn open_frame( + &mut self, + frame_id: TraceIndex, + binary_member_index: BinaryFunctionDefinitionIndex, + name: String, + module: ModuleId, + parameters: Vec, + type_instantiation: Vec, + return_types: Vec, + locals_types: Vec, + is_native: bool, + gas_left: u64, + ) { + let frame = Box::new(Frame { + frame_id, + function_name: name, + module, + binary_member_index: binary_member_index.0, + type_instantiation, + parameters, + return_types, + locals_types, + is_native, + }); + self.push_event(TraceEvent::OpenFrame { frame, gas_left }); + } + + /// Record a `CloseFrame` event in the trace. + pub fn close_frame(&mut self, frame_id: TraceIndex, return_: Vec, gas_left: u64) { + self.push_event(TraceEvent::CloseFrame { + frame_id, + return_, + gas_left, + }); + } + + /// Record an `Instruction` event in the trace along with the effects of the instruction. + pub fn instruction( + &mut self, + instruction: &Bytecode, + type_parameters: Vec, + effects: Vec, + gas_left: u64, + pc: u16, + ) { + self.push_event(TraceEvent::Instruction { + type_parameters, + pc, + gas_left, + instruction: Box::new(format!("{:?}", instruction_opcode(instruction))), + }); + for effect in effects { + self.push_event(TraceEvent::Effect(Box::new(effect))); + } + } + + /// Push an `Effect` event to the trace. + pub fn effect(&mut self, effect: Effect) { + self.push_event(TraceEvent::Effect(Box::new(effect))); + } + + // All events pushed to the trace are first pushed, and then the tracer is notified of the + // event. + fn push_event(&mut self, event: TraceEvent) { + self.trace.events.push(event.clone()); + self.tracer.notify(&event, Writer(&mut self.trace)); + } +} + +impl Display for TraceValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TraceValue::RuntimeValue { value } => { + write!(f, "{:#}", value) + } + TraceValue::ImmRef { location, snapshot } => { + write!(f, "&{} {:#}", location, snapshot) + } + TraceValue::MutRef { location, snapshot } => { + write!(f, "&mut {} {:#}", location, snapshot) + } + } + } +} + +impl Display for Location { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Location::Local(frame_idx, idx) => { + write!(f, "l{idx}@{frame_idx}") + } + Location::Indexed(loc, offset) => { + write!(f, "{loc}[{offset}]") + } + Location::Global(id) => { + write!(f, "g{}", id) + } + } + } +} + +impl Display for Effect { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Effect::Pop(value) => { + write!(f, "Pop {}", value) + } + Effect::Push(value) => { + write!(f, "Push {}", value) + } + Effect::Read(Read { + location, + root_value_read: value_read, + moved, + }) => { + let arrow = if *moved { "==>" } else { "-->" }; + write!(f, "{location} {arrow} {value_read}") + } + Effect::Write(Write { + location, + root_value_after_write: value_written, + }) => { + write!(f, "{location} <-- {value_written}") + } + Effect::ExecutionError(error_string) => { + write!(f, "ExecutionError: {error_string}") + } + Effect::DataLoad(DataLoad { + ref_type, + location, + snapshot, + }) => { + let ref_type = match ref_type { + RefType::Imm => "&", + RefType::Mut => "&mut", + }; + write!(f, "g{ref_type}{location} ~~> {snapshot}") + } + } + } +} diff --git a/external-crates/move/crates/move-trace-format/src/interface.rs b/external-crates/move/crates/move-trace-format/src/interface.rs new file mode 100644 index 00000000000..d0eeff72ece --- /dev/null +++ b/external-crates/move/crates/move-trace-format/src/interface.rs @@ -0,0 +1,40 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crate::format::{MoveTrace, TraceEvent, TraceVersion}; +use serde::Serialize; + +/// This is meant to be an internal tracing interface for the VM, and should only be implemented +/// and used if you are _sure_ that you want/need to use it. Generally you should use the output +/// trace format for any analysis or debugging purposes. This should only be used if you want to +/// add custom tracing data to the VM's traces that cannot be added using other means or +/// post-processing. +pub trait Tracer { + /// Notify the tracer of a new event in the VM. This is called for every event that is emitted, + /// and immediatlye _after_ the `event` has been added to the trace held inside of the `writer`. + fn notify(&mut self, event: &TraceEvent, writer: Writer<'_>); +} + +pub struct NopTracer; +impl Tracer for NopTracer { + fn notify(&mut self, _event: &TraceEvent, _writer: Writer<'_>) {} +} + +/// A writer that allows you to push custom events to the trace but encapsulates the trace so that +/// non-external events cannot be accidentally added. +pub struct Writer<'a>(pub(crate) &'a mut MoveTrace); + +impl<'a> Writer<'a> { + /// Emit an external event into the trace. + pub fn push(&mut self, e: T) { + self.0.events.push(TraceEvent::External(Box::new( + serde_json::to_value(e).unwrap(), + ))); + } + + /// Get the current version of the trace. + pub fn trace_version(&mut self) -> TraceVersion { + self.0.version + } +} diff --git a/external-crates/move/crates/move-trace-format/src/lib.rs b/external-crates/move/crates/move-trace-format/src/lib.rs new file mode 100644 index 00000000000..972d97becf6 --- /dev/null +++ b/external-crates/move/crates/move-trace-format/src/lib.rs @@ -0,0 +1,7 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pub mod format; +pub mod interface; +pub mod memory_tracer; diff --git a/external-crates/move/crates/move-trace-format/src/memory_tracer.rs b/external-crates/move/crates/move-trace-format/src/memory_tracer.rs new file mode 100644 index 00000000000..93afa0d7589 --- /dev/null +++ b/external-crates/move/crates/move-trace-format/src/memory_tracer.rs @@ -0,0 +1,197 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! This module contains the implementation of the memory tracer. The memory tracer is a tracer +//! that takes a stream of trace events, and uses these events to create a snapshot of the memory +//! state (operand stack, locals, and globals) at each point in time during execution. +//! +//! The memory tracer then emits `External` events with the current VM state for every instruction, +//! and open/close frame event that is has built up. +//! +//! The memory tracer is useful for debugging, and as an example of how to build up this +//! state for more advanced analysis and also using the custom tracing trait. + +use crate::{ + format::{DataLoad, Effect, Location, Read, TraceEvent, TraceIndex, TraceValue, Write}, + interface::{Tracer, Writer}, +}; +use core::fmt; +use move_core_types::annotated_value::MoveValue; +use std::collections::BTreeMap; + +#[derive(Debug, Clone)] +pub struct TraceState { + // Tracks "global memory" state (i.e., references out in to global memory/references returned + // from native functions). + pub loaded_state: BTreeMap, + // The current state (i.e., values) of the VM's operand stack. + pub operand_stack: Vec, + // The current call stack indexed by frame id. Maps from the frame id to the current state of + // the frame's locals. The bool indicates if the frame is native or not. + pub call_stack: BTreeMap, bool)>, +} + +impl TraceState { + pub fn new() -> Self { + Self { + loaded_state: BTreeMap::new(), + operand_stack: vec![], + call_stack: BTreeMap::new(), + } + } + + /// Apply an event to the state machine and update the locals state accordingly. + fn apply_event(&mut self, event: &TraceEvent) { + match event { + TraceEvent::OpenFrame { frame, .. } => { + let mut locals = BTreeMap::new(); + for (i, p) in frame.parameters.iter().enumerate() { + // NB: parameters are passed directly, so we just pop to make sure they aren't also + // left on the operand stack. For the initial call, these pops may (should) fail, but that + // is fine as we already have the values in the parameter list. + self.operand_stack.pop(); + locals.insert(i, p.clone()); + } + + self.call_stack + .insert(frame.frame_id, (locals, frame.is_native)); + } + TraceEvent::CloseFrame { .. } => { + self.call_stack + .pop_last() + .expect("Unbalanced call stack in memory tracer -- this should never happen"); + } + TraceEvent::Effect(ef) => match &**ef { + Effect::ExecutionError(_) => (), + Effect::Push(value) => { + self.operand_stack.push(value.clone()); + } + Effect::Pop(_) => { + self.operand_stack.pop().expect( + "Tried to pop off the empty operand stack -- this should never happen", + ); + } + Effect::Read(Read { + location, + root_value_read: _, + moved, + }) => { + if *moved { + match location { + Location::Local(frame_idx, idx) => { + let frame = self.call_stack.get_mut(frame_idx).unwrap(); + frame.0.remove(idx); + } + Location::Indexed(..) => { + panic!("Cannot move from indexed location"); + } + Location::Global(..) => { + panic!("Cannot move from global location"); + } + } + } + } + Effect::Write(Write { + location, + root_value_after_write: value_written, + }) => match location { + Location::Local(frame_idx, idx) => { + let frame = self.call_stack.get_mut(frame_idx).unwrap(); + frame.0.insert(*idx, value_written.clone()); + } + Location::Indexed(location, _idx) => { + let val = self.get_mut_location(location); + *val = value_written.clone().snapshot().clone(); + } + Location::Global(id) => { + let val = self.loaded_state.get_mut(id).unwrap(); + *val = value_written.snapshot().clone(); + } + }, + Effect::DataLoad(DataLoad { + location, snapshot, .. + }) => { + let Location::Global(id) = location else { + unreachable!("Dataload by reference must have a global location"); + }; + self.loaded_state.insert(*id, snapshot.clone()); + } + }, + // External events are treated opaqeuly + TraceEvent::External(_) => (), + // Instructions + TraceEvent::Instruction { .. } => (), + } + } + + /// Given a reference "location" return a mutable reference to the value it points to so that + /// it can be updated. + fn get_mut_location(&mut self, location: &Location) -> &mut MoveValue { + match location { + Location::Local(frame_idx, idx) => { + let frame = self.call_stack.get_mut(frame_idx).unwrap(); + frame.0.get_mut(idx).unwrap().value_mut().unwrap() + } + Location::Indexed(loc, _offset) => self.get_mut_location(loc), + Location::Global(id) => self.loaded_state.get_mut(id).unwrap(), + } + } +} + +impl Tracer for TraceState { + fn notify(&mut self, event: &TraceEvent, mut write: Writer<'_>) { + self.apply_event(event); + // We only emit the state when we hit a non-effect internal event. This coincides with + // emitting the current state of the VM before each instruction/function call. + match event { + TraceEvent::Instruction { .. } + | TraceEvent::OpenFrame { .. } + | TraceEvent::CloseFrame { .. } => { + write.push(self.to_string()); + } + _ => (), + } + } +} + +impl fmt::Display for TraceState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.loaded_state.is_empty() { + writeln!(f, "Loaded state:")?; + for (id, v) in &self.loaded_state { + writeln!( + f, + "\t{}: {}", + id, + format!("{:#}", v).replace('\n', "\n\t ") + )?; + } + } + + if !self.operand_stack.is_empty() { + writeln!(f, "Operand stack:")?; + for (i, v) in self.operand_stack.iter().enumerate() { + writeln!(f, "\t{}: {}", i, format!("{:#}", v).replace('\n', "\n\t "))?; + } + } + + if !self.call_stack.is_empty() { + writeln!(f, "Call stack:")?; + for (i, (frame, _)) in self.call_stack.iter() { + if !frame.is_empty() { + writeln!(f, "\tFrame {}:", i)?; + for (j, v) in frame.iter() { + writeln!( + f, + "\t\t{}: {}", + j, + format!("{:#}", v).replace('\n', "\n\t\t") + )?; + } + } + } + } + Ok(()) + } +} diff --git a/external-crates/move/crates/move-transactional-test-runner/src/framework.rs b/external-crates/move/crates/move-transactional-test-runner/src/framework.rs index 0cefbaacc7d..e3965d8f898 100644 --- a/external-crates/move/crates/move-transactional-test-runner/src/framework.rs +++ b/external-crates/move/crates/move-transactional-test-runner/src/framework.rs @@ -14,30 +14,32 @@ use std::{ sync::Arc, }; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; use async_trait::async_trait; use clap::Parser; use move_binary_format::file_format::CompiledModule; use move_bytecode_source_map::{mapping::SourceMapping, source_map::SourceMap}; use move_command_line_common::{ - address::ParsedAddress, env::read_bool_env_var, files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}, - testing::{add_update_baseline_fix, format_diff, read_env_update_baseline, EXP_EXT}, - types::ParsedType, - values::{ParsableValue, ParsedValue}, + testing::{EXP_EXT, add_update_baseline_fix, format_diff, read_env_update_baseline}, }; use move_compiler::{ + FullyCompiledProgram, compiled_unit::AnnotatedCompiledUnit, - diagnostics::{Diagnostics, WarningFilters}, + diagnostics::{Diagnostics, warning_filters::WarningFiltersBuilder}, editions::{Edition, Flavor}, - shared::{files::MappedFiles, NumericalAddress, PackageConfig}, - FullyCompiledProgram, + shared::{NumericalAddress, PackageConfig, files::MappedFiles}, }; use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, language_storage::{ModuleId, TypeTag}, + parsing::{ + address::ParsedAddress, + types::ParsedType, + values::{ParsableValue, ParsedValue}, + }, }; use move_disassembler::disassembler::{Disassembler, DisassemblerOptions}; use move_ir_types::location::Spanned; @@ -46,8 +48,8 @@ use move_vm_runtime::session::SerializedReturnValues; use tempfile::NamedTempFile; use crate::tasks::{ - taskify, InitCommand, PrintBytecodeCommand, PublishCommand, RunCommand, SyntaxChoice, - TaskCommand, TaskInput, + InitCommand, PrintBytecodeCommand, PublishCommand, RunCommand, SyntaxChoice, TaskCommand, + TaskInput, taskify, }; pub struct CompiledState { @@ -660,7 +662,7 @@ pub fn compile_source_units( // struct types on purpose and generating warnings for all of them does not // make much sense (and there would be a lot of them!) so let's suppress // them function warnings, so let's suppress these - let warning_filter = WarningFilters::unused_warnings_filter_for_test(); + let warning_filter = WarningFiltersBuilder::unused_warnings_filter_for_test(); let (mut files, comments_and_compiler_res) = move_compiler::Compiler::from_files( None, vec![file_name.as_ref().to_str().unwrap().to_owned()], diff --git a/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs b/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs index 420ddc0035a..b6c944b1a45 100644 --- a/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs +++ b/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs @@ -7,16 +7,18 @@ use std::{convert::TryInto, fmt::Debug, path::Path, str::FromStr}; -use anyhow::{anyhow, bail, Result}; +use anyhow::{Result, anyhow, bail}; use clap::*; -use move_command_line_common::{ - address::ParsedAddress, - files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}, - types::ParsedType, - values::{ParsableValue, ParsedValue}, -}; +use move_command_line_common::files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}; use move_compiler::shared::NumericalAddress; -use move_core_types::identifier::Identifier; +use move_core_types::{ + identifier::Identifier, + parsing::{ + address::ParsedAddress, + types::ParsedType, + values::{ParsableValue, ParsedValue}, + }, +}; use tempfile::NamedTempFile; #[derive(Debug)] diff --git a/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs b/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs index 5fba0dfc5f3..dc175a93ae5 100644 --- a/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs +++ b/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs @@ -12,10 +12,9 @@ use move_binary_format::{ errors::{Location, VMError, VMResult}, CompiledModule, }; -use move_command_line_common::{ - address::ParsedAddress, files::verify_and_create_named_address_mapping, -}; +use move_command_line_common::files::verify_and_create_named_address_mapping; use move_compiler::{editions::Edition, shared::PackagePaths, FullyCompiledProgram}; +use move_core_types::parsing::address::ParsedAddress; use move_core_types::{ account_address::AccountAddress, identifier::IdentStr, @@ -301,7 +300,7 @@ impl SimpleVMTestAdapter { } } -static PRECOMPILED_MOVE_STDLIB: Lazy = Lazy::new(|| { +pub static PRECOMPILED_MOVE_STDLIB: Lazy = Lazy::new(|| { let program_res = move_compiler::construct_pre_compiled_lib( vec![PackagePaths { name: None, diff --git a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/example.move b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/example.move index 814a83e5261..90eb4b882ea 100644 --- a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/example.move +++ b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/example.move @@ -2,7 +2,7 @@ //# run -module 0x1::m { +module 0x5::m { fun main() {} } @@ -30,7 +30,7 @@ module A::N { //# run --args 0 -module 0x2::m { +module 0x6::m { entry fun main(v: u64) { helper(v) } @@ -41,7 +41,7 @@ module 0x2::m { //# run --args 42 --syntax=mvir -module 0x3.m { +module 0x7.m { import 0x42.N; entry foo(v: u64) { label b0: diff --git a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.exp b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.exp index 7cdb1a383ce..00e1910f1c0 100644 --- a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.exp +++ b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.exp @@ -1,5 +1,5 @@ processed 4 tasks task 3, line 21: -//# run 42::M::test -return values: { 42 } +//# run 43::M::test +return values: { 43 } diff --git a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.move b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.move index aef3acd8611..a2f3b4edabb 100644 --- a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.move +++ b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/named_addresses_in_commands.move @@ -1,9 +1,9 @@ -//# init --addresses A=42 +//# init --addresses A=43 //# run --args @A module 0x42::m { fun main(a: &address) { - assert!(*a == @42, 1000); + assert!(*a == @43, 1000); } } @@ -14,8 +14,8 @@ module A::M { } public fun test(): Foo { - Foo { x: 42 } + Foo { x: 43 } } } -//# run 42::M::test +//# run 43::M::test diff --git a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.exp b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.exp index ffe8b4bf239..6935d223798 100644 --- a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.exp +++ b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.exp @@ -5,27 +5,23 @@ task 0, lines 1-7: // Move bytecode v6 module 42.M { - - - entry foo() { B0: 0: Ret - } + } + task 1, lines 9-13: //# print-bytecode // Move bytecode v6 -module 42.M { - - - +module 43.M { entry foo() { B0: 0: Ret - } + } + diff --git a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.move b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.move index 054f68f813c..ef1952472bc 100644 --- a/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.move +++ b/external-crates/move/crates/move-transactional-test-runner/tests/vm_test_harness/print_bytecode.move @@ -7,7 +7,7 @@ label b0: } //# print-bytecode -module 0x42::M { +module 0x43::M { entry fun foo() { } } diff --git a/external-crates/move/crates/move-unit-test/Cargo.toml b/external-crates/move/crates/move-unit-test/Cargo.toml index 4ba2fbaabb0..bd60e803104 100644 --- a/external-crates/move/crates/move-unit-test/Cargo.toml +++ b/external-crates/move/crates/move-unit-test/Cargo.toml @@ -26,6 +26,7 @@ move-core-types.workspace = true move-ir-types.workspace = true move-stdlib-natives = { workspace = true, features = ["testing"] } move-symbol-pool.workspace = true +move-trace-format.workspace = true move-vm-profiler.workspace = true move-vm-runtime = { workspace = true, features = ["testing"] } move-vm-test-utils.workspace = true @@ -46,4 +47,4 @@ name = "move_unit_test_testsuite" harness = false [features] -gas-profiler = [] +tracing = [] diff --git a/external-crates/move/crates/move-unit-test/src/lib.rs b/external-crates/move/crates/move-unit-test/src/lib.rs index 978c5b16e14..00570a03b36 100644 --- a/external-crates/move/crates/move-unit-test/src/lib.rs +++ b/external-crates/move/crates/move-unit-test/src/lib.rs @@ -10,16 +10,16 @@ pub mod test_runner; use std::{collections::BTreeMap, io::Write, marker::Send, sync::Mutex}; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use clap::*; +use move_binary_format::CompiledModule; use move_command_line_common::files::verify_and_create_named_address_mapping; use move_compiler::{ - self, + self, Compiler, Flags, PASS_CFGIR, compiled_unit::NamedCompiledModule, diagnostics, shared::{self, NumericalAddress}, unit_test::{self, TestPlan}, - Compiler, Flags, PASS_CFGIR, }; use move_core_types::language_storage::ModuleId; use move_vm_runtime::native_functions::NativeFunctionTable; @@ -35,6 +35,7 @@ const DEFAULT_RAND_ITERS: u64 = 10; const RAND_NUM_ITERS_FLAG: &str = "rand-num-iters"; const SEED_FLAG: &str = "seed"; +const TRACE_FLAG: &str = "trace-execution"; #[derive(Debug, Parser, Clone)] #[clap(author, version, about)] @@ -71,6 +72,15 @@ pub struct UnitTestingConfig { )] pub dep_files: Vec, + /// Bytecode dependency files + #[clap( + name = "bytecode-depencencies", + long = "bytecode-dependencies", + num_args(1..), + action = clap::ArgAction::Append, + )] + pub bytecode_deps_files: Vec, + /// Report test statistics at the end of testing. CSV report generated if /// 'csv' passed #[clap(name = "report-statistics", short = 's', long = "statistics")] @@ -116,6 +126,10 @@ pub struct UnitTestingConfig { // WARNING: You should only use this flag for debugging and meta-testing purposes! #[clap(skip)] pub deterministic_generation: bool, + + // Enable tracing for tests + #[clap(long = TRACE_FLAG, value_name = "PATH")] + pub trace_execution: Option>, } fn format_module_id( @@ -140,12 +154,14 @@ impl UnitTestingConfig { report_stacktrace_on_abort: false, source_files: vec![], dep_files: vec![], + bytecode_deps_files: vec![], verbose: false, list: false, named_address_values: vec![], rand_num_iters: Some(DEFAULT_RAND_ITERS), seed: None, deterministic_generation: false, + trace_execution: None, } } @@ -162,6 +178,7 @@ impl UnitTestingConfig { &self, source_files: Vec, deps: Vec, + bytecode_deps_files: Vec, ) -> Option { let addresses = verify_and_create_named_address_mapping(self.named_address_values.clone()).ok()?; @@ -174,7 +191,7 @@ impl UnitTestingConfig { let (_, compiler) = diagnostics::unwrap_or_report_pass_diagnostics(&files, comments_and_compiler_res); - let (mut compiler, cfgir) = compiler.into_ast(); + let (compiler, cfgir) = compiler.into_ast(); let compilation_env = compiler.compilation_env(); let test_plan = unit_test::plan_builder::construct_test_plan(compilation_env, None, &cfgir); let mapped_files = compilation_env.mapped_files().clone(); @@ -184,16 +201,30 @@ impl UnitTestingConfig { diagnostics::unwrap_or_report_pass_diagnostics(&files, compilation_result); diagnostics::report_warnings(&files, warnings); let units: Vec<_> = units.into_iter().map(|unit| unit.named_module).collect(); - test_plan.map(|tests| TestPlan::new(tests, mapped_files, units)) + + let bytecode_deps_modules = bytecode_deps_files + .iter() + .map(|path| { + let bytes = std::fs::read(path).unwrap(); + CompiledModule::deserialize_with_defaults(&bytes).unwrap() + }) + .collect::>(); + + test_plan.map(|tests| TestPlan::new(tests, mapped_files, units, bytecode_deps_modules)) } /// Build a test plan from a unit test config pub fn build_test_plan(&self) -> Option { let deps = self.dep_files.clone(); - let TestPlan { module_info, .. } = self.compile_to_test_plan(deps.clone(), vec![])?; + let TestPlan { module_info, .. } = + self.compile_to_test_plan(deps.clone(), vec![], vec![])?; - let mut test_plan = self.compile_to_test_plan(self.source_files.clone(), deps)?; + let mut test_plan = self.compile_to_test_plan( + self.source_files.clone(), + deps, + self.bytecode_deps_files.clone(), + )?; test_plan.module_info.extend(module_info); Some(test_plan) } @@ -242,6 +273,11 @@ impl UnitTestingConfig { } writeln!(shared_writer.lock().unwrap(), "Running Move unit tests")?; + let trace_location = match &self.trace_execution { + Some(None) => Some("traces".to_string()), + Some(Some(path)) => Some(path.clone()), + None => None, + }; let mut test_runner = TestRunner::new( self.gas_limit.unwrap_or(DEFAULT_EXECUTION_BOUND), self.num_threads, @@ -249,6 +285,7 @@ impl UnitTestingConfig { self.seed, rand_num_iters, self.deterministic_generation, + trace_location, test_plan, native_function_table, cost_table, diff --git a/external-crates/move/crates/move-unit-test/src/test_reporter.rs b/external-crates/move/crates/move-unit-test/src/test_reporter.rs index 674dd7ea49f..b02b73940b6 100644 --- a/external-crates/move/crates/move-unit-test/src/test_reporter.rs +++ b/external-crates/move/crates/move-unit-test/src/test_reporter.rs @@ -16,9 +16,11 @@ use move_core_types::{ vm_status::{StatusCode, StatusType}, }; use move_ir_types::location::Loc; +use move_trace_format::format::MoveTrace; use std::{ collections::{BTreeMap, BTreeSet}, io::{Result, Write}, + path::Path, sync::Mutex, time::Duration, }; @@ -41,7 +43,7 @@ pub enum FailureReason { Property(String), } -#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct TestFailure { pub test_run_info: TestRunInfo, pub vm_error: Option, @@ -49,10 +51,11 @@ pub struct TestFailure { pub prng_seed: Option, } -#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct TestRunInfo { pub elapsed_time: Duration, pub instructions_executed: u64, + pub trace: Option, } type TestRuns = BTreeMap>; @@ -69,11 +72,34 @@ pub struct TestResults { test_plan: TestPlan, } +fn write_string_to_file(filepath: &str, content: &str) -> std::io::Result<()> { + let path = Path::new(filepath); + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent)?; + } + let mut file = std::fs::File::create(path)?; + file.write_all(content.as_bytes())?; + Ok(()) +} + impl TestRunInfo { - pub fn new(elapsed_time: Duration, instructions_executed: u64) -> Self { + pub fn new( + elapsed_time: Duration, + instructions_executed: u64, + trace: Option, + ) -> Self { Self { elapsed_time, instructions_executed, + trace, + } + } + + pub fn save_trace(&self, path: &str) -> Result<()> { + if let Some(trace) = &self.trace { + write_string_to_file(path, &format!("{}", trace.to_json())) + } else { + Ok(()) } } } diff --git a/external-crates/move/crates/move-unit-test/src/test_runner.rs b/external-crates/move/crates/move-unit-test/src/test_runner.rs index 6f406018c55..1921dbfee41 100644 --- a/external-crates/move/crates/move-unit-test/src/test_runner.rs +++ b/external-crates/move/crates/move-unit-test/src/test_runner.rs @@ -22,19 +22,20 @@ use move_core_types::{ effects::ChangeSet, identifier::IdentStr, language_storage::{ModuleId, TypeTag}, - runtime_value::{serialize_values, MoveValue}, + runtime_value::{MoveValue, serialize_values}, u256::U256, vm_status::StatusCode, }; +use move_trace_format::format::MoveTraceBuilder; use move_vm_runtime::{ move_vm::MoveVM, native_extensions::NativeContextExtensions, native_functions::NativeFunctionTable, }; use move_vm_test_utils::{ - gas_schedule::{unit_cost_schedule, CostTable, Gas, GasStatus}, InMemoryStorage, + gas_schedule::{CostTable, Gas, GasStatus, unit_cost_schedule}, }; -use rand::{rngs::StdRng, Rng, SeedableRng}; +use rand::{Rng, SeedableRng, rngs::StdRng}; use rayon::prelude::*; use crate::{ @@ -54,6 +55,7 @@ pub struct SharedTestingConfig { prng_seed: Option, num_iters: u64, deterministic_generation: bool, + trace_location: Option, } pub struct TestRunner { @@ -66,13 +68,11 @@ pub struct TestRunner { /// tests fn setup_test_storage<'a>( modules: impl Iterator, + bytecode_deps_modules: impl Iterator, ) -> Result { let mut storage = InMemoryStorage::new(); - let modules = Modules::new(modules); - for module in modules - .compute_dependency_graph() - .compute_topological_order()? - { + let modules = Modules::new(modules.chain(bytecode_deps_modules)); + for module in modules.compute_topological_order()? { let module_id = module.self_id(); let mut module_bytes = Vec::new(); module.serialize_with_version(module.version, &mut module_bytes)?; @@ -118,14 +118,27 @@ impl TestRunner { prng_seed: Option, num_iters: u64, deterministic_generation: bool, + trace_location: Option, tests: TestPlan, // TODO: maybe we should require the clients to always pass in a list of native functions // so we don't have to make assumptions about their gas parameters. native_function_table: Option, cost_table: Option, ) -> Result { + // If we want to trace the execution, check that the tracing compilation feature + // is enabled, otherwise we won't generate a trace. + move_vm_profiler::tracing_feature_disabled! { + if trace_location.is_some() { + return Err(anyhow::anyhow!( + "Tracing is enabled but the binary was not compiled with the `tracing` \ + feature flag set. Rebuild binary with `--features tracing`" + )); + } + }; + let modules = tests.module_info.values().map(|info| &info.module); - let starting_storage_state = setup_test_storage(modules)?; + let starting_storage_state = + setup_test_storage(modules, tests.bytecode_deps_modules.iter())?; let native_function_table = native_function_table.unwrap_or_else(|| { move_stdlib_natives::all_natives( AccountAddress::from_hex_literal("0x1").unwrap(), @@ -150,6 +163,7 @@ impl TestRunner { prng_seed, num_iters, deterministic_generation, + trace_location, }, num_threads, tests, @@ -254,10 +268,18 @@ impl SharedTestingConfig { ) { let move_vm = MoveVM::new(self.native_function_table.clone()).unwrap(); let extensions = extensions::new_extensions(); + + let mut move_tracer = MoveTraceBuilder::new(); + let tracer = if self.trace_location.is_some() { + Some(&mut move_tracer) + } else { + None + }; + let mut session = move_vm.new_session_with_extensions(&self.starting_storage_state, extensions); let mut gas_meter = GasStatus::new(&self.cost_table, Gas::new(self.execution_bound)); - move_vm_profiler::gas_profiler_feature_enabled! { + move_vm_profiler::tracing_feature_enabled! { use move_vm_profiler::GasProfiler; use move_vm_types::gas::GasMeter; gas_meter.set_profiler(GasProfiler::init_default_cfg( @@ -267,15 +289,16 @@ impl SharedTestingConfig { } // TODO: collect VM logs if the verbose flag (i.e, `self.verbose`) is set - let now = Instant::now(); - let serialized_return_values_result = session.execute_function_bypass_visibility( - &test_plan.module_id, - IdentStr::new(function_name).unwrap(), - vec![], // no ty args, at least for now - serialize_values(arguments.iter()), - &mut gas_meter, - ); + let serialized_return_values_result = session + .execute_function_bypass_visibility_with_tracer_if_enabled( + &test_plan.module_id, + IdentStr::new(function_name).unwrap(), + vec![], // no ty args, at least for now + serialize_values(arguments.iter()), + &mut gas_meter, + tracer, + ); let mut return_result = serialized_return_values_result.map(|res| { res.return_values .into_iter() @@ -287,6 +310,11 @@ impl SharedTestingConfig { err.remove_exec_state(); } } + let trace = if self.trace_location.is_some() { + Some(move_tracer.into_trace()) + } else { + None + }; let test_run_info = TestRunInfo::new( now.elapsed(), // TODO(Gas): This doesn't look quite right... @@ -296,6 +324,7 @@ impl SharedTestingConfig { .checked_sub(gas_meter.remaining_gas()) .unwrap() .into(), + trace, ); match session.finish_with_extensions().0 { Ok((cs, extensions)) => (Ok(cs), Ok(extensions), return_result, test_run_info), @@ -417,6 +446,25 @@ impl SharedTestingConfig { let (_cs_result, _ext_result, exec_result, test_run_info) = self.execute_via_move_vm(test_plan, function_name, arguments); + // Save the trace -- one per test -- for each test that we have traced (and if + // tracing is enabled). + if let Some(location) = &self.trace_location { + let trace_file_location = format!( + "{}/{}__{}{}.json", + location, + format_module_id(output.test_info, &output.test_plan.module_id).replace("::", "__"), + function_name, + if let Some(seed) = prng_seed { + format!("_seed_{}", seed) + } else { + "".to_string() + } + ); + if let Err(e) = test_run_info.save_trace(&trace_file_location) { + eprintln!("Unable to save trace to {trace_file_location} -- {:?}", e); + } + } + match exec_result { Err(err) => { let sub_status = err.sub_status().and_then(|status| { diff --git a/external-crates/move/crates/move-unit-test/tests/sources/A.move b/external-crates/move/crates/move-unit-test/tests/sources/A.move index 75d32f13466..98b029b1447 100644 --- a/external-crates/move/crates/move-unit-test/tests/sources/A.move +++ b/external-crates/move/crates/move-unit-test/tests/sources/A.move @@ -1,4 +1,4 @@ -module 0x1::A { +module 0x6::A { #[test] fun a() { } diff --git a/external-crates/move/crates/move-unit-test/tests/sources/B.move b/external-crates/move/crates/move-unit-test/tests/sources/B.move index 8e37c3b6086..2707c3f2500 100644 --- a/external-crates/move/crates/move-unit-test/tests/sources/B.move +++ b/external-crates/move/crates/move-unit-test/tests/sources/B.move @@ -1,6 +1,6 @@ -module 0x1::B { +module 0x6::B { #[test_only] - use 0x1::A; + use 0x6::A; #[test] fun b() { } @@ -11,13 +11,13 @@ module 0x1::B { } #[test] - #[expected_failure(abort_code = 0, location=0x1::A)] + #[expected_failure(abort_code = 0, location=0x6::A)] public fun b_other0() { A::a_call() } #[test] - #[expected_failure(abort_code = 1, location=0x1::A)] + #[expected_failure(abort_code = 1, location=0x6::A)] public fun b_other1() { A::a_call() } diff --git a/external-crates/move/crates/move-unit-test/tests/test_deps.rs b/external-crates/move/crates/move-unit-test/tests/test_deps.rs index abbfa6f84a8..4eb1297456f 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_deps.rs +++ b/external-crates/move/crates/move-unit-test/tests/test_deps.rs @@ -30,7 +30,7 @@ fn test_deps_arent_tested() { let mut iter = test_plan.module_tests.into_iter(); let (mod_id, _) = iter.next().unwrap(); let expected_mod_id = ModuleId::new( - AccountAddress::from_hex_literal("0x1").unwrap(), + AccountAddress::from_hex_literal("0x6").unwrap(), Identifier::new("B").unwrap(), ); assert!(mod_id == expected_mod_id); diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.exp index f259c8e2605..fd3f5da0d15 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.exp @@ -1,5 +1,5 @@ Running Move unit tests -[ PASS ] 0x1::M::correct_address -[ PASS ] 0x1::M::correct_addresses -[ PASS ] 0x1::M::wrong_address +[ PASS ] 0x6::M::correct_address +[ PASS ] 0x6::M::correct_addresses +[ PASS ] 0x6::M::wrong_address Test result: OK. Total tests: 3; passed: 3; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.move b/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.move index bb56acb2f98..a8375f7b236 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/address_args.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { const ErrorCode: u64 = 100; #[test(a = @0x42)] diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.exp index bdcc00dec37..e2e58bf110a 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.exp @@ -1,6 +1,6 @@ Running Move unit tests -[ PASS ] 0x1::M::u64_add_overflow -[ PASS ] 0x1::M::u64_div_by_zero -[ PASS ] 0x1::M::u64_mul_overflow -[ PASS ] 0x1::M::u64_sub_underflow +[ PASS ] 0x6::M::u64_add_overflow +[ PASS ] 0x6::M::u64_div_by_zero +[ PASS ] 0x6::M::u64_mul_overflow +[ PASS ] 0x6::M::u64_sub_underflow Test result: OK. Total tests: 4; passed: 4; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.move b/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.move index d4a9cb199d7..ada0e4b772c 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/arithmetic_errors.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { #[test] #[expected_failure] fun u64_sub_underflow() { diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.exp index d30bf07e8c3..4a96ee000ca 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.exp @@ -1,4 +1,4 @@ Running Move unit tests -[ PASS ] 0x1::M::test_local_abort -[ PASS ] 0x1::M::test_local_abort_invalid_code +[ PASS ] 0x6::M::test_local_abort +[ PASS ] 0x6::M::test_local_abort_invalid_code Test result: OK. Total tests: 2; passed: 2; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.move b/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.move index 956b0698ccb..464af3ba3f3 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/const_abort.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { const ErrorCode: u64 = 42; const DifferentErrorCode: u64 = 42; diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.exp index 06604b21341..ae41e61ef9d 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.exp @@ -1,4 +1,4 @@ Running Move unit tests -[ PASS ] 0x1::M::make_sure_not_other_number -[ PASS ] 0x1::M::make_sure_number_matches +[ PASS ] 0x7::M::make_sure_not_other_number +[ PASS ] 0x7::M::make_sure_number_matches Test result: OK. Total tests: 2; passed: 2; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.move b/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.move index 8876a204089..8a8eabb521a 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/construct_data.move @@ -1,4 +1,4 @@ -module 0x1::B { +module 0x6::B { #[test_only] public struct TestingStruct has drop { x: u64 } @@ -13,9 +13,9 @@ module 0x1::B { } } -module 0x1::M { +module 0x7::M { #[test_only] - use 0x1::B; + use 0x6::B; #[test] fun make_sure_number_matches() { diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.exp index 6e7e37be0ed..58e8e8902db 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.exp @@ -1,19 +1,19 @@ Running Move unit tests -[ FAIL ] 0x1::B::failing_test -[ PASS ] 0x1::M::dummy_test +[ PASS ] 0x6::M::dummy_test +[ FAIL ] 0x7::B::failing_test Test failures: -Failures in 0x1::B: +Failures in 0x7::B: ┌── failing_test ────── │ error[E11001]: test failure │ ┌─ cross_module_aborts.move:4:9 │ │ │ 3 │ public fun this_aborts() { -│ │ ----------- In this function in 0x1::M +│ │ ----------- In this function in 0x6::M │ 4 │ abort 0 -│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x1::M rooted here +│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x6::M rooted here │ │ │ stack trace diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.move b/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.move index 2ab099fc48c..21a395f8319 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/cross_module_aborts.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { #[test_only] public fun this_aborts() { abort 0 @@ -8,10 +8,10 @@ module 0x1::M { fun dummy_test() { } } -module 0x1::B { +module 0x7::B { #[test_only] - use 0x1::M; + use 0x6::M; #[test] fun failing_test() { diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.exp index 3a1e8fabffb..0d2c2319fad 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.exp @@ -1,3 +1,3 @@ Running Move unit tests -[ PASS ] 0x1::M::do_nothing +[ PASS ] 0x6::M::do_nothing Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.move b/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.move index 15fe4a72923..3b6b4c40055 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/do_nothing.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { #[test] fun do_nothing() {} } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.exp index feefbb17334..3b0cb6f4004 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.exp @@ -1,10 +1,10 @@ Running Move unit tests -[ FAIL ] 0x1::M::fail -[ FAIL ] 0x1::M::fail_with_code +[ FAIL ] 0x6::M::fail +[ FAIL ] 0x6::M::fail_with_code Test failures: -Failures in 0x1::M: +Failures in 0x6::M: ┌── fail ────── │ Test did not error as expected diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.move b/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.move index fc94d10c562..c9919182986 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/expected_abort_no_abort.move @@ -1,7 +1,7 @@ -module 0x1::M { +module 0x6::M { #[test, expected_failure] fun fail() { } - #[test, expected_failure(abort_code=0, location=0x1::M)] + #[test, expected_failure(abort_code=0, location=0x6::M)] fun fail_with_code() { } } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.exp index e62e47b3f03..854c6b05823 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.exp @@ -1,20 +1,20 @@ Running Move unit tests -[ PASS ] 0x1::A::native_abort_good_right_code -[ FAIL ] 0x1::A::native_abort_good_wrong_code -[ FAIL ] 0x1::A::native_abort_unexpected_abort +[ PASS ] 0x6::A::native_abort_good_right_code +[ FAIL ] 0x6::A::native_abort_good_wrong_code +[ FAIL ] 0x6::A::native_abort_unexpected_abort Test failures: -Failures in 0x1::A: +Failures in 0x6::A: ┌── native_abort_good_wrong_code ────── │ error[E11001]: test failure │ ┌─ native_abort.move:11:9 │ │ │ 10 │ fun native_abort_good_wrong_code() { -│ │ ---------------------------- In this function in 0x1::A +│ │ ---------------------------- In this function in 0x6::A │ 11 │ vector::borrow(&vector::empty(), 1); -│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test did not error as expected. Expected test to give a vector operation error with sub-status 0 originating in the module 0x1::A but instead it gave a vector operation error with sub-status 1 originating in the module 0x1::A rooted here +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test did not error as expected. Expected test to give a vector operation error with sub-status 0 originating in the module 0x6::A but instead it gave a vector operation error with sub-status 1 originating in the module 0x6::A rooted here │ │ └────────────────── @@ -25,9 +25,9 @@ Failures in 0x1::A: │ ┌─ native_abort.move:5:9 │ │ │ 4 │ fun native_abort_unexpected_abort() { -│ │ ----------------------------- In this function in 0x1::A +│ │ ----------------------------- In this function in 0x6::A │ 5 │ vector::borrow(&vector::empty(), 1); -│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a vector operation error with sub-status 1 originating in the module 0x1::A rooted here +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a vector operation error with sub-status 1 originating in the module 0x6::A rooted here │ │ └────────────────── diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.move b/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.move index 53203d68f1a..6f5ebf4b53a 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/native_abort.move @@ -1,4 +1,4 @@ -module 0x1::A { +module 0x6::A { #[test] fun native_abort_unexpected_abort() { @@ -6,13 +6,13 @@ module 0x1::A { } #[test] - #[expected_failure(vector_error, minor_status=0, location=0x1::A)] + #[expected_failure(vector_error, minor_status=0, location=0x6::A)] fun native_abort_good_wrong_code() { vector::borrow(&vector::empty(), 1); } #[test] - #[expected_failure(vector_error, minor_status=1, location=0x1::A)] + #[expected_failure(vector_error, minor_status=1, location=0x6::A)] fun native_abort_good_right_code() { vector::borrow(&vector::empty(), 1); } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.exp index 09223ba5484..e844b1cbe3d 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.exp @@ -1,13 +1,13 @@ Running Move unit tests -[ FAIL ] 0x1::M::non_existent_native +[ FAIL ] 0x6::M::non_existent_native Test failures: -Failures in 0x1::M: +Failures in 0x6::M: ┌── non_existent_native ────── │ INTERNAL TEST ERROR: INTERNAL VM INVARIANT VIOLATION. -│ Test was not expected to error, but it gave a UNEXPECTED_VERIFIER_ERROR (code 2017) error originating in the module 0x1::M rooted here +│ Test was not expected to error, but it gave a UNEXPECTED_VERIFIER_ERROR (code 2017) error originating in the module 0x6::M rooted here └────────────────── Test result: FAILED. Total tests: 1; passed: 0; failed: 1 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.move b/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.move index b623fa3170c..ba90e05eedc 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/non_exsistent_native.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { native fun foo(); #[test] diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.exp index 74debdf69ea..405edfc621a 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.exp @@ -1,5 +1,5 @@ Running Move unit tests -[ PASS ] 0x1::Module::other_module_aborts -[ PASS ] 0x1::Module::tests_a -[ PASS ] 0x1::Module::tests_aborts +[ PASS ] 0x7::Module::other_module_aborts +[ PASS ] 0x7::Module::tests_a +[ PASS ] 0x7::Module::tests_aborts Test result: OK. Total tests: 3; passed: 3; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.move b/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.move index 40d74305afa..1a4cac0c9d0 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/proposal_test.move @@ -1,12 +1,12 @@ // This is a test based on the example in the unit testing proposal -module 0x1::TestonlyModule { +module 0x6::TestonlyModule { #[test_only] public fun aborts() { abort 42 } } -module 0x1::Module { +module 0x7::Module { fun a(a: u64): bool { a == 10 } @@ -21,7 +21,7 @@ module 0x1::Module { // A test-only module import #[test_only] - use 0x1::TestonlyModule; + use 0x6::TestonlyModule; // A test only struct. This will only be included in test mode. #[test_only, allow(unused_field)] @@ -41,7 +41,7 @@ module 0x1::Module { } #[test] - #[expected_failure(abort_code=42, location=0x1::TestonlyModule)] + #[expected_failure(abort_code=42, location=0x6::TestonlyModule)] fun other_module_aborts() { TestonlyModule::aborts() } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.exp index 6a1375e6289..57b5a4fe534 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.exp @@ -1,22 +1,22 @@ Running Move unit tests -[ FAIL ] 0x1::random_test::should_fail_test_div_mod_10 -[ FAIL ] 0x1::random_test::should_fail_test_div_mod_10_2_vec -[ FAIL ] 0x1::random_test::should_fail_test_expected_failure -[ PASS ] 0x1::random_test::should_pass_test_expected_failure_pass -[ TIMEOUT ] 0x1::random_test::should_timeout_test_timeout +[ FAIL ] 0x6::random_test::should_fail_test_div_mod_10 +[ FAIL ] 0x6::random_test::should_fail_test_div_mod_10_2_vec +[ FAIL ] 0x6::random_test::should_fail_test_expected_failure +[ PASS ] 0x6::random_test::should_pass_test_expected_failure_pass +[ TIMEOUT ] 0x6::random_test::should_timeout_test_timeout Test failures: -Failures in 0x1::random_test: +Failures in 0x6::random_test: ┌── should_fail_test_div_mod_10 ────── (seed = 8) │ error[E11001]: test failure │ ┌─ random_test.move:4:11 │ │ │ 3 │ fun should_fail_test_div_mod_10(x: u64) { -│ │ --------------------------- In this function in 0x1::random_test +│ │ --------------------------- In this function in 0x6::random_test │ 4 │ x / (x % 10); -│ │ ^ Test was not expected to error, but it gave an arithmetic error originating in the module 0x1::random_test rooted here +│ │ ^ Test was not expected to error, but it gave an arithmetic error originating in the module 0x6::random_test rooted here │ │ │ This test uses randomly generated inputs. Rerun with `test should_fail_test_div_mod_10 --seed 8` to recreate this test failure. @@ -29,9 +29,9 @@ Failures in 0x1::random_test: │ ┌─ random_test.move:9:33 │ │ │ 8 │ fun should_fail_test_div_mod_10_2_vec(x: vector>) { -│ │ --------------------------------- In this function in 0x1::random_test +│ │ --------------------------------- In this function in 0x6::random_test │ 9 │ std::vector::length(&x) / (std::vector::length(&x) % 10); -│ │ ^ Test was not expected to error, but it gave an arithmetic error originating in the module 0x1::random_test rooted here +│ │ ^ Test was not expected to error, but it gave an arithmetic error originating in the module 0x6::random_test rooted here │ │ │ This test uses randomly generated inputs. Rerun with `test should_fail_test_div_mod_10_2_vec --seed 5` to recreate this test failure. diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.move b/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.move index 39824f02362..a74f9fde285 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/random_test.move @@ -1,4 +1,4 @@ -module 0x1::random_test { +module 0x6::random_test { #[random_test] fun should_fail_test_div_mod_10(x: u64) { x / (x % 10); diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.exp index b4f7f0f84b3..a8f2b110444 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.exp @@ -1,14 +1,14 @@ Running Move unit tests -[ FAIL ] 0x1::M::multi_signer_fail -[ PASS ] 0x1::M::multi_signer_pass -[ PASS ] 0x1::M::multi_signer_pass_expected_failure -[ FAIL ] 0x1::M::single_signer_fail -[ PASS ] 0x1::M::single_signer_pass -[ PASS ] 0x1::M::test_correct_signer_arg_addrs +[ FAIL ] 0x6::M::multi_signer_fail +[ PASS ] 0x6::M::multi_signer_pass +[ PASS ] 0x6::M::multi_signer_pass_expected_failure +[ FAIL ] 0x6::M::single_signer_fail +[ PASS ] 0x6::M::single_signer_pass +[ PASS ] 0x6::M::test_correct_signer_arg_addrs Test failures: -Failures in 0x1::M: +Failures in 0x6::M: ┌── multi_signer_fail ────── │ Test did not error as expected @@ -20,9 +20,9 @@ Failures in 0x1::M: │ ┌─ signer_args.move:8:9 │ │ │ 7 │ fun single_signer_fail(_a: signer) { -│ │ ------------------ In this function in 0x1::M +│ │ ------------------ In this function in 0x6::M │ 8 │ abort 0 -│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x1::M rooted here +│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x6::M rooted here │ │ └────────────────── diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.move b/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.move index 9da46ca0a99..24a82fc7e74 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/signer_args.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { #[test(_a=@0x1)] fun single_signer_pass(_a: signer) { } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.exp index 05c32d5cdd8..d9eedbe0eb1 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.exp @@ -1,22 +1,22 @@ Running Move unit tests -[ PASS ] 0x1::M::no_timeout -[ FAIL ] 0x1::M::no_timeout_fail -[ PASS ] 0x1::M::no_timeout_while_loop -[ TIMEOUT ] 0x1::M::timeout_fail -[ PASS ] 0x1::M::timeout_fail_with_expected_failure +[ PASS ] 0x6::M::no_timeout +[ FAIL ] 0x6::M::no_timeout_fail +[ PASS ] 0x6::M::no_timeout_while_loop +[ TIMEOUT ] 0x6::M::timeout_fail +[ PASS ] 0x6::M::timeout_fail_with_expected_failure Test failures: -Failures in 0x1::M: +Failures in 0x6::M: ┌── no_timeout_fail ────── │ error[E11001]: test failure │ ┌─ timeout.move:17:29 │ │ │ 17 │ fun no_timeout_fail() { abort 0 } -│ │ --------------- ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x1::M rooted here +│ │ --------------- ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x6::M rooted here │ │ │ -│ │ In this function in 0x1::M +│ │ In this function in 0x6::M │ │ └────────────────── diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move index b772e68a35d..d516c5e0beb 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { #[test] fun timeout_fail() { while (true) {} diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.exp index d8748e6bb25..a258d97e684 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.exp @@ -1,23 +1,23 @@ Running Move unit tests -[ PASS ] 0x1::M::correct_abort_code -[ PASS ] 0x1::M::just_test_failure -[ FAIL ] 0x1::M::unexpected_abort -[ FAIL ] 0x1::M::unexpected_abort_in_native_function -[ FAIL ] 0x1::M::unexpected_abort_in_other_function -[ FAIL ] 0x1::M::wrong_abort_code +[ PASS ] 0x6::M::correct_abort_code +[ PASS ] 0x6::M::just_test_failure +[ FAIL ] 0x6::M::unexpected_abort +[ FAIL ] 0x6::M::unexpected_abort_in_native_function +[ FAIL ] 0x6::M::unexpected_abort_in_other_function +[ FAIL ] 0x6::M::wrong_abort_code Test failures: -Failures in 0x1::M: +Failures in 0x6::M: ┌── unexpected_abort ────── │ error[E11001]: test failure │ ┌─ unexpected_abort.move:4:9 │ │ │ 3 │ public fun unexpected_abort() { -│ │ ---------------- In this function in 0x1::M +│ │ ---------------- In this function in 0x6::M │ 4 │ abort 0 -│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x1::M rooted here +│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0x6::M rooted here │ │ └────────────────── @@ -46,9 +46,9 @@ Failures in 0x1::M: │ ┌─ unexpected_abort.move:27:9 │ │ │ 26 │ fun abort_in_other_function() { -│ │ ----------------------- In this function in 0x1::M +│ │ ----------------------- In this function in 0x6::M │ 27 │ abort 1 -│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 1 originating in the module 0x1::M rooted here +│ │ ^^^^^^^ Test was not expected to error, but it aborted with code 1 originating in the module 0x6::M rooted here │ │ │ stack trace @@ -62,9 +62,9 @@ Failures in 0x1::M: │ ┌─ unexpected_abort.move:10:9 │ │ │ 9 │ public fun wrong_abort_code() { -│ │ ---------------- In this function in 0x1::M +│ │ ---------------- In this function in 0x6::M │ 10 │ abort 0 -│ │ ^^^^^^^ Test did not error as expected. Expected test to abort with code 1 originating in the module 0x1::M but instead it aborted with code 0 originating in the module 0x1::M rooted here +│ │ ^^^^^^^ Test did not error as expected. Expected test to abort with code 1 originating in the module 0x6::M but instead it aborted with code 0 originating in the module 0x6::M rooted here │ │ └────────────────── diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.move b/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.move index 1b81628abfd..b88279071c7 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/unexpected_abort.move @@ -1,17 +1,17 @@ -module 0x1::M { +module 0x6::M { #[test] public fun unexpected_abort() { abort 0 } #[test] - #[expected_failure(abort_code=1, location=0x1::M)] + #[expected_failure(abort_code=1, location=0x6::M)] public fun wrong_abort_code() { abort 0 } #[test] - #[expected_failure(abort_code=0, location=0x1::M)] + #[expected_failure(abort_code=0, location=0x6::M)] public fun correct_abort_code() { abort 0 } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.exp index 1b5eb5fc70d..e7e62238990 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.exp @@ -1,4 +1,4 @@ Running Move unit tests -[ PASS ] 0x1::M::poison_call -[ PASS ] 0x1::M::poison_call_OLD +[ PASS ] 0x6::M::poison_call +[ PASS ] 0x6::M::poison_call_OLD Test result: OK. Total tests: 2; passed: 2; failed: 0 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.move b/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.move index 7f92796a3a1..b52e3ece519 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/use_unit_test_module.move @@ -1,4 +1,4 @@ -module 0x1::M { +module 0x6::M { use std::unit_test; #[test] diff --git a/external-crates/move/crates/move-vm-config/Cargo.toml b/external-crates/move/crates/move-vm-config/Cargo.toml index 6780cd878ab..bb066673444 100644 --- a/external-crates/move/crates/move-vm-config/Cargo.toml +++ b/external-crates/move/crates/move-vm-config/Cargo.toml @@ -11,4 +11,4 @@ move-binary-format.workspace = true once_cell.workspace = true [features] -gas-profiler = [] +tracing = [] diff --git a/external-crates/move/crates/move-vm-config/src/runtime.rs b/external-crates/move/crates/move-vm-config/src/runtime.rs index 8532d9f515a..cce5835f40a 100644 --- a/external-crates/move/crates/move-vm-config/src/runtime.rs +++ b/external-crates/move/crates/move-vm-config/src/runtime.rs @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::{binary_config::BinaryConfig, file_format_common::VERSION_MAX}; -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] use once_cell::sync::Lazy; -use crate::verifier::{VerifierConfig, DEFAULT_MAX_CONSTANT_VECTOR_LEN}; +use crate::verifier::{DEFAULT_MAX_CONSTANT_VECTOR_LEN, VerifierConfig}; -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] const MOVE_VM_PROFILER_ENV_VAR_NAME: &str = "MOVE_VM_PROFILE"; -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] static PROFILER_ENABLED: Lazy = Lazy::new(|| std::env::var(MOVE_VM_PROFILER_ENV_VAR_NAME).is_ok()); @@ -37,6 +37,9 @@ pub struct VMConfig { // Whether value serialization errors when generating type layouts should be rethrown or // converted to a different error. pub rethrow_serialization_type_layout_errors: bool, + /// Maximal nodes which are allowed when converting to layout. This includes + /// the types of fields for struct types. + pub max_type_to_layout_nodes: Option, } impl Default for VMConfig { @@ -51,6 +54,7 @@ impl Default for VMConfig { error_execution_state: true, binary_config: BinaryConfig::with_extraneous_bytes_check(false), rethrow_serialization_type_layout_errors: false, + max_type_to_layout_nodes: Some(512), } } } @@ -85,7 +89,7 @@ pub struct VMProfilerConfig { pub use_long_function_name: bool, } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] impl std::default::Default for VMProfilerConfig { fn default() -> Self { Self { @@ -96,7 +100,7 @@ impl std::default::Default for VMProfilerConfig { } } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] impl VMProfilerConfig { pub fn get_default_config_if_enabled() -> Option { if *PROFILER_ENABLED { diff --git a/external-crates/move/crates/move-vm-integration-tests/Cargo.toml b/external-crates/move/crates/move-vm-integration-tests/Cargo.toml index 27c282a2606..1d68e1cfa72 100644 --- a/external-crates/move/crates/move-vm-integration-tests/Cargo.toml +++ b/external-crates/move/crates/move-vm-integration-tests/Cargo.toml @@ -16,7 +16,11 @@ tempfile.workspace = true move-binary-format = { workspace = true, features = ["fuzzing"] } move-bytecode-verifier.workspace = true +move-compiler.workspace = true move-core-types.workspace = true +move-ir-to-bytecode.workspace = true +move-stdlib.workspace = true +move-stdlib-natives.workspace = true move-vm-config.workspace = true move-vm-profiler.workspace = true move-vm-runtime.workspace = true @@ -26,19 +30,13 @@ move-vm-types.workspace = true [dev-dependencies] memory-stats = "1.0.0" -move-compiler.workspace = true -move-ir-to-bytecode.workspace = true -move-stdlib.workspace = true -move-stdlib-natives.workspace = true - [features] default = [] -gas-profiler = [ - "move-vm-config/gas-profiler", - "move-vm-runtime/gas-profiler", - "move-vm-profiler/gas-profiler", - "move-vm-types/gas-profiler", - "move-vm-test-utils/gas-profiler", +tracing = [ + "move-vm-config/tracing", + "move-vm-runtime/tracing", + "move-vm-profiler/tracing", + "move-vm-test-utils/tracing", ] [[bin]] diff --git a/external-crates/move/crates/move-vm-integration-tests/src/compiler.rs b/external-crates/move/crates/move-vm-integration-tests/src/compiler.rs index ed350104d40..3169e1bb7b0 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/compiler.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/compiler.rs @@ -6,7 +6,7 @@ use std::{fs::File, io::Write, path::Path}; use anyhow::Result; -use move_binary_format::file_format::CompiledModule; +use move_binary_format::{file_format::CompiledModule, file_format_common::VERSION_MAX}; use move_compiler::{compiled_unit::AnnotatedCompiledUnit, Compiler as MoveCompiler}; use tempfile::tempdir; @@ -60,3 +60,10 @@ pub fn compile_modules(s: &str) -> Result> { pub fn as_module(unit: AnnotatedCompiledUnit) -> CompiledModule { unit.named_module.module } + +pub fn serialize_module_at_max_version( + module: &CompiledModule, + binary: &mut Vec, +) -> Result<()> { + module.serialize_with_version(VERSION_MAX, binary) +} diff --git a/external-crates/move/crates/move-vm-integration-tests/src/lib.rs b/external-crates/move/crates/move-vm-integration-tests/src/lib.rs index 79794736905..c2100761067 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/lib.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/lib.rs @@ -3,7 +3,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -#![cfg(test)] - +#[cfg(test)] mod compiler; +#[cfg(test)] mod tests; diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_entry_point_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_entry_point_tests.rs index 06b94312bfb..15ce27c6ccb 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_entry_point_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_entry_point_tests.rs @@ -7,14 +7,14 @@ use move_core_types::{ account_address::AccountAddress, identifier::Identifier, language_storage::ModuleId, - runtime_value::{serialize_values, MoveValue}, + runtime_value::{MoveValue, serialize_values}, vm_status::StatusType, }; use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::{BlankStorage, InMemoryStorage}; use move_vm_types::gas::UnmeteredGasMeter; -use crate::compiler::{as_module, compile_units}; +use crate::compiler::{as_module, compile_units, serialize_module_at_max_version}; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); @@ -50,7 +50,7 @@ fn call_non_existent_function() { let mut units = compile_units(&code).unwrap(); let m = as_module(units.pop().unwrap()); let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&m, &mut blob).unwrap(); let mut storage = InMemoryStorage::new(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("M").unwrap()); diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_storage_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_storage_tests.rs index 5d7e64656d0..85587633b58 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_storage_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/bad_storage_tests.rs @@ -15,7 +15,7 @@ use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::InMemoryStorage; use move_vm_types::gas::UnmeteredGasMeter; -use crate::compiler::{as_module, compile_units}; +use crate::compiler::{as_module, compile_units, serialize_module_at_max_version}; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); @@ -34,7 +34,7 @@ fn test_malformed_module() { let m = as_module(units.pop().unwrap()); let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&m, &mut blob).unwrap(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("M").unwrap()); let fun_name = Identifier::new("foo").unwrap(); @@ -104,7 +104,7 @@ fn test_unverifiable_module() { let mut storage = InMemoryStorage::new(); let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&m, &mut blob).unwrap(); storage.publish_or_overwrite_module(m.self_id(), blob); let vm = MoveVM::new(vec![]).unwrap(); @@ -128,7 +128,7 @@ fn test_unverifiable_module() { let mut m = m; m.function_defs[0].code.as_mut().unwrap().code = vec![]; let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&m, &mut blob).unwrap(); storage.publish_or_overwrite_module(m.self_id(), blob); let vm = MoveVM::new(vec![]).unwrap(); @@ -168,9 +168,9 @@ fn test_missing_module_dependency() { let m = as_module(units.pop().unwrap()); let mut blob_m = vec![]; - m.serialize(&mut blob_m).unwrap(); + serialize_module_at_max_version(&m, &mut blob_m).unwrap(); let mut blob_n = vec![]; - n.serialize(&mut blob_n).unwrap(); + serialize_module_at_max_version(&n, &mut blob_n).unwrap(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("N").unwrap()); let fun_name = Identifier::new("bar").unwrap(); @@ -238,9 +238,9 @@ fn test_malformed_module_dependency() { let m = as_module(units.pop().unwrap()); let mut blob_m = vec![]; - m.serialize(&mut blob_m).unwrap(); + serialize_module_at_max_version(&m, &mut blob_m).unwrap(); let mut blob_n = vec![]; - n.serialize(&mut blob_n).unwrap(); + serialize_module_at_max_version(&n, &mut blob_n).unwrap(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("N").unwrap()); let fun_name = Identifier::new("bar").unwrap(); @@ -315,7 +315,7 @@ fn test_unverifiable_module_dependency() { let m = as_module(units.pop().unwrap()); let mut blob_n = vec![]; - n.serialize(&mut blob_n).unwrap(); + serialize_module_at_max_version(&n, &mut blob_n).unwrap(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("N").unwrap()); let fun_name = Identifier::new("bar").unwrap(); @@ -323,7 +323,7 @@ fn test_unverifiable_module_dependency() { // Publish M and N and call N::bar. Everything should work. { let mut blob_m = vec![]; - m.serialize(&mut blob_m).unwrap(); + serialize_module_at_max_version(&m, &mut blob_m).unwrap(); let mut storage = InMemoryStorage::new(); @@ -349,7 +349,7 @@ fn test_unverifiable_module_dependency() { let mut m = m; m.function_defs[0].code.as_mut().unwrap().code = vec![]; let mut blob_m = vec![]; - m.serialize(&mut blob_m).unwrap(); + serialize_module_at_max_version(&m, &mut blob_m).unwrap(); let mut storage = InMemoryStorage::new(); diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/compatibility_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/compatibility_tests.rs index 1327e0b9b99..139a175e9f8 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/compatibility_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/compatibility_tests.rs @@ -200,10 +200,7 @@ fn test_enum_upgrade_add_variant_at_front() { } ", ); - let mut compat = Compatibility::default(); - assert!(compat.disallow_new_variants); - assert!(compat.check(&old, &new).is_err()); - compat.disallow_new_variants = false; + let compat = Compatibility::default(); assert!(compat.check(&old, &new).is_err()); assert!(InclusionCheck::Equal.check(&old, &new).is_err()); assert!(InclusionCheck::Subset.check(&old, &new).is_err()); @@ -227,12 +224,9 @@ fn test_enum_upgrade_add_variant_at_end() { } ", ); - let mut compat = Compatibility::default(); - assert!(compat.disallow_new_variants); + let compat = Compatibility::default(); assert!(compat.check(&old, &new).is_err()); // Allow adding new variants at the end of the enum - compat.disallow_new_variants = false; - assert!(compat.check(&old, &new).is_ok()); assert!(InclusionCheck::Equal.check(&old, &new).is_err()); // NOTE: We currently restrict all enums (even in subset mode) so that new enum variants are not // allowed. This assertion will fail when we allow new enum variants in subset mode and should diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/depth_tests_modules.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/depth_tests_modules.move index 639d3372902..4b0cef722cb 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/depth_tests_modules.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/depth_tests_modules.move @@ -1,7 +1,7 @@ -module 0x2::A { +module 0x7::A { public struct S has copy, drop { - f1: 0x2::B::S, - f2: 0x2::C::S, + f1: 0x7::B::S, + f2: 0x7::C::S, } public struct Box has copy, drop, store { x: T } @@ -13,58 +13,58 @@ module 0x2::A { public struct Box127 has copy, drop, store { x: Box63> } } -module 0x2::B { +module 0x7::B { public struct S has copy, drop { f1: u64, f2: u128, } } -module 0x2::C { +module 0x7::C { public struct S has copy, drop { f1: address, f2: bool, } } -module 0x2::D { +module 0x7::D { public struct S has copy, drop { - f1: 0x2::B::S, + f1: 0x7::B::S, } } -module 0x2::E { +module 0x7::E { public struct S has copy, drop { - f1: 0x2::F::S, + f1: 0x7::F::S, f2: u64, } } -module 0x2::F { +module 0x7::F { public struct S has copy, drop { f1: T, f2: u64, } } -module 0x2::G { +module 0x7::G { public struct S has copy, drop { - f1: 0x2::H::S, + f1: 0x7::H::S, f2: u64, } } -module 0x2::H { +module 0x7::H { public struct S has copy, drop { - f1: 0x2::F::S, - f2: 0x2::E::S, - f3: 0x2::E::S<0x2::F::S>, + f1: 0x7::F::S, + f2: 0x7::E::S, + f3: 0x7::E::S<0x7::F::S>, f4: A, f5: B, f6: u64, } } -module 0x2::I { +module 0x7::I { public struct S { f1: F, f2: E, diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/exec_func_effects_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/exec_func_effects_tests.rs index 51b809a432f..eba8cbbb875 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/exec_func_effects_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/exec_func_effects_tests.rs @@ -11,7 +11,7 @@ use move_core_types::{ effects::ChangeSet, identifier::Identifier, language_storage::ModuleId, - runtime_value::{serialize_values, MoveValue}, + runtime_value::{MoveValue, serialize_values}, u256::U256, vm_status::StatusCode, }; @@ -19,7 +19,7 @@ use move_vm_runtime::{move_vm::MoveVM, session::SerializedReturnValues}; use move_vm_test_utils::InMemoryStorage; use move_vm_types::gas::UnmeteredGasMeter; -use crate::compiler::{as_module, compile_units}; +use crate::compiler::{as_module, compile_units, serialize_module_at_max_version}; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); const TEST_MODULE_ID: &str = "M"; @@ -132,7 +132,7 @@ fn compile_module(storage: &mut InMemoryStorage, mod_id: &ModuleId, code: &str) let mut units = compile_units(code).unwrap(); let module = as_module(units.pop().unwrap()); let mut blob = vec![]; - module.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&module, &mut blob).unwrap(); storage.publish_or_overwrite_module(mod_id.clone(), blob); } diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/function_arg_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/function_arg_tests.rs index f91e8ef9379..420c3bd0cd1 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/function_arg_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/function_arg_tests.rs @@ -16,7 +16,7 @@ use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::InMemoryStorage; use move_vm_types::gas::UnmeteredGasMeter; -use crate::compiler::{as_module, compile_units}; +use crate::compiler::{as_module, compile_units, serialize_module_at_max_version}; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); @@ -53,7 +53,7 @@ fn run( let mut units = compile_units(&code).unwrap(); let m = as_module(units.pop().unwrap()); let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&m, &mut blob).unwrap(); let mut storage = InMemoryStorage::new(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("M").unwrap()); @@ -166,10 +166,9 @@ fn expected_u64_got_u64() { #[test] #[allow(non_snake_case)] fn expected_Foo_got_Foo() { - expect_ok( - &["Foo"], - vec![MoveValue::Struct(MoveStruct::new(vec![MoveValue::U64(0)]))], - ) + expect_ok(&["Foo"], vec![MoveValue::Struct(MoveStruct::new(vec![ + MoveValue::U64(0), + ]))]) } #[test] @@ -179,10 +178,10 @@ fn expected_signer_ref_got_signer() { #[test] fn expected_u64_signer_ref_got_u64_signer() { - expect_ok( - &["u64", "&signer"], - vec![MoveValue::U64(0), MoveValue::Signer(TEST_ADDR)], - ) + expect_ok(&["u64", "&signer"], vec![ + MoveValue::U64(0), + MoveValue::Signer(TEST_ADDR), + ]) } #[test] @@ -241,25 +240,17 @@ fn expected_A_B__A_u32_vector_B_got_u16_u256__u16_u32_vector_u256() { #[test] #[allow(non_snake_case)] fn expected_T__Bar_T_got_bool__Bar_bool() { - expect_ok_generic( - &["T"], - &["Bar"], - vec![TypeTag::Bool], - vec![MoveValue::Struct(MoveStruct::new(vec![MoveValue::Bool( - false, - )]))], - ) + expect_ok_generic(&["T"], &["Bar"], vec![TypeTag::Bool], vec![ + MoveValue::Struct(MoveStruct::new(vec![MoveValue::Bool(false)])), + ]) } #[test] #[allow(non_snake_case)] fn expected_T__T_got_bool__bool() { - expect_ok_generic( - &["T"], - &["T"], - vec![TypeTag::Bool], - vec![MoveValue::Bool(false)], - ) + expect_ok_generic(&["T"], &["T"], vec![TypeTag::Bool], vec![MoveValue::Bool( + false, + )]) } #[test] diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/instantiation_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/instantiation_tests.rs index ef48ef92fa5..6227ecc6074 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/instantiation_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/instantiation_tests.rs @@ -26,7 +26,7 @@ use move_core_types::{ language_storage::{ModuleId, StructTag, TypeTag}, vm_status::StatusCode, }; -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] use move_vm_profiler::GasProfiler; use move_vm_runtime::{ move_vm::MoveVM, @@ -36,7 +36,7 @@ use move_vm_test_utils::{ gas_schedule::{Gas, GasStatus, INITIAL_COST_SCHEDULE}, InMemoryStorage, }; -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] use move_vm_types::gas::GasMeter; const MODULE_NAME: &str = "Mod"; @@ -559,7 +559,7 @@ fn run_with_module( .into_iter() .map(|tag| session.load_type(&tag)) .collect::>>(); - move_vm_profiler::gas_profiler_feature_enabled! { + move_vm_profiler::tracing_feature_enabled! { gas.set_profiler(GasProfiler::init( &session.vm_config().profiler_config, entry_name.to_string(), diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/invariant_violation_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/invariant_violation_tests.rs index ed3ac20d040..74cc7375a34 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/invariant_violation_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/invariant_violation_tests.rs @@ -11,6 +11,8 @@ use move_core_types::{account_address::AccountAddress, vm_status::StatusCode}; use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::{gas_schedule::GasStatus, InMemoryStorage}; +use crate::compiler::serialize_module_at_max_version; + #[test] fn merge_borrow_states_infinite_loop() { let mut m = empty_module(); @@ -81,7 +83,7 @@ fn merge_borrow_states_infinite_loop() { let storage: InMemoryStorage = InMemoryStorage::new(); let mut session = vm.new_session(&storage); let mut module_bytes = vec![]; - m.serialize(&mut module_bytes).unwrap(); + serialize_module_at_max_version(&m, &mut module_bytes).unwrap(); let meter = &mut GasStatus::new_unmetered(); session .publish_module(module_bytes, AccountAddress::ZERO, meter) diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/leak_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/leak_tests.rs index 01d1fcde517..a885821c48b 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/leak_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/leak_tests.rs @@ -10,6 +10,8 @@ use move_core_types::account_address::AccountAddress; use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::{gas_schedule::GasStatus, InMemoryStorage}; +use crate::compiler::serialize_module_at_max_version; + #[test] fn leak_with_abort() { let mut locals = vec![U128, MutableReference(Box::new(U128))]; @@ -57,7 +59,7 @@ fn leak_with_abort() { let storage: InMemoryStorage = InMemoryStorage::new(); let mut session = vm.new_session(&storage); let mut module_bytes = vec![]; - m.serialize(&mut module_bytes).unwrap(); + serialize_module_at_max_version(&m, &mut module_bytes).unwrap(); let meter = &mut GasStatus::new_unmetered(); session .publish_module(module_bytes, AccountAddress::ZERO, meter) diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests.rs index 3d24fad5ae5..bdd6307f9c3 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests.rs @@ -9,10 +9,10 @@ use std::{collections::BTreeMap, path::PathBuf, str::FromStr, sync::Arc, thread}; use move_binary_format::{ + CompiledModule, file_format::{ - empty_module, AddressIdentifierIndex, IdentifierIndex, ModuleHandle, TableIndex, + AddressIdentifierIndex, IdentifierIndex, ModuleHandle, TableIndex, empty_module, }, - CompiledModule, }; use move_compiler::Compiler; use move_core_types::{ @@ -32,17 +32,21 @@ use move_vm_types::{ loaded_data::runtime_types::{CachedDatatype, DepthFormula, Type}, }; -use crate::compiler::{compile_modules_in_file, expect_modules}; +use crate::compiler::{compile_modules_in_file, expect_modules, serialize_module_at_max_version}; -const DEFAULT_ACCOUNT: AccountAddress = AccountAddress::TWO; +const DEFAULT_ACCOUNT: AccountAddress = { + let mut address = [0u8; AccountAddress::LENGTH]; + address[AccountAddress::LENGTH - 1] = 7u8; + AccountAddress::new(address) +}; const UPGRADE_ACCOUNT: AccountAddress = { let mut address = [0u8; AccountAddress::LENGTH]; - address[AccountAddress::LENGTH - 1] = 3u8; + address[AccountAddress::LENGTH - 1] = 8u8; AccountAddress::new(address) }; const UPGRADE_ACCOUNT_2: AccountAddress = { let mut address = [0u8; AccountAddress::LENGTH]; - address[AccountAddress::LENGTH - 1] = 4u8; + address[AccountAddress::LENGTH - 1] = 9u8; AccountAddress::new(address) }; @@ -131,7 +135,7 @@ impl Adapter { for module in modules { let mut binary = vec![]; - module.serialize(&mut binary).unwrap_or_else(|e| { + serialize_module_at_max_version(&module, &mut binary).unwrap_or_else(|e| { panic!("failure in module serialization: {e:?}\n{:#?}", module) }); session @@ -149,7 +153,7 @@ impl Adapter { for module in modules { let mut binary = vec![]; - module.serialize(&mut binary).unwrap_or_else(|e| { + serialize_module_at_max_version(&module, &mut binary).unwrap_or_else(|e| { panic!("failure in module serialization: {e:?}\n{:#?}", module) }); session @@ -164,7 +168,7 @@ impl Adapter { .into_iter() .map(|module| { let mut binary = vec![]; - module.serialize(&mut binary).unwrap_or_else(|e| { + serialize_module_at_max_version(&module, &mut binary).unwrap_or_else(|e| { panic!("failure in module serialization: {e:?}\n{:#?}", module) }); binary @@ -187,7 +191,7 @@ impl Adapter { .into_iter() .map(|module| { let mut binary = vec![]; - module.serialize(&mut binary).unwrap_or_else(|e| { + serialize_module_at_max_version(&module, &mut binary).unwrap_or_else(|e| { panic!("failure in module serialization: {e:?}\n{:#?}", module) }); binary @@ -778,7 +782,7 @@ fn relink_type_identity() { let b1_modules = get_relinker_tests_modules_with_deps("b_v1", ["c_v1"]).unwrap(); adapter.publish_modules(c0_modules); - let c0_s = adapter.load_type(&TypeTag::from_str("0x2::c::S").unwrap()); + let c0_s = adapter.load_type(&TypeTag::from_str("0x7::c::S").unwrap()); let mut adapter = adapter.relink( UPGRADE_ACCOUNT, @@ -795,8 +799,8 @@ fn relink_type_identity() { adapter.publish_modules(c1_modules); adapter.publish_modules(b1_modules); - let c1_s = adapter.load_type(&TypeTag::from_str("0x2::c::S").unwrap()); - let b1_s = adapter.load_type(&TypeTag::from_str("0x2::b::S").unwrap()); + let c1_s = adapter.load_type(&TypeTag::from_str("0x7::c::S").unwrap()); + let b1_s = adapter.load_type(&TypeTag::from_str("0x7::b::S").unwrap()); assert_eq!(c0_s, c1_s); assert_ne!(c1_s, b1_s); @@ -818,7 +822,7 @@ fn relink_defining_module_successive() { let c2_modules = get_relinker_tests_modules_with_deps("c_v2", []).unwrap(); adapter.publish_modules(c0_modules); - let c0_s = adapter.load_type(&TypeTag::from_str("0x2::c::S").unwrap()); + let c0_s = adapter.load_type(&TypeTag::from_str("0x7::c::S").unwrap()); let mut adapter = adapter.relink( UPGRADE_ACCOUNT, @@ -832,8 +836,8 @@ fn relink_defining_module_successive() { ); adapter.publish_modules(c1_modules); - let c1_s = adapter.load_type(&TypeTag::from_str("0x2::c::S").unwrap()); - let c1_r = adapter.load_type(&TypeTag::from_str("0x2::c::R").unwrap()); + let c1_s = adapter.load_type(&TypeTag::from_str("0x7::c::S").unwrap()); + let c1_r = adapter.load_type(&TypeTag::from_str("0x7::c::R").unwrap()); let mut adapter = adapter.relink( UPGRADE_ACCOUNT_2, @@ -848,9 +852,9 @@ fn relink_defining_module_successive() { ); adapter.publish_modules(c2_modules); - let c2_s = adapter.load_type(&TypeTag::from_str("0x2::c::S").unwrap()); - let c2_r = adapter.load_type(&TypeTag::from_str("0x2::c::R").unwrap()); - let c2_q = adapter.load_type(&TypeTag::from_str("0x2::c::Q").unwrap()); + let c2_s = adapter.load_type(&TypeTag::from_str("0x7::c::S").unwrap()); + let c2_r = adapter.load_type(&TypeTag::from_str("0x7::c::R").unwrap()); + let c2_q = adapter.load_type(&TypeTag::from_str("0x7::c::Q").unwrap()); for s in &[c0_s, c1_s, c2_s] { let TypeTag::Struct(st) = adapter.get_type_tag(s) else { @@ -904,9 +908,9 @@ fn relink_defining_module_oneshot() { ); adapter.publish_modules(c2_modules); - let s = adapter.load_type(&TypeTag::from_str("0x2::c::S").unwrap()); - let r = adapter.load_type(&TypeTag::from_str("0x2::c::R").unwrap()); - let q = adapter.load_type(&TypeTag::from_str("0x2::c::Q").unwrap()); + let s = adapter.load_type(&TypeTag::from_str("0x7::c::S").unwrap()); + let r = adapter.load_type(&TypeTag::from_str("0x7::c::R").unwrap()); + let q = adapter.load_type(&TypeTag::from_str("0x7::c::Q").unwrap()); let TypeTag::Struct(s) = adapter.get_type_tag(&s) else { panic!("Not a struct: {s:?}") diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests_modules.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests_modules.move index 74d980a6c0e..1e35583dfea 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests_modules.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/loader_tests_modules.move @@ -1,14 +1,14 @@ -module 0x2::A { +module 0x7::A { public struct S has copy, drop { - f1: 0x2::B::S, - f2: 0x2::C::S, + f1: 0x7::B::S, + f2: 0x7::C::S, } - public fun new(f1: 0x2::B::S, f2: 0x2::C::S): S { + public fun new(f1: 0x7::B::S, f2: 0x7::C::S): S { Self::S { f1, f2 } } - public fun destroy(v: S): (0x2::B::S, 0x2::C::S) { + public fun destroy(v: S): (0x7::B::S, 0x7::C::S) { let S { f1: v1, f2: v2 } = v; (v1, v2) } @@ -16,22 +16,22 @@ module 0x2::A { public fun entry_a() { let mut i = 0; while (i < 10) { - let b = 0x2::B::new(20, 100); - let c = 0x2::C::new(@0x42, true); - let another_b = 0x2::B::b_and_c(&b, c); - let (_, _) = 0x2::B::destroy(another_b); - let another_c = 0x2::C::new(@0x42, false); - 0x2::C::destroy(another_c); + let b = 0x7::B::new(20, 100); + let c = 0x7::C::new(@0x42, true); + let another_b = 0x7::B::b_and_c(&b, c); + let (_, _) = 0x7::B::destroy(another_b); + let another_c = 0x7::C::new(@0x42, false); + 0x7::C::destroy(another_c); i = i + 1; } } - public fun get_field_1(s: &S): 0x2::B::S { + public fun get_field_1(s: &S): 0x7::B::S { *&s.f1 } } -module 0x2::B { +module 0x7::B { public struct S has copy, drop { f1: u64, f2: u128, @@ -44,8 +44,8 @@ module 0x2::B { (val1, val2) } - public fun b_and_c(b: &S, c: 0x2::C::S): S { - let _ = 0x2::C::destroy(c); + public fun b_and_c(b: &S, c: 0x7::C::S): S { + let _ = 0x7::C::destroy(c); let another_b = S { f1: 0, f2: b.f2, @@ -54,7 +54,7 @@ module 0x2::B { } } -module 0x2::C { +module 0x7::C { public struct S has copy, drop { f1: address, f2: bool, @@ -83,65 +83,65 @@ module 0x2::C { } -module 0x2::D { +module 0x7::D { public struct S has copy, drop { - f1: 0x2::B::S, + f1: 0x7::B::S, } - public fun new(): 0x2::D::S { + public fun new(): 0x7::D::S { Self::S { - f1: 0x2::B::new(20, 100), + f1: 0x7::B::new(20, 100), } } public fun entry_d() { let mut i = 0; while (i < 10) { - let b = 0x2::B::new(20, 100); - let c = 0x2::C::new(@0x45, false); - let another_b = 0x2::B::b_and_c(&b, c); - let (_, _) = 0x2::B::destroy(another_b); - let another_c = 0x2::C::new(@0x46, true); - 0x2::C::destroy(another_c); + let b = 0x7::B::new(20, 100); + let c = 0x7::C::new(@0x45, false); + let another_b = 0x7::B::b_and_c(&b, c); + let (_, _) = 0x7::B::destroy(another_b); + let another_c = 0x7::C::new(@0x46, true); + 0x7::C::destroy(another_c); i = i + 1; } } } -module 0x2::E { +module 0x7::E { public struct S { f1: u64, } - public fun new(): 0x2::E::S { Self::S { f1: 20 } } + public fun new(): 0x7::E::S { Self::S { f1: 20 } } public fun entry_e() { let mut i = 0; while (i < 10) { - let b = 0x2::B::new(20, 100); - let c = 0x2::C::new(@0x100, false); - let another_b = 0x2::B::b_and_c(&b, c); - let (_, _) = 0x2::B::destroy(another_b); - let another_c = 0x2::C::new(@0x101, true); - 0x2::C::destroy(another_c); + let b = 0x7::B::new(20, 100); + let c = 0x7::C::new(@0x100, false); + let another_b = 0x7::B::b_and_c(&b, c); + let (_, _) = 0x7::B::destroy(another_b); + let another_c = 0x7::C::new(@0x101, true); + 0x7::C::destroy(another_c); i = i + 1; }; } } -module 0x2::F { +module 0x7::F { public struct S { f1: u64, } - public fun new(): 0x2::F::S { Self::S { f1: 20 } } + public fun new(): 0x7::F::S { Self::S { f1: 20 } } public fun entry_f() { - 0x2::A::entry_a(); + 0x7::A::entry_a(); } } -module 0x2::G { +module 0x7::G { public struct S has copy, drop { f1: u64, f2: u128, @@ -157,8 +157,8 @@ module 0x2::G { (val1, val2, val3, val4, val5) } - public fun b_and_c(b: &S, c: 0x2::C::S): S { - let _ = 0x2::C::destroy(c); + public fun b_and_c(b: &S, c: 0x7::C::S): S { + let _ = 0x7::C::destroy(c); let another_b = S { f1: 0, f2: b.f2, diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/nested_loop_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/nested_loop_tests.rs index e93605ac1f3..6f9a41389d3 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/nested_loop_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/nested_loop_tests.rs @@ -8,7 +8,7 @@ use move_vm_runtime::move_vm::MoveVM; use move_vm_test_utils::InMemoryStorage; use move_vm_types::gas::UnmeteredGasMeter; -use crate::compiler::{as_module, compile_units}; +use crate::compiler::{as_module, compile_units, serialize_module_at_max_version}; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); @@ -35,7 +35,7 @@ fn test_publish_module_with_nested_loops() { let m = as_module(units.pop().unwrap()); let mut m_blob = vec![]; - m.serialize(&mut m_blob).unwrap(); + serialize_module_at_max_version(&m, &mut m_blob).unwrap(); // Should succeed with max_loop_depth = 2 { @@ -44,7 +44,8 @@ fn test_publish_module_with_nested_loops() { move_stdlib_natives::all_natives( AccountAddress::from_hex_literal("0x1").unwrap(), move_stdlib_natives::GasParameters::zeros(), - /* silent debug */ true, + // silent debug + true, ), VMConfig { verifier: VerifierConfig { @@ -68,7 +69,8 @@ fn test_publish_module_with_nested_loops() { move_stdlib_natives::all_natives( AccountAddress::from_hex_literal("0x1").unwrap(), move_stdlib_natives::GasParameters::zeros(), - /* silent debug */ true, + // silent debug + true, ), VMConfig { verifier: VerifierConfig { diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_a_v0.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_a_v0.move index 270ccc213d4..7a15a696273 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_a_v0.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_a_v0.move @@ -1,6 +1,6 @@ /// Dependencies: [B v0+, C v1+] -module 0x2::a { +module 0x7::a { public fun a(): u64 { - 0x2::b::b() + 0x2::c::d() + 0x7::b::b() + 0x7::c::d() } } diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v0.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v0.move index abbc19add9e..9395c6f183e 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v0.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v0.move @@ -1,6 +1,6 @@ /// Dependencies: [C v0+] -module 0x2::b { +module 0x7::b { public fun b(): u64 { - 0x2::c::c() + 1 + 0x7::c::c() + 1 } } diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v1.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v1.move index bf93efa2b63..a24c27d5e46 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v1.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_b_v1.move @@ -1,8 +1,8 @@ /// Dependencies: [C v0+] -module 0x2::b { +module 0x7::b { public struct S { x: u64 } public fun b(): u64 { - 0x2::c::c() * 0x2::c::d() + 0x7::c::c() * 0x7::c::d() } } diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v0.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v0.move index 6efe3748c37..ebd04f15071 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v0.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v0.move @@ -1,5 +1,5 @@ /// Dependencies: [] -module 0x2::c { +module 0x7::c { public struct S { x: u64 } public fun c(): u64 { diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v1.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v1.move index b36c4e9549b..446fc1ebcfe 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v1.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v1.move @@ -1,5 +1,5 @@ /// Dependencies: [] -module 0x2::c { +module 0x7::c { public struct S { x: u64 } public struct R { x: u64, y: u64 } diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v2.move b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v2.move index ba0318bef1c..826d4dd5fd9 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v2.move +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/relinking_tests_c_v2.move @@ -1,5 +1,5 @@ /// Dependencies: [] -module 0x2::c { +module 0x7::c { public struct S { x: u64 } public struct R { x: u64, y: u64 } public struct Q { x: u64, y: u64, z: u64 } diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/return_value_tests.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/return_value_tests.rs index f409ab3b25f..f946738e428 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/return_value_tests.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/return_value_tests.rs @@ -14,7 +14,7 @@ use move_vm_runtime::{move_vm::MoveVM, session::SerializedReturnValues}; use move_vm_test_utils::InMemoryStorage; use move_vm_types::gas::UnmeteredGasMeter; -use crate::compiler::{as_module, compile_units}; +use crate::compiler::{as_module, compile_units, serialize_module_at_max_version}; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); @@ -43,7 +43,7 @@ fn run( let mut units = compile_units(&code).unwrap(); let m = as_module(units.pop().unwrap()); let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); + serialize_module_at_max_version(&m, &mut blob).unwrap(); let mut storage = InMemoryStorage::new(); let module_id = ModuleId::new(TEST_ADDR, Identifier::new("M").unwrap()); @@ -109,14 +109,10 @@ fn return_u64() { #[test] fn return_u64_bool() { - expect_success( - &[], - "(): (u64, bool)", - "(42, true)", - vec![], - vec![], - &[MoveTypeLayout::U64, MoveTypeLayout::Bool], - ) + expect_success(&[], "(): (u64, bool)", "(42, true)", vec![], vec![], &[ + MoveTypeLayout::U64, + MoveTypeLayout::Bool, + ]) } #[test] diff --git a/external-crates/move/crates/move-vm-profiler/Cargo.toml b/external-crates/move/crates/move-vm-profiler/Cargo.toml index b4f1c4c87bd..ced1ecd85ee 100644 --- a/external-crates/move/crates/move-vm-profiler/Cargo.toml +++ b/external-crates/move/crates/move-vm-profiler/Cargo.toml @@ -15,4 +15,4 @@ tracing = { workspace = true, optional = true } move-vm-config.workspace = true [features] -gas-profiler = ["move-vm-config/gas-profiler", "serde_json", "tracing"] +tracing = ["move-vm-config/tracing", "serde_json", "dep:tracing"] diff --git a/external-crates/move/crates/move-vm-profiler/src/lib.rs b/external-crates/move/crates/move-vm-profiler/src/lib.rs index 761180bfe19..ba91214bc68 100644 --- a/external-crates/move/crates/move-vm-profiler/src/lib.rs +++ b/external-crates/move/crates/move-vm-profiler/src/lib.rs @@ -6,7 +6,7 @@ use std::collections::BTreeMap; use move_vm_config::runtime::VMProfilerConfig; use serde::Serialize; -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] use tracing::info; #[derive(Debug, Clone, Serialize)] @@ -64,7 +64,7 @@ pub struct GasProfiler { finished: bool, } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] impl GasProfiler { // Used by profiler viz tool const OPEN_FRAME_IDENT: &'static str = "O"; @@ -72,7 +72,7 @@ impl GasProfiler { const TOP_LEVEL_FRAME_NAME: &'static str = "root"; - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn init(config: &Option, name: String, start_gas: u64) -> Self { let mut prof = GasProfiler { exporter: "speedscope@1.15.2".to_string(), @@ -103,7 +103,7 @@ impl GasProfiler { prof } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn init_default_cfg(name: String, start_gas: u64) -> Self { Self::init( &VMProfilerConfig::get_default_config_if_enabled(), @@ -112,22 +112,22 @@ impl GasProfiler { ) } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn short_name(s: &String) -> String { s.split("::").last().unwrap_or(s).to_string() } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] fn is_metered(&self) -> bool { (self.profiles[0].end_value != 0) && (self.start_gas != 0) } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] fn start_gas(&self) -> u64 { self.start_gas } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] fn add_frame( &mut self, frame_name: String, @@ -148,7 +148,7 @@ impl GasProfiler { } } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn open_frame(&mut self, frame_name: String, metadata: String, gas_start: u64) { if self.config.is_none() || self.start_gas == 0 { return; @@ -164,7 +164,7 @@ impl GasProfiler { }); } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn close_frame(&mut self, frame_name: String, metadata: String, gas_end: u64) { if self.config.is_none() || self.start_gas == 0 { return; @@ -180,7 +180,7 @@ impl GasProfiler { self.profiles[0].end_value = start - gas_end; } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn to_file(&self) { use std::{ ffi::{OsStr, OsString}, @@ -222,7 +222,7 @@ impl GasProfiler { info!("Gas profile written to file: {}", p.display()); } - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] pub fn finish(&mut self) { if self.finished { return; @@ -235,7 +235,7 @@ impl GasProfiler { } } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] impl Drop for GasProfiler { fn drop(&mut self) { self.finish(); @@ -245,7 +245,7 @@ impl Drop for GasProfiler { #[macro_export] macro_rules! profile_open_frame { ($gas_meter:expr, $frame_name:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] { let gas_rem = $gas_meter.remaining_gas().into(); move_vm_profiler::profile_open_frame_impl!( @@ -260,12 +260,12 @@ macro_rules! profile_open_frame { #[macro_export] macro_rules! profile_open_frame_impl { ($profiler:expr, $frame_name:expr, $gas_rem:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] { if let Some(profiler) = $profiler { if let Some(config) = &profiler.config { let name = if !config.use_long_function_name { - GasProfiler::short_name(&$frame_name) + $crate::GasProfiler::short_name(&$frame_name) } else { $frame_name }; @@ -279,7 +279,7 @@ macro_rules! profile_open_frame_impl { #[macro_export] macro_rules! profile_close_frame { ($gas_meter:expr, $frame_name:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] { let gas_rem = $gas_meter.remaining_gas().into(); move_vm_profiler::profile_close_frame_impl!( @@ -294,12 +294,12 @@ macro_rules! profile_close_frame { #[macro_export] macro_rules! profile_close_frame_impl { ($profiler:expr, $frame_name:expr, $gas_rem:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] { if let Some(profiler) = $profiler { if let Some(config) = &profiler.config { let name = if !config.use_long_function_name { - GasProfiler::short_name(&$frame_name) + $crate::GasProfiler::short_name(&$frame_name) } else { $frame_name }; @@ -313,7 +313,7 @@ macro_rules! profile_close_frame_impl { #[macro_export] macro_rules! profile_open_instr { ($gas_meter:expr, $frame_name:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] { let gas_rem = $gas_meter.remaining_gas().into(); if let Some(profiler) = $gas_meter.get_profiler_mut() { @@ -330,7 +330,7 @@ macro_rules! profile_open_instr { #[macro_export] macro_rules! profile_close_instr { ($gas_meter:expr, $frame_name:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] { let gas_rem = $gas_meter.remaining_gas().into(); if let Some(profiler) = $gas_meter.get_profiler_mut() { @@ -347,39 +347,39 @@ macro_rules! profile_close_instr { #[macro_export] macro_rules! profile_dump_file { ($profiler:expr) => { - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] $profiler.to_file() }; } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] #[macro_export] -macro_rules! gas_profiler_feature_enabled { +macro_rules! tracing_feature_enabled { ($($tt:tt)*) => { - if cfg!(feature = "gas-profiler") { + if cfg!(feature = "tracing") { $($tt)* } }; } -#[cfg(not(feature = "gas-profiler"))] +#[cfg(not(feature = "tracing"))] #[macro_export] -macro_rules! gas_profiler_feature_enabled { +macro_rules! tracing_feature_enabled { ( $( $tt:tt )* ) => {}; } -#[cfg(not(feature = "gas-profiler"))] +#[cfg(not(feature = "tracing"))] #[macro_export] -macro_rules! gas_profiler_feature_disabled { +macro_rules! tracing_feature_disabled { ($($tt:tt)*) => { - if !cfg!(feature = "gas-profiler") { + if !cfg!(feature = "tracing") { $($tt)* } }; } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] #[macro_export] -macro_rules! gas_profiler_feature_disabled { +macro_rules! tracing_feature_disabled { ( $( $tt:tt )* ) => {}; } diff --git a/external-crates/move/crates/move-vm-runtime/Cargo.toml b/external-crates/move/crates/move-vm-runtime/Cargo.toml index 7348e2ef37f..2d95a0250f8 100644 --- a/external-crates/move/crates/move-vm-runtime/Cargo.toml +++ b/external-crates/move/crates/move-vm-runtime/Cargo.toml @@ -21,6 +21,7 @@ tracing.workspace = true move-binary-format.workspace = true move-bytecode-verifier = { path = "../move-bytecode-verifier" } move-core-types.workspace = true +move-trace-format.workspace = true move-vm-config.workspace = true move-vm-profiler.workspace = true move-vm-types.workspace = true @@ -36,12 +37,9 @@ move-binary-format = { workspace = true, features = ["fuzzing"] } default = [] fuzzing = ["move-vm-types/fuzzing"] failpoints = ["fail/failpoints"] -# Enable tracing and debugging also for release builds. By default, it is only enabled for debug builds. -debugging = [] testing = [] lazy_natives = [] -gas-profiler = [ - "move-vm-config/gas-profiler", - "move-vm-types/gas-profiler", - "move-vm-profiler/gas-profiler", +tracing = [ + "move-vm-config/tracing", + "move-vm-profiler/tracing", ] diff --git a/external-crates/move/crates/move-vm-runtime/src/interpreter.rs b/external-crates/move/crates/move-vm-runtime/src/interpreter.rs index d361bd75be4..4557f0a86fd 100644 --- a/external-crates/move/crates/move-vm-runtime/src/interpreter.rs +++ b/external-crates/move/crates/move-vm-runtime/src/interpreter.rs @@ -17,11 +17,6 @@ use move_core_types::{ vm_status::{StatusCode, StatusType}, }; use move_vm_config::runtime::VMRuntimeLimitsConfig; -#[cfg(feature = "gas-profiler")] -use move_vm_profiler::GasProfiler; -use move_vm_profiler::{ - profile_close_frame, profile_close_instr, profile_open_frame, profile_open_instr, -}; use move_vm_types::{ data_store::DataStore, gas::{GasMeter, SimpleInstruction}, @@ -36,10 +31,12 @@ use smallvec::SmallVec; use tracing::error; use crate::{ + close_frame, close_initial_frame, close_instruction, loader::{Function, Loader, Resolver}, native_extensions::NativeContextExtensions, native_functions::NativeContext, - trace, + open_frame, open_initial_frame, open_instruction, trace, + tracing2::tracer::VMTracer, }; macro_rules! debug_write { @@ -80,9 +77,9 @@ enum InstrRet { /// stack. pub(crate) struct Interpreter { /// Operand stack, where Move `Value`s are stored for stack operations. - operand_stack: Stack, + pub(crate) operand_stack: Stack, /// The stack of active functions. - call_stack: CallStack, + pub(crate) call_stack: CallStack, /// Limits imposed at runtime runtime_limits_config: VMRuntimeLimitsConfig, } @@ -113,13 +110,23 @@ impl Interpreter { gas_meter: &mut impl GasMeter, extensions: &mut NativeContextExtensions, loader: &Loader, + tracer: &mut Option>, ) -> VMResult> { let mut interpreter = Interpreter { operand_stack: Stack::new(), call_stack: CallStack::new(), runtime_limits_config: loader.vm_config().runtime_limits_config.clone(), }; - profile_open_frame!(gas_meter, function.pretty_string()); + + open_initial_frame!( + tracer, + &args, + &ty_args, + &function, + loader, + gas_meter, + data_store.link_context() + ); if function.is_native() { for arg in args { @@ -142,14 +149,14 @@ impl Interpreter { .map_err(|e| { e.at_code_offset(function.index(), 0) .finish(Location::Module(function.module_id().clone())) - })?; + }); - profile_close_frame!(gas_meter, function.pretty_string()); + close_initial_frame!(tracer, &function, &return_values, gas_meter); - Ok(return_values.into_iter().collect()) + Ok(return_values?.into_iter().collect()) } else { interpreter.execute_main( - loader, data_store, gas_meter, extensions, function, ty_args, args, + loader, data_store, gas_meter, extensions, function, ty_args, args, tracer, ) } } @@ -170,6 +177,7 @@ impl Interpreter { function: Arc, ty_args: Vec, args: Vec, + tracer: &mut Option>, ) -> VMResult> { let mut locals = Locals::new(function.local_count()); for (i, value) in args.into_iter().enumerate() { @@ -191,7 +199,7 @@ impl Interpreter { loop { let resolver = current_frame.resolver(link_context, loader); let exit_code = current_frame // self - .execute_code(&resolver, &mut self, gas_meter) + .execute_code(&resolver, &mut self, gas_meter, tracer) .map_err(|err| self.maybe_core_dump(err, ¤t_frame))?; match exit_code { ExitCode::Return => { @@ -205,7 +213,16 @@ impl Interpreter { .charge_drop_frame(non_ref_vals.into_iter()) .map_err(|e| self.set_location(e))?; - profile_close_frame!(gas_meter, current_frame.function.pretty_string()); + close_frame!( + tracer, + ¤t_frame, + ¤t_frame.function, + &self, + &loader, + gas_meter, + link_context, + None + ); if let Some(frame) = self.call_stack.pop() { // Note: the caller will find the callee's return values at the top of the @@ -219,9 +236,16 @@ impl Interpreter { } ExitCode::Call(fh_idx) => { let func = resolver.function_from_handle(fh_idx); - #[cfg(feature = "gas-profiler")] - let func_name = func.pretty_string(); - profile_open_frame!(gas_meter, func_name.clone()); + open_frame!( + tracer, + &[], + &func, + ¤t_frame, + &self, + &loader, + gas_meter, + link_context + ); // Charge gas let module_id = func.module_id(); @@ -237,11 +261,27 @@ impl Interpreter { .map_err(|e| set_err_info!(current_frame, e))?; if func.is_native() { - self.call_native(&resolver, gas_meter, extensions, func, vec![])?; + let func_clone = func.clone(); + // Defer the error handling until we can trace the closure of the frame. + let deferred_err = + self.call_native(&resolver, gas_meter, extensions, func, vec![]); + + close_frame!( + tracer, + ¤t_frame, + &func_clone, + &self, + &loader, + gas_meter, + link_context, + deferred_err.as_ref().err() + ); + + // Now raise the error from the `call_native` if there was one. + deferred_err?; current_frame.pc += 1; // advance past the Call instruction in the caller - profile_close_frame!(gas_meter, func_name.clone()); continue; } let frame = self @@ -253,7 +293,8 @@ impl Interpreter { let err = set_err_info!(frame, err); self.maybe_core_dump(err, &frame) })?; - // Note: the caller will find the callee's return values at the top of the shared operand stack + // Note: the caller will find the callee's return values at the top of the + // shared operand stack current_frame = frame; } ExitCode::CallGeneric(idx) => { @@ -262,9 +303,16 @@ impl Interpreter { .instantiate_generic_function(idx, current_frame.ty_args()) .map_err(|e| set_err_info!(current_frame, e))?; let func = resolver.function_from_instantiation(idx); - #[cfg(feature = "gas-profiler")] - let func_name = func.pretty_string(); - profile_open_frame!(gas_meter, func_name.clone()); + open_frame!( + tracer, + &ty_args, + &func, + ¤t_frame, + &self, + &loader, + gas_meter, + link_context + ); // Charge gas let module_id = func.module_id(); @@ -281,10 +329,25 @@ impl Interpreter { .map_err(|e| set_err_info!(current_frame, e))?; if func.is_native() { - self.call_native(&resolver, gas_meter, extensions, func, ty_args)?; - current_frame.pc += 1; // advance past the Call instruction in the caller - profile_close_frame!(gas_meter, func_name.clone()); + let func_clone = func.clone(); + // Defer the error handling until we can trace the closure of the frame. + let deferred_err = + self.call_native(&resolver, gas_meter, extensions, func, ty_args); + close_frame!( + tracer, + ¤t_frame, + &func_clone, + &self, + &loader, + gas_meter, + link_context, + deferred_err.as_ref().err() + ); + + // Now raise the error from the `call_native` if there was one. + deferred_err?; + current_frame.pc += 1; // advance past the Call instruction in the caller continue; } let frame = self @@ -693,8 +756,8 @@ const OPERAND_STACK_SIZE_LIMIT: usize = 1024; const CALL_STACK_SIZE_LIMIT: usize = 1024; /// The operand stack. -struct Stack { - value: Vec, +pub(crate) struct Stack { + pub(crate) value: Vec, } impl Stack { @@ -752,7 +815,7 @@ impl Stack { /// A call stack. // #[derive(Debug)] -struct CallStack(Vec); +pub(crate) struct CallStack(pub(crate) Vec); impl CallStack { /// Create a new empty call stack. @@ -784,11 +847,11 @@ impl CallStack { /// A `Frame` is the execution context for a function. It holds the locals of /// the function and the function itself. // #[derive(Debug)] -struct Frame { - pc: u16, - locals: Locals, - function: Arc, - ty_args: Vec, +pub(crate) struct Frame { + pub(crate) pc: u16, + pub(crate) locals: Locals, + pub(crate) function: Arc, + pub(crate) ty_args: Vec, } /// An `ExitCode` from `execute_code_unit`. @@ -806,8 +869,9 @@ impl Frame { resolver: &Resolver, interpreter: &mut Interpreter, gas_meter: &mut impl GasMeter, + tracer: &mut Option>, ) -> VMResult { - self.execute_code_impl(resolver, interpreter, gas_meter) + self.execute_code_impl(resolver, interpreter, gas_meter, tracer) .map_err(|e| { let e = if resolver.loader().vm_config().error_execution_state { e.with_exec_state(interpreter.get_internal_state()) @@ -1363,11 +1427,13 @@ impl Frame { Ok(InstrRet::Ok) } + #[allow(unused_variables)] fn execute_code_impl( &mut self, resolver: &Resolver, interpreter: &mut Interpreter, gas_meter: &mut impl GasMeter, + tracer: &mut Option>, ) -> PartialVMResult { let code = self.function.code(); loop { @@ -1385,7 +1451,14 @@ impl Frame { ) }); - profile_open_instr!(gas_meter, format!("{:?}", instruction)); + open_instruction!( + tracer, + instruction, + self, + interpreter, + resolver.loader(), + gas_meter + ); let r = Self::execute_instruction( &mut self.pc, @@ -1396,11 +1469,19 @@ impl Frame { interpreter, gas_meter, instruction, - )?; + ); - profile_close_instr!(gas_meter, format!("{:?}", instruction)); + close_instruction!( + tracer, + instruction, + self, + interpreter, + resolver.loader(), + gas_meter, + r.as_ref().err() + ); - match r { + match r? { InstrRet::Ok => (), InstrRet::ExitCode(exit_code) => { return Ok(exit_code); @@ -1501,7 +1582,8 @@ impl Frame { } Type::DatatypeInstantiation(inst) => { let (si, ty_args) = &**inst; - // Calculate depth of all type arguments, and make sure they themselves are not too deep. + // Calculate depth of all type arguments, and make sure they themselves are not + // too deep. let ty_arg_depths = ty_args .iter() .map(|ty| { diff --git a/external-crates/move/crates/move-vm-runtime/src/lib.rs b/external-crates/move/crates/move-vm-runtime/src/lib.rs index 137ad35ec95..92490ffe0a8 100644 --- a/external-crates/move/crates/move-vm-runtime/src/lib.rs +++ b/external-crates/move/crates/move-vm-runtime/src/lib.rs @@ -22,9 +22,10 @@ pub mod runtime; pub mod session; #[macro_use] mod tracing; +mod tracing2; // Only include debugging functionality in debug builds -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] mod debug; #[cfg(test)] diff --git a/external-crates/move/crates/move-vm-runtime/src/loader.rs b/external-crates/move/crates/move-vm-runtime/src/loader.rs index 07dd1f0fece..f2893c01a09 100644 --- a/external-crates/move/crates/move-vm-runtime/src/loader.rs +++ b/external-crates/move/crates/move-vm-runtime/src/loader.rs @@ -1360,7 +1360,7 @@ impl Loader { // Return an instantiated type given a generic and an instantiation. // Stopgap to avoid a recursion that is either taking too long or using too // much memory - fn subst(&self, ty: &Type, ty_args: &[Type]) -> PartialVMResult { + pub(crate) fn subst(&self, ty: &Type, ty_args: &[Type]) -> PartialVMResult { // Before instantiating the type, count the # of nodes of all type arguments plus // existing type instantiation. // If that number is larger than MAX_TYPE_INSTANTIATION_NODES, refuse to construct this type. @@ -1378,6 +1378,14 @@ impl Loader { ty.subst(ty_args) } + pub(crate) fn make_type( + &self, + module: &CompiledModule, + tok: &SignatureToken, + ) -> PartialVMResult { + self.module_cache.read().make_type(module, tok) + } + // Verify the kind (constraints) of an instantiation. // Function invocations call this function to verify correctness of type // arguments provided @@ -1407,7 +1415,7 @@ impl Loader { self.module_cache.read().function_at(idx) } - fn get_module( + pub(crate) fn get_module( &self, link_context: AccountAddress, runtime_id: &ModuleId, @@ -2210,7 +2218,7 @@ impl Function { ) } - #[cfg(any(debug_assertions, feature = "debugging"))] + #[cfg(any(debug_assertions, feature = "tracing"))] pub(crate) fn pretty_short_string(&self) -> String { let id = &self.module; format!( @@ -2369,11 +2377,9 @@ impl TypeCache { /// Maximal depth of a value in terms of type depth. pub const VALUE_DEPTH_MAX: u64 = 128; -/// Maximal nodes which are allowed when converting to layout. This includes the types of +/// [Historical] Maximal nodes which are allowed when converting to layout. This includes the types of /// fields for struct types. -/// Maximal nodes which are allowed when converting to layout. This includes the types of -/// fields for datatypes. -const MAX_TYPE_TO_LAYOUT_NODES: u64 = 256; +const HISTORICAL_MAX_TYPE_TO_LAYOUT_NODES: u64 = 256; /// Maximal nodes which are all allowed when instantiating a generic type. This does not include /// field types of datatypes. @@ -2542,7 +2548,7 @@ impl Loader { .collect::>>()?; variant_layouts.push(field_layouts); } - R::MoveDatatypeLayout::Enum(R::MoveEnumLayout(variant_layouts)) + R::MoveDatatypeLayout::Enum(Box::new(R::MoveEnumLayout(Box::new(variant_layouts)))) } Datatype::Struct(ref sinfo) => { let field_tys = sinfo @@ -2555,7 +2561,7 @@ impl Loader { .map(|ty| self.type_to_type_layout_impl(ty, count, depth + 1)) .collect::>>()?; - R::MoveDatatypeLayout::Struct(R::MoveStructLayout::new(field_layouts)) + R::MoveDatatypeLayout::Struct(Box::new(R::MoveStructLayout::new(field_layouts))) } }; @@ -2580,14 +2586,19 @@ impl Loader { count: &mut u64, depth: u64, ) -> PartialVMResult { - if *count > MAX_TYPE_TO_LAYOUT_NODES { + if *count + > self + .vm_config() + .max_type_to_layout_nodes + .unwrap_or(HISTORICAL_MAX_TYPE_TO_LAYOUT_NODES) + { return Err(PartialVMError::new(StatusCode::TOO_MANY_TYPE_NODES)); } if depth > VALUE_DEPTH_MAX { return Err(PartialVMError::new(StatusCode::VM_MAX_VALUE_DEPTH_REACHED)); } *count += 1; - Ok(match ty { + let ty = match ty { Type::Bool => R::MoveTypeLayout::Bool, Type::U8 => R::MoveTypeLayout::U8, Type::U16 => R::MoveTypeLayout::U16, @@ -2614,7 +2625,8 @@ impl Loader { .with_message(format!("no type layout for {:?}", ty)), ); } - }) + }; + Ok(ty) } fn datatype_gidx_to_fully_annotated_layout( @@ -2667,10 +2679,10 @@ impl Loader { field_layouts, ); } - A::MoveDatatypeLayout::Enum(A::MoveEnumLayout { + A::MoveDatatypeLayout::Enum(Box::new(A::MoveEnumLayout { type_: struct_tag.clone(), variants: variant_layouts, - }) + })) } Datatype::Struct(struct_type) => { if struct_type.fields.len() != struct_type.field_names.len() { @@ -2692,7 +2704,10 @@ impl Loader { Ok(A::MoveFieldLayout::new(n.clone(), l)) }) .collect::>>()?; - A::MoveDatatypeLayout::Struct(A::MoveStructLayout::new(struct_tag, field_layouts)) + A::MoveDatatypeLayout::Struct(Box::new(A::MoveStructLayout::new( + struct_tag, + field_layouts, + ))) } }; @@ -2717,7 +2732,12 @@ impl Loader { count: &mut u64, depth: u64, ) -> PartialVMResult { - if *count > MAX_TYPE_TO_LAYOUT_NODES { + if *count + > self + .vm_config() + .max_type_to_layout_nodes + .unwrap_or(HISTORICAL_MAX_TYPE_TO_LAYOUT_NODES) + { return Err(PartialVMError::new(StatusCode::TOO_MANY_TYPE_NODES)); } if depth > VALUE_DEPTH_MAX { diff --git a/external-crates/move/crates/move-vm-runtime/src/native_functions.rs b/external-crates/move/crates/move-vm-runtime/src/native_functions.rs index 54d9f9a3d7e..f9e7ba44529 100644 --- a/external-crates/move/crates/move-vm-runtime/src/native_functions.rs +++ b/external-crates/move/crates/move-vm-runtime/src/native_functions.rs @@ -10,7 +10,10 @@ use std::{ sync::Arc, }; -use move_binary_format::errors::{ExecutionState, PartialVMError, PartialVMResult}; +use move_binary_format::{ + errors::{ExecutionState, PartialVMError, PartialVMResult}, + file_format::AbilitySet, +}; use move_core_types::{ account_address::AccountAddress, annotated_value as A, @@ -158,6 +161,10 @@ impl<'a, 'b> NativeContext<'a, 'b> { } } + pub fn type_to_abilities(&self, ty: &Type) -> PartialVMResult { + self.resolver.loader().abilities(ty) + } + pub fn extensions(&self) -> &NativeContextExtensions<'b> { self.extensions } diff --git a/external-crates/move/crates/move-vm-runtime/src/runtime.rs b/external-crates/move/crates/move-vm-runtime/src/runtime.rs index e310c217e1e..af124aeab54 100644 --- a/external-crates/move/crates/move-vm-runtime/src/runtime.rs +++ b/external-crates/move/crates/move-vm-runtime/src/runtime.rs @@ -6,9 +6,9 @@ use std::{borrow::Borrow, collections::BTreeSet, sync::Arc}; use move_binary_format::{ - errors::{verification_error, Location, PartialVMError, PartialVMResult, VMResult}, - file_format::{AbilitySet, LocalIndex}, CompiledModule, IndexKind, + errors::{Location, PartialVMError, PartialVMResult, VMResult, verification_error}, + file_format::{AbilitySet, LocalIndex}, }; use move_bytecode_verifier::script_signature; use move_core_types::{ @@ -20,6 +20,7 @@ use move_core_types::{ runtime_value::MoveTypeLayout, vm_status::StatusCode, }; +use move_trace_format::format::MoveTraceBuilder; use move_vm_config::runtime::VMConfig; use move_vm_types::{ data_store::DataStore, @@ -36,6 +37,7 @@ use crate::{ native_extensions::NativeContextExtensions, native_functions::{NativeFunction, NativeFunctions}, session::{LoadedFunctionInstantiation, SerializedReturnValues, Session}, + tracing2::tracer::VMTracer, }; /// An instantiation of the MoveVM. @@ -333,6 +335,7 @@ impl VMRuntime { data_store: &mut impl DataStore, gas_meter: &mut impl GasMeter, extensions: &mut NativeContextExtensions, + tracer: &mut Option>, ) -> VMResult { let arg_types = param_types .into_iter() @@ -364,6 +367,7 @@ impl VMRuntime { gas_meter, extensions, &self.loader, + tracer, )?; let serialized_return_values = self @@ -404,6 +408,7 @@ impl VMRuntime { gas_meter: &mut impl GasMeter, extensions: &mut NativeContextExtensions, bypass_declared_entry_check: bool, + tracer: Option<&mut MoveTraceBuilder>, ) -> VMResult { use move_binary_format::file_format::SignatureIndex; fn check_is_entry( @@ -455,6 +460,7 @@ impl VMRuntime { data_store, gas_meter, extensions, + &mut tracer.map(VMTracer::new), ) } @@ -504,7 +510,7 @@ impl VMRuntime { gas_meter: &mut impl GasMeter, extensions: &mut NativeContextExtensions, ) -> VMResult { - move_vm_profiler::gas_profiler_feature_enabled! { + move_vm_profiler::tracing_feature_enabled! { use move_vm_profiler::GasProfiler; if gas_meter.get_profiler_mut().is_none() { gas_meter.set_profiler(GasProfiler::init_default_cfg( @@ -524,6 +530,7 @@ impl VMRuntime { gas_meter, extensions, bypass_declared_entry_check, + None, ) } diff --git a/external-crates/move/crates/move-vm-runtime/src/session.rs b/external-crates/move/crates/move-vm-runtime/src/session.rs index 53e92a7cf17..65505a0e683 100644 --- a/external-crates/move/crates/move-vm-runtime/src/session.rs +++ b/external-crates/move/crates/move-vm-runtime/src/session.rs @@ -18,6 +18,7 @@ use move_core_types::{ resolver::MoveResolver, runtime_value::MoveTypeLayout, }; +use move_trace_format::format::MoveTraceBuilder; use move_vm_types::{ data_store::DataStore, gas::GasMeter, @@ -93,6 +94,7 @@ impl<'r, 'l, S: MoveResolver> Session<'r, 'l, S> { gas_meter, &mut self.native_extensions, bypass_declared_entry_check, + None, ) } @@ -105,7 +107,7 @@ impl<'r, 'l, S: MoveResolver> Session<'r, 'l, S> { args: Vec>, gas_meter: &mut impl GasMeter, ) -> VMResult { - move_vm_profiler::gas_profiler_feature_enabled! { + move_vm_profiler::tracing_feature_enabled! { use move_vm_profiler::GasProfiler; if gas_meter.get_profiler_mut().is_none() { gas_meter.set_profiler(GasProfiler::init_default_cfg( @@ -125,6 +127,46 @@ impl<'r, 'l, S: MoveResolver> Session<'r, 'l, S> { gas_meter, &mut self.native_extensions, bypass_declared_entry_check, + None, + ) + } + + pub fn execute_function_bypass_visibility_with_tracer_if_enabled( + &mut self, + module: &ModuleId, + function_name: &IdentStr, + ty_args: Vec, + args: Vec>, + gas_meter: &mut impl GasMeter, + tracer: Option<&mut MoveTraceBuilder>, + ) -> VMResult { + move_vm_profiler::tracing_feature_enabled! { + use move_vm_profiler::GasProfiler; + if gas_meter.get_profiler_mut().is_none() { + gas_meter.set_profiler(GasProfiler::init_default_cfg( + function_name.to_string(), + gas_meter.remaining_gas().into(), + )); + } + } + + let tracer = if cfg!(feature = "tracing") { + tracer + } else { + None + }; + + let bypass_declared_entry_check = true; + self.runtime.execute_function( + module, + function_name, + ty_args, + args, + &mut self.data_cache, + gas_meter, + &mut self.native_extensions, + bypass_declared_entry_check, + tracer, ) } diff --git a/external-crates/move/crates/move-vm-runtime/src/tracing.rs b/external-crates/move/crates/move-vm-runtime/src/tracing.rs index f2e2a6fe2f9..f13c21550ba 100644 --- a/external-crates/move/crates/move-vm-runtime/src/tracing.rs +++ b/external-crates/move/crates/move-vm-runtime/src/tracing.rs @@ -3,7 +3,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] use ::{ move_binary_format::file_format::Bytecode, move_vm_types::values::Locals, @@ -18,33 +18,33 @@ use ::{ }, }; -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] use crate::debug::DebugContext; -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] use crate::{ interpreter::Interpreter, loader::{Function, Loader}, }; -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] const MOVE_VM_TRACING_ENV_VAR_NAME: &str = "MOVE_VM_TRACE"; -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] const MOVE_VM_STEPPING_ENV_VAR_NAME: &str = "MOVE_VM_STEP"; -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] static FILE_PATH: Lazy = Lazy::new(|| { env::var(MOVE_VM_TRACING_ENV_VAR_NAME).unwrap_or_else(|_| "move_vm_trace.trace".to_string()) }); -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] static TRACING_ENABLED: Lazy = Lazy::new(|| env::var(MOVE_VM_TRACING_ENV_VAR_NAME).is_ok()); -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] static DEBUGGING_ENABLED: Lazy = Lazy::new(|| env::var(MOVE_VM_STEPPING_ENV_VAR_NAME).is_ok()); -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] static LOGGING_FILE: Lazy> = Lazy::new(|| { Mutex::new( OpenOptions::new() @@ -55,11 +55,11 @@ static LOGGING_FILE: Lazy> = Lazy::new(|| { ) }); -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] static DEBUG_CONTEXT: Lazy> = Lazy::new(|| Mutex::new(DebugContext::new())); // Only include in debug builds -#[cfg(any(debug_assertions, feature = "debugging"))] +#[cfg(any(debug_assertions, feature = "tracing"))] pub(crate) fn trace( function_desc: &Function, locals: &Locals, @@ -93,7 +93,7 @@ pub(crate) fn trace( macro_rules! trace { ($function_desc:expr, $locals:expr, $pc:expr, $instr:tt, $resolver:expr, $interp:expr) => { // Only include this code in debug releases - #[cfg(any(debug_assertions, feature = "debugging"))] + #[cfg(any(debug_assertions, feature = "tracing"))] $crate::tracing::trace( &$function_desc, $locals, diff --git a/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs b/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs new file mode 100644 index 00000000000..408ec299ff4 --- /dev/null +++ b/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs @@ -0,0 +1,108 @@ +pub(crate) mod tracer; + +#[cfg(feature = "tracing")] +pub(crate) const TRACING_ENABLED: bool = true; + +#[cfg(not(feature = "tracing"))] +pub(crate) const TRACING_ENABLED: bool = false; + +#[macro_export] +macro_rules! open_initial_frame { + ($tracer: expr, $args: expr, $ty_args: expr, $function: expr, $loader: expr, $gas_meter: expr, $link_context: expr) => { + if $crate::tracing2::TRACING_ENABLED { + $tracer.as_mut().map(|tracer| { + tracer.open_initial_frame( + $args, + $ty_args, + $function, + $loader, + $gas_meter.remaining_gas().into(), + $link_context, + ) + }); + move_vm_profiler::profile_open_frame!($gas_meter, $function.pretty_string()); + } + }; +} + +#[macro_export] +macro_rules! close_initial_frame { + ($tracer: expr, $function: expr, $return_values: expr, $gas_meter: expr) => { + if $crate::tracing2::TRACING_ENABLED { + $tracer.as_mut().map(|tracer| { + tracer.close_initial_frame($return_values, $gas_meter.remaining_gas().into()) + }); + move_vm_profiler::profile_close_frame!($gas_meter, $function.pretty_string()); + } + }; +} + +#[macro_export] +macro_rules! close_frame { + ($tracer: expr, $frame: expr, $function: expr, $interp: expr, $loader: expr, $gas_meter: expr, $link_context: expr, $call_err: expr) => { + if $crate::tracing2::TRACING_ENABLED { + $tracer.as_mut().map(|tracer| { + tracer.close_frame( + $frame, + $function, + $interp, + $loader, + $gas_meter.remaining_gas().into(), + $link_context, + $call_err, + ) + }); + move_vm_profiler::profile_close_frame!($gas_meter, $function.pretty_string()); + } + }; +} + +#[macro_export] +macro_rules! open_frame { + ($tracer: expr, $ty_args: expr, $function: expr, $calling_frame: expr, $interp: expr, $loader: expr, $gas_meter: expr, $link_context: expr) => { + if $crate::tracing2::TRACING_ENABLED { + $tracer.as_mut().map(|tracer| { + tracer.open_frame( + $ty_args, + $function, + $calling_frame, + $interp, + $loader, + $gas_meter.remaining_gas().into(), + $link_context, + ) + }); + move_vm_profiler::profile_open_frame!($gas_meter, $function.pretty_string()); + } + }; +} + +#[macro_export] +macro_rules! open_instruction { + ($tracer: expr, $instruction: expr, $frame: expr, $interp: expr, $loader: expr, $gas_meter: expr) => { + if $crate::tracing2::TRACING_ENABLED { + $tracer.as_mut().map(|tracer| { + tracer.open_instruction($frame, $interp, $loader, $gas_meter.remaining_gas().into()) + }); + move_vm_profiler::profile_open_instr!($gas_meter, format!("{:?}", $instruction)); + } + }; +} + +#[macro_export] +macro_rules! close_instruction { + ($tracer: expr, $instruction: expr, $frame: expr, $interp: expr, $loader: expr, $gas_meter: expr, $result: expr) => { + if $crate::tracing2::TRACING_ENABLED { + $tracer.as_mut().map(|tracer| { + tracer.close_instruction( + $frame, + $interp, + $loader, + $gas_meter.remaining_gas().into(), + $result, + ) + }); + move_vm_profiler::profile_close_instr!($gas_meter, format!("{:?}", $instruction)); + } + }; +} diff --git a/external-crates/move/crates/move-vm-runtime/src/tracing2/tracer.rs b/external-crates/move/crates/move-vm-runtime/src/tracing2/tracer.rs new file mode 100644 index 00000000000..8b80436c125 --- /dev/null +++ b/external-crates/move/crates/move-vm-runtime/src/tracing2/tracer.rs @@ -0,0 +1,1758 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + interpreter::{Frame, Interpreter}, + loader::{Function, Loader}, +}; +use move_binary_format::{ + errors::{PartialVMError, VMError, VMResult}, + file_format::{ConstantPoolIndex, SignatureIndex}, +}; +use move_core_types::{ + account_address::AccountAddress, + annotated_value::{MoveTypeLayout, MoveValue}, + language_storage::TypeTag, +}; +use move_trace_format::format::{ + DataLoad, Effect as EF, Location, MoveTraceBuilder, Read, RefType, TraceIndex, TraceValue, + TypeTagWithRefs, Write, +}; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; +use smallvec::SmallVec; +use std::collections::BTreeMap; + +/// Internal state for the tracer. This is where the actual tracing logic is implemented. +pub(crate) struct VMTracer<'a> { + trace: &'a mut MoveTraceBuilder, + link_context: Option, + pc: Option, + active_frames: BTreeMap, + type_stack: Vec, + loaded_data: BTreeMap, + effects: Vec, +} + +/// Information about a frame that we keep during trace building +#[derive(Debug, Clone)] +struct FrameInfo { + frame_identifier: TraceIndex, + is_native: bool, + locals_types: Vec, + return_types: Vec, +} + +/// A type tag, and the move type layout and reference information for that type if it is +/// computable without error. Due to runtime value depth restrictions you can have a valid type +/// whose type layout is not computable at runtime without error. +#[derive(Debug, Clone)] +struct TagWithLayoutInfoOpt { + tag: TypeTag, + layout: (Option, Option), +} + +// Information about a function that we use for trace building +// All types are fully substituted +#[derive(Debug, Clone)] +struct FunctionTypeInfo { + ty_args: Vec, + local_types: Vec, + return_types: Vec, +} + +/// A runtime location can refer to the stack to make it easier to refer to values on the stack and +/// resolving them. However, the stack is not a valid location for a reference and all references +/// are rooted in a local or global so the Trace `Location` does not include the stack, and +/// only `Local`, `Global`, and `Indexed` locations. +#[derive(Debug, Clone)] +enum RuntimeLocation { + Stack(usize), + Local(TraceIndex, usize), + Indexed(Box, usize), + Global(TraceIndex), +} + +/// The reference information for a local. This is used to track the state of a local in a frame. +/// * It can be a value, in which case the reference type is `Value`. +/// * It can be a local that does not currently hold a value (is "empty"), in which case +/// we track the reference type and the type of the local, but we don't have a `RuntimeLocation` +/// for the reference. This is e.g., the case when we open a frame and the local is not +/// initialized yet. +/// * It can be a local that holds a value (is "filled"), in which case we track the reference type and the +/// location the reference resolves to. +#[derive(Debug, Clone)] +enum ReferenceType { + Value, + Empty { + ref_type: RefType, + }, + Filled { + ref_type: RefType, + location: RuntimeLocation, + }, +} + +/// A `RootedType` is a a type layout with reference information, where any reference type is +/// fully rooted back to a specific location. +#[derive(Debug, Clone)] +struct RootedType { + layout: MoveTypeLayout, + ref_type: Option<(RefType, RuntimeLocation)>, +} + +/// A `LocalType` layout where a reference type may not be rooted to a +/// specific location (or it may be rooted to a specific location if the location is filled with a +/// value at the time). Note the type layout may be `None` in the case where the type is not +/// calculable at runtime without error. +#[derive(Debug, Clone)] +struct LocalType { + layout: Option, + ref_type: ReferenceType, +} + +impl TagWithLayoutInfoOpt { + pub fn as_tag_with_refs(&self) -> TypeTagWithRefs { + TypeTagWithRefs { + type_: self.tag.clone(), + ref_type: self.layout.1.clone(), + } + } +} + +impl RuntimeLocation { + fn as_trace_location(&self) -> Location { + match self { + RuntimeLocation::Stack(_) => { + panic!("Cannot convert stack location to trace location") + } + RuntimeLocation::Local(fidx, lidx) => Location::Local(*fidx, *lidx), + RuntimeLocation::Indexed(loc, idx) => { + Location::Indexed(Box::new(loc.as_trace_location()), *idx) + } + RuntimeLocation::Global(id) => Location::Global(*id), + } + } + + fn as_runtime_location(loc: Location) -> Self { + match loc { + Location::Local(fidx, lidx) => RuntimeLocation::Local(fidx, lidx), + Location::Indexed(loc, idx) => { + RuntimeLocation::Indexed(Box::new(RuntimeLocation::as_runtime_location(*loc)), idx) + } + Location::Global(id) => RuntimeLocation::Global(id), + } + } +} + +impl LocalType { + fn into_rooted_type(self) -> Option { + let ref_type = match self.ref_type { + ReferenceType::Value => None, + ReferenceType::Empty { .. } => panic!("Empty reference type"), + ReferenceType::Filled { ref_type, location } => Some((ref_type, location)), + }; + Some(RootedType { + layout: self.layout?, + ref_type, + }) + } +} + +impl RootedType { + fn into_local_type(self) -> LocalType { + let ref_type = match self.ref_type { + None => ReferenceType::Value, + Some((ref_type, location)) => ReferenceType::Filled { ref_type, location }, + }; + LocalType { + layout: Some(self.layout), + ref_type, + } + } +} + +impl<'a> VMTracer<'a> { + /// Emit an error event to the trace if `true` + fn emit_trace_error_if_err(&mut self, is_err: bool) { + if is_err { + self.trace.effect(EF::ExecutionError( + "!! TRACING ERROR !! Events below this may be incorrect.".to_string(), + )); + } + } + + fn current_frame(&self) -> Option<&FrameInfo> { + self.active_frames.last_key_value().map(|(_, v)| v) + } + + fn current_frame_mut(&mut self) -> Option<&mut FrameInfo> { + self.active_frames.last_entry().map(|e| e.into_mut()) + } + + /// Get the current locals type and reference state(s) + fn current_frame_locals(&self) -> Option<&[LocalType]> { + Some(self.current_frame()?.locals_types.as_slice()) + } + + /// Return the current frame identifier. This is trace index of the frame and is used to + /// identify reference locations rooted higher up the call stack. + fn current_frame_identifier(&self) -> Option { + Some(self.current_frame()?.frame_identifier) + } + + /// Given the trace index for a frame, return the index of the frame in the call stack. + fn trace_index_to_frame_index(&self, idx: TraceIndex) -> Option { + self.active_frames + .range(..=idx) + .enumerate() + .last() + .map(|(i, _)| i) + } + + /// Register the pre-effects for the instruction (i.e., reads, pops.) + fn register_pre_effects(&mut self, effects: Vec) { + assert!(self.effects.is_empty()); + self.effects = effects; + } + + /// Register the post-effects for the instruction (i.e., pushes, writes) and return the total + /// effects for the instruction. + fn register_post_effects(&mut self, effects: Vec) -> Vec { + self.effects.extend(effects); + std::mem::take(&mut self.effects) + } + + /// Insert a local with a specifice runtime location into the current frame. + fn insert_local(&mut self, local_index: usize, local: RootedType) -> Option<()> { + *self + .current_frame_mut()? + .locals_types + .get_mut(local_index)? = local.into_local_type(); + Some(()) + } + + /// Invalidate a local in the current frame. This is used to mark a local as uninitialized and + /// remove its reference information. + fn invalidate_local(&mut self, local_index: usize) -> Option<()> { + let local = self + .current_frame_mut()? + .locals_types + .get_mut(local_index)?; + match &local.ref_type { + ReferenceType::Filled { ref_type, .. } => { + local.ref_type = ReferenceType::Empty { + ref_type: ref_type.clone(), + } + } + ReferenceType::Empty { .. } => (), + ReferenceType::Value => (), + }; + Some(()) + } + + /// Resolve a value on the stack to a TraceValue. References are fully rooted all the way back + /// to their location in a local. + fn resolve_stack_value( + &self, + frame: Option<&Frame>, + interpreter: &Interpreter, + stack_idx: usize, + ) -> Option { + if stack_idx >= interpreter.operand_stack.value.len() { + return None; + } + let offset = self.type_stack.len() - 1; + self.resolve_location( + &RuntimeLocation::Stack(offset - stack_idx), + frame, + interpreter, + ) + } + + /// Resolve a value in a local to a TraceValue. References are fully rooted all the way back to + /// their root location in a local. + fn resolve_local( + &self, + frame: &Frame, + interpreter: &Interpreter, + local_index: usize, + ) -> Option { + self.resolve_location( + &RuntimeLocation::Local(self.current_frame_identifier()?, local_index), + Some(frame), + interpreter, + ) + } + + /// Shared utility function that creates a TraceValue from a runtime location along with + /// grabbing the snapshot of the value. + fn make_trace_value( + &self, + location: RuntimeLocation, + ref_info: Option, + frame: Option<&Frame>, + interpreter: &Interpreter, + ) -> Option { + let value = self.root_location_snapshot(&location, frame, interpreter)?; + Some(match ref_info { + Some(RefType::Imm) => TraceValue::ImmRef { + location: location.as_trace_location(), + snapshot: Box::new(value), + }, + Some(RefType::Mut) => TraceValue::MutRef { + location: location.as_trace_location(), + snapshot: Box::new(value), + }, + None => TraceValue::RuntimeValue { value }, + }) + } + + /// Given a location, resolve it to the value it points to or the value itself in the case + /// where it's not a reference. + fn resolve_location( + &self, + loc: &RuntimeLocation, + frame: Option<&Frame>, + interpreter: &Interpreter, + ) -> Option { + Some(match loc { + RuntimeLocation::Stack(sidx) => { + let ty = self.type_stack.get(*sidx)?; + let ref_ty = ty.ref_type.as_ref().map(|(r, _)| r.clone()); + let location = ty + .ref_type + .as_ref() + .map(|(_, l)| l.clone()) + .unwrap_or_else(|| loc.clone()); + self.make_trace_value(location, ref_ty, frame, interpreter)? + } + RuntimeLocation::Local(fidx, lidx) => { + let ty = &self.active_frames.get(fidx)?.locals_types.get(*lidx)?; + let ref_ty = match &ty.ref_type { + ReferenceType::Value => None, + ReferenceType::Empty { ref_type } => Some(ref_type.clone()), + ReferenceType::Filled { ref_type, .. } => Some(ref_type.clone()), + }; + let location = match &ty.ref_type { + ReferenceType::Filled { location, .. } => location.clone(), + ReferenceType::Value => loc.clone(), + _ => panic!( + "We tried to access a local that was not initialized at {:?}", + loc + ), + }; + self.make_trace_value(location, ref_ty, frame, interpreter)? + } + RuntimeLocation::Indexed(location, _) => { + self.resolve_location(location, frame, interpreter)? + } + RuntimeLocation::Global(id) => self.loaded_data.get(id)?.clone(), + }) + } + + /// Snapshot the value at the root of a location. This is used to create the value snapshots + /// for TraceValue references. + fn root_location_snapshot( + &self, + loc: &RuntimeLocation, + frame: Option<&Frame>, + interpreter: &Interpreter, + ) -> Option { + Some(match loc { + RuntimeLocation::Local(fidx, loc_idx) => { + let local_ty = self + .active_frames + .get(fidx)? + .locals_types + .get(*loc_idx)? + .clone(); + let call_stack_index = self.trace_index_to_frame_index(*fidx)?; + match local_ty.ref_type { + ReferenceType::Value => { + let frame = if call_stack_index >= interpreter.call_stack.0.len() { + frame? + } else { + interpreter.call_stack.0.get(call_stack_index)? + }; + frame + .locals + .copy_loc(*loc_idx) + .ok()? + .as_annotated_move_value_for_tracing_only(&local_ty.layout?)? + } + ReferenceType::Empty { .. } => { + panic!("We tried to access a local that was not initialized") + } + ReferenceType::Filled { location, .. } => { + self.root_location_snapshot(&location, frame, interpreter)? + } + } + } + RuntimeLocation::Stack(stack_idx) => { + let ty = self.type_stack.get(*stack_idx)?; + match &ty.ref_type { + Some((_, location)) => { + self.root_location_snapshot(location, frame, interpreter)? + } + None => { + let value = interpreter.operand_stack.value.get(*stack_idx)?; + value.as_annotated_move_value_for_tracing_only(&ty.layout)? + } + } + } + RuntimeLocation::Indexed(loc, _) => { + self.root_location_snapshot(loc, frame, interpreter)? + } + RuntimeLocation::Global(id) => self.loaded_data.get(id)?.snapshot().clone(), + }) + } + + fn link_context(&self) -> AccountAddress { + self.link_context + .expect("Link context always set by this point") + } + + /// Load data returned by a native function into the tracer state. + /// We also emit a data load event for the data loaded from the native function. + fn load_data( + &mut self, + layout: &MoveTypeLayout, + reftype: &Option, + value: &Value, + ) -> Option<(RefType, RuntimeLocation)> { + let value = value.as_annotated_move_value_for_tracing_only(layout)?; + + let Some(ref_type) = reftype else { + return None; + }; + + // We treat any references coming out of a native as global reference. + // This generally works fine as long as you don't have a native function returning a + // mutable reference within a mutable reference passed-in. + let id = self.trace.current_trace_offset(); + + let location = RuntimeLocation::Global(id); + + self.trace.effect(EF::DataLoad(DataLoad { + ref_type: ref_type.clone(), + location: location.as_trace_location(), + snapshot: value.clone(), + })); + let trace_value = match &ref_type { + RefType::Imm => TraceValue::ImmRef { + location: location.as_trace_location(), + snapshot: Box::new(value), + }, + RefType::Mut => TraceValue::MutRef { + location: location.as_trace_location(), + snapshot: Box::new(value), + }, + }; + self.loaded_data.insert(id, trace_value); + Some((ref_type.clone(), location)) + } + + /// Handle (and load) any data returned by a native function. + fn handle_native_return( + &mut self, + function: &Function, + interpreter: &Interpreter, + ) -> Option<()> { + assert!(function.is_native()); + let trace_frame = self.current_frame()?.clone(); + assert!(trace_frame.is_native); + let len = interpreter.operand_stack.value.len(); + for (i, r_ty) in trace_frame.return_types.iter().cloned().enumerate() { + let r_ty = r_ty.layout; + let ref_type = self.load_data( + r_ty.0.as_ref()?, + &r_ty.1, + interpreter.operand_stack.value.get(len - i - 1)?, + ); + self.type_stack.push(RootedType { + layout: r_ty.0?, + ref_type, + }); + } + Some(()) + } + + //--------------------------------------------------------------------------- + // Core entry points for the tracer + //--------------------------------------------------------------------------- + + fn open_initial_frame_( + &mut self, + args: &[Value], + ty_args: &[Type], + function: &Function, + loader: &Loader, + remaining_gas: u64, + link_context: AccountAddress, + ) -> Option<()> { + self.link_context = Some(link_context); + + let function_type_info = FunctionTypeInfo::new(function, loader, ty_args, link_context)?; + + assert!(function_type_info.local_types.len() == function.local_count()); + + let call_args: Vec<_> = args + .iter() + .zip(function_type_info.local_types.iter().cloned()) + .map(|(value, tag_with_layout_info_opt)| { + let (layout, ref_type) = tag_with_layout_info_opt.layout; + let move_value = value.as_annotated_move_value_for_tracing_only(&layout?)?; + assert!(ref_type.is_none()); + Some(TraceValue::RuntimeValue { value: move_value }) + }) + .collect::>()?; + + let locals_types = function_type_info + .local_types + .iter() + .cloned() + .map(|tag_with_layout_info_opt| { + let (layout, ref_type) = tag_with_layout_info_opt.layout; + LocalType { + layout, + ref_type: ref_type + .map(|r_type| match r_type { + RefType::Imm => ReferenceType::Empty { ref_type: r_type }, + RefType::Mut => ReferenceType::Empty { ref_type: r_type }, + }) + .unwrap_or(ReferenceType::Value), + } + }) + .collect(); + + let current_trace_offset = self.trace.current_trace_offset(); + self.active_frames.insert( + current_trace_offset, + FrameInfo { + frame_identifier: current_trace_offset, + is_native: function.is_native(), + locals_types, + return_types: function_type_info.return_types.clone(), + }, + ); + + self.trace.open_frame( + self.current_frame_identifier()?, + function.index(), + function.name().to_string(), + function.module_id().clone(), + call_args, + function_type_info.ty_args, + function_type_info + .return_types + .iter() + .map(|tag_with_layout_info_opt| tag_with_layout_info_opt.as_tag_with_refs()) + .collect(), + function_type_info + .local_types + .into_iter() + .map(|tag_with_layout_info_opt| tag_with_layout_info_opt.as_tag_with_refs()) + .collect(), + function.is_native(), + remaining_gas, + ); + Some(()) + } + + fn close_initial_frame_(&mut self, return_values: &[Value], remaining_gas: u64) -> Option<()> { + let current_frame_return_tys = self.current_frame()?.return_types.clone(); + let return_values: Vec<_> = return_values + .iter() + .zip(current_frame_return_tys.into_iter()) + .map(|(value, tag_with_layout_info_opt)| { + let (layout, ref_type) = tag_with_layout_info_opt.layout; + let move_value = value.as_annotated_move_value_for_tracing_only(&layout?)?; + assert!(ref_type.is_none()); + Some(TraceValue::RuntimeValue { value: move_value }) + }) + .collect::>()?; + self.trace.close_frame( + self.current_frame_identifier()?, + return_values, + remaining_gas, + ); + self.active_frames + .pop_last() + .expect("Unbalanced frame close"); + Some(()) + } + + fn open_frame_( + &mut self, + ty_args: &[Type], + function: &Function, + calling_frame: &Frame, + interpreter: &Interpreter, + loader: &Loader, + remaining_gas: u64, + link_context: AccountAddress, + ) -> Option<()> { + self.link_context = Some(link_context); + + let call_args = (0..function.arg_count()) + .rev() + .map(|i| self.resolve_stack_value(Some(calling_frame), interpreter, i)) + .collect::>>()?; + + let call_args_types = self + .type_stack + .split_off(self.type_stack.len() - function.arg_count()); + let function_type_info = FunctionTypeInfo::new(function, loader, ty_args, link_context)?; + + let locals_types = function_type_info + .local_types + .iter() + .cloned() + .enumerate() + .map(|(i, tag_with_layout_info_opt)| { + // For any arguments, start them out with the correct locations + if let Some(a_layout) = call_args_types.get(i).cloned() { + let ref_type = match a_layout.ref_type { + Some((ref_type, location)) => ReferenceType::Filled { ref_type, location }, + None => ReferenceType::Value, + }; + LocalType { + layout: Some(a_layout.layout), + ref_type, + } + } else { + let (layout, ref_type) = tag_with_layout_info_opt.layout; + let ref_type = ref_type + .map(|ref_type| ReferenceType::Empty { ref_type }) + .unwrap_or(ReferenceType::Value); + LocalType { layout, ref_type } + } + }) + .collect(); + + let current_trace_offset = self.trace.current_trace_offset(); + self.active_frames.insert( + current_trace_offset, + FrameInfo { + frame_identifier: current_trace_offset, + is_native: function.is_native(), + locals_types, + return_types: function_type_info.return_types.clone(), + }, + ); + + self.trace.open_frame( + self.current_frame_identifier()?, + function.index(), + function.name().to_string(), + function.module_id().clone(), + call_args, + function_type_info.ty_args, + function_type_info + .return_types + .iter() + .map(|tag_with_layout_info_opt| tag_with_layout_info_opt.as_tag_with_refs()) + .collect(), + function_type_info + .local_types + .into_iter() + .map(|tag_with_layout_info_opt| tag_with_layout_info_opt.as_tag_with_refs()) + .collect(), + function.is_native(), + remaining_gas, + ); + Some(()) + } + + fn close_frame_( + &mut self, + frame: &Frame, + function: &Function, + interpreter: &Interpreter, + _loader: &Loader, + remaining_gas: u64, + _link_context: AccountAddress, + ) -> Option<()> { + if function.is_native() { + self.handle_native_return(function, interpreter) + .expect("Native function return failed -- this should not happen."); + } + + let return_values = (0..function.return_type_count()) + .rev() + .map(|i| self.resolve_stack_value(Some(frame), interpreter, i)) + .collect::>>()?; + + // Note that when a native function frame closes the values returned by the native function + // are all pushed on the operand stack. + if function.is_native() { + for val in &return_values { + self.trace.effect(EF::Push(val.clone())); + } + } + + self.trace.close_frame( + self.current_frame_identifier()?, + return_values, + remaining_gas, + ); + self.active_frames + .pop_last() + .expect("Unbalanced frame close"); + Some(()) + } + + fn open_instruction_( + &mut self, + frame: &Frame, + interpreter: &Interpreter, + loader: &Loader, + _remaining_gas: u64, + ) -> Option<()> { + use move_binary_format::file_format::Bytecode as B; + + let pc = frame.pc; + self.pc = Some(pc); + + let popn = |n: usize| { + let mut effects = vec![]; + for i in 0..n { + let v = self.resolve_stack_value(Some(frame), interpreter, i)?; + effects.push(EF::Pop(v)); + } + Some(effects) + }; + + assert_eq!( + self.type_stack.len(), + interpreter.operand_stack.value.len(), + "Type stack and operand stack must be the same length {} {}", + frame.function.name(), + pc, + ); + + match &frame.function.code()[pc as usize] { + B::Nop + | B::Branch(_) + | B::Ret + | B::LdU8(_) + | B::LdU16(_) + | B::LdU32(_) + | B::LdU64(_) + | B::LdU128(_) + | B::LdU256(_) + | B::LdFalse + | B::LdTrue + | B::LdConst(_) => { + self.register_pre_effects(vec![]); + } + B::MutBorrowField(_) + | B::ImmBorrowField(_) + | B::MutBorrowFieldGeneric(_) + | B::ImmBorrowFieldGeneric(_) + | B::FreezeRef + | B::Not + | B::Abort + | B::Unpack(_) + | B::UnpackGeneric(_) + | B::CastU8 + | B::CastU16 + | B::CastU32 + | B::CastU64 + | B::CastU128 + | B::CastU256 + | B::Pop + | B::BrTrue(_) + | B::BrFalse(_) + | B::VecUnpack(_, _) + | B::VecLen(_) + | B::VecPopBack(_) + | B::VariantSwitch(_) + | B::UnpackVariantImmRef(_) + | B::UnpackVariantMutRef(_) + | B::UnpackVariantGenericImmRef(_) + | B::UnpackVariantGenericMutRef(_) + | B::UnpackVariant(_) + | B::UnpackVariantGeneric(_) => { + self.register_pre_effects(popn(1)?); + } + B::Add + | B::Sub + | B::Mul + | B::Mod + | B::Div + | B::BitOr + | B::BitAnd + | B::Xor + | B::Shl + | B::Shr + | B::Lt + | B::Gt + | B::Le + | B::Ge + | B::Eq + | B::Neq + | B::Or + | B::And + | B::WriteRef + | B::VecImmBorrow(_) + | B::VecMutBorrow(_) + | B::VecPushBack(_) => self.register_pre_effects(popn(2)?), + B::VecSwap(_) => self.register_pre_effects(popn(3)?), + B::VecPack(_, n) => self.register_pre_effects(popn(*n as usize)?), + i @ (B::MoveLoc(l) | B::CopyLoc(l)) => { + let v = self.resolve_local(frame, interpreter, *l as usize)?; + let effects = vec![EF::Read(Read { + location: Location::Local(self.current_frame_identifier()?, *l as usize), + root_value_read: v.clone(), + moved: matches!(i, B::MoveLoc(_)), + })]; + self.register_pre_effects(effects); + } + B::StLoc(lidx) => { + let ty = self.type_stack.last()?; + let v = self.resolve_stack_value(Some(frame), interpreter, 0)?; + self.insert_local(*lidx as usize, ty.clone())?; + let effects = vec![EF::Pop(v.clone())]; + self.register_pre_effects(effects); + } + B::ImmBorrowLoc(l_idx) | B::MutBorrowLoc(l_idx) => { + let val = self.resolve_local(frame, interpreter, *l_idx as usize)?; + let location = Location::Local(self.current_frame_identifier()?, *l_idx as usize); + self.register_pre_effects(vec![EF::Read(Read { + location, + root_value_read: val, + moved: false, + })]); + } + // Handled by open frame + B::Call(_) | B::CallGeneric(_) => {} + B::Pack(sidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let field_count = resolver.field_count(*sidx) as usize; + self.register_pre_effects(popn(field_count)?); + } + B::PackGeneric(sidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let field_count = resolver.field_instantiation_count(*sidx) as usize; + self.register_pre_effects(popn(field_count)?); + } + B::PackVariant(vidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let (field_count, _variant_tag) = resolver.variant_field_count_and_tag(*vidx); + self.register_pre_effects(popn(field_count as usize)?); + } + B::PackVariantGeneric(vidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let (field_count, _variant_tag) = + resolver.variant_instantiantiation_field_count_and_tag(*vidx); + self.register_pre_effects(popn(field_count as usize)?); + } + B::ReadRef => { + let ref_value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let location = ref_value.location()?.clone(); + let runtime_location = RuntimeLocation::as_runtime_location(location.clone()); + let value = self.resolve_location(&runtime_location, Some(frame), interpreter)?; + self.register_pre_effects(vec![ + EF::Pop(ref_value), + EF::Read(Read { + location, + root_value_read: value.clone(), + moved: false, + }), + ]); + } + + B::ExistsDeprecated(_) + | B::ExistsGenericDeprecated(_) + | B::MoveFromDeprecated(_) + | B::MoveFromGenericDeprecated(_) + | B::MoveToDeprecated(_) + | B::MoveToGenericDeprecated(_) + | B::MutBorrowGlobalDeprecated(_) + | B::MutBorrowGlobalGenericDeprecated(_) + | B::ImmBorrowGlobalDeprecated(_) + | B::ImmBorrowGlobalGenericDeprecated(_) => unreachable!(), + } + Some(()) + } + + fn close_instruction_( + &mut self, + frame: &Frame, + interpreter: &Interpreter, + loader: &Loader, + remaining_gas: u64, + ) -> Option<()> { + use move_binary_format::file_format::Bytecode as B; + + // NB: Do _not_ use the frames pc here, as it will be incremented by the interpreter to the + // next instruction already. + let pc = self + .pc + .expect("PC always set by this point by `open_instruction`"); + + // NB: At the start of this function (i.e., at this point) the operand stack in the VM, and + // the type stack in the tracer are _out of sync_. This is because the VM has already + // executed the instruction and we now need to manage the type transition of the + // instruction along with snapshoting the effects of the instruction's execution. + let instruction = &frame.function.code()[pc as usize]; + match instruction { + B::Pop | B::BrTrue(_) | B::BrFalse(_) => { + self.type_stack.pop()?; + let effects = self.register_post_effects(vec![]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Branch(_) | B::Ret => { + let effects = self.register_post_effects(vec![]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::LdU8(_) + | B::LdU16(_) + | B::LdU32(_) + | B::LdU64(_) + | B::LdU128(_) + | B::LdU256(_) + | B::LdFalse + | B::LdTrue + | B::LdConst(_)) => { + let layout = match i { + B::LdU8(_) => MoveTypeLayout::U8, + B::LdU16(_) => MoveTypeLayout::U16, + B::LdU32(_) => MoveTypeLayout::U32, + B::LdU64(_) => MoveTypeLayout::U64, + B::LdU128(_) => MoveTypeLayout::U128, + B::LdU256(_) => MoveTypeLayout::U256, + B::LdTrue => MoveTypeLayout::Bool, + B::LdFalse => MoveTypeLayout::Bool, + B::LdConst(const_idx) => get_constant_type_layout( + &frame.function, + loader, + self.link_context(), + *const_idx, + )?, + _ => unreachable!(), + }; + let a_layout = RootedType { + layout, + ref_type: None, + }; + self.type_stack.push(a_layout); + + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = vec![EF::Push(value)]; + let effects = self.register_post_effects(effects); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::MoveLoc(l) | B::CopyLoc(l)) => { + let local_annot_type = self + .current_frame_locals()? + .get(*l as usize)? + .clone() + .into_rooted_type()?; + self.type_stack.push(local_annot_type); + if matches!(i, B::MoveLoc(_)) { + self.invalidate_local(*l as usize)?; + } + // This was pushed on the stack during execution so read it off from there. + let v = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(v.clone())]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::CastU8 | B::CastU16 | B::CastU32 | B::CastU64 | B::CastU128 | B::CastU256) => { + let layout = match i { + B::CastU8 => MoveTypeLayout::U8, + B::CastU16 => MoveTypeLayout::U16, + B::CastU32 => MoveTypeLayout::U32, + B::CastU64 => MoveTypeLayout::U64, + B::CastU128 => MoveTypeLayout::U128, + B::CastU256 => MoveTypeLayout::U256, + _ => unreachable!(), + }; + let annot_layout = RootedType { + layout, + ref_type: None, + }; + self.type_stack.pop()?; + self.type_stack.push(annot_layout); + + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = vec![EF::Push(value.clone())]; + let effects = self.register_post_effects(effects); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::StLoc(lidx) => { + let ty = self.type_stack.pop()?; + self.insert_local(*lidx as usize, ty.clone())?; + let v = self.resolve_local(frame, interpreter, *lidx as usize)?; + let effects = self.register_post_effects(vec![EF::Write(Write { + location: Location::Local(self.current_frame_identifier()?, *lidx as usize), + root_value_after_write: v.clone(), + })]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Add + | B::Sub + | B::Mul + | B::Mod + | B::Div + | B::BitOr + | B::BitAnd + | B::Xor + | B::Shl + | B::Shr => { + self.type_stack.pop()?; + // NB in the case of shift left and shift right the second operand is the resultant + // value type. + let a_ty = self.type_stack.pop()?; + self.type_stack.push(a_ty); + + let result = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(result)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Lt | B::Gt | B::Le | B::Ge => { + self.type_stack.pop()?; + self.type_stack.pop()?; + let a_layout = RootedType { + layout: MoveTypeLayout::Bool, + ref_type: None, + }; + self.type_stack.push(a_layout); + + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Call(_) | B::CallGeneric(_) => { + // NB: We don't register effects for calls as they will be handled by + // open_frame. + self.trace + .instruction(instruction, vec![], vec![], remaining_gas, pc); + } + B::Pack(sidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let field_count = resolver.field_count(*sidx) as usize; + let struct_type = resolver.get_struct_type(*sidx); + let stack_len = self.type_stack.len(); + let _ = self.type_stack.split_off(stack_len - field_count); + let ty = loader.type_to_fully_annotated_layout(&struct_type).ok()?; + let a_layout = RootedType { + layout: ty, + ref_type: None, + }; + self.type_stack.push(a_layout); + + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::PackGeneric(sidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let field_count = resolver.field_instantiation_count(*sidx) as usize; + let struct_type = resolver + .instantiate_struct_type(*sidx, &frame.ty_args) + .ok()?; + let stack_len = self.type_stack.len(); + let _ = self.type_stack.split_off(stack_len - field_count); + let ty = loader.type_to_fully_annotated_layout(&struct_type).ok()?; + let a_layout = RootedType { + layout: ty, + ref_type: None, + }; + self.type_stack.push(a_layout); + + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + let TypeTag::Struct(s_type) = loader.type_to_type_tag(&struct_type).ok()? else { + panic!("Expected struct, got {:#?}", struct_type); + }; + self.trace + .instruction(instruction, s_type.type_params, effects, remaining_gas, pc); + } + B::Unpack(_) | B::UnpackGeneric(_) => { + let ty = self.type_stack.pop()?; + let MoveTypeLayout::Struct(s) = ty.layout else { + panic!("Expected struct, got {:#?}", ty.layout); + }; + let field_tys = s.fields.iter().map(|t| t.layout.clone()); + for field_ty in field_tys { + self.type_stack.push(RootedType { + layout: field_ty.clone(), + ref_type: None, + }); + } + + let mut effects = vec![]; + for i in (0..s.fields.len()).rev() { + let value = self.resolve_stack_value(Some(frame), interpreter, i)?; + effects.push(EF::Push(value)); + } + + let effects = self.register_post_effects(effects); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Eq | B::Neq => { + self.type_stack.pop()?; + self.type_stack.pop()?; + let a_layout = RootedType { + layout: MoveTypeLayout::Bool, + ref_type: None, + }; + self.type_stack.push(a_layout); + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Or | B::And => { + self.type_stack.pop()?; + self.type_stack.pop()?; + let a_layout = RootedType { + layout: MoveTypeLayout::Bool, + ref_type: None, + }; + self.type_stack.push(a_layout); + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Not => { + let a_ty = self.type_stack.pop()?; + self.type_stack.push(a_ty); + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::Nop => { + self.trace + .instruction(instruction, vec![], vec![], remaining_gas, pc); + } + B::Abort => { + self.type_stack.pop()?; + let effects = self.register_post_effects(vec![]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::ReadRef => { + let ref_ty = self.type_stack.pop()?; + let a_layout = RootedType { + layout: ref_ty.layout.clone(), + ref_type: None, + }; + self.type_stack.push(a_layout); + + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::ImmBorrowLoc(l_idx) | B::MutBorrowLoc(l_idx)) => { + let non_imm_ty = self.current_frame_locals()?.get(*l_idx as usize)?.clone(); + let ref_type = match i { + B::ImmBorrowLoc(_) => RefType::Imm, + B::MutBorrowLoc(_) => RefType::Mut, + _ => unreachable!(), + }; + let a_layout = RootedType { + layout: non_imm_ty.layout?.clone(), + ref_type: Some(( + ref_type, + RuntimeLocation::Local(self.current_frame_identifier()?, *l_idx as usize), + )), + }; + self.type_stack.push(a_layout); + + let val = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(val)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::WriteRef => { + let reference_ty = self.type_stack.pop()?; + let _value_ty = self.type_stack.pop()?; + let location = reference_ty.ref_type.as_ref()?.1.clone(); + let root_value_after_write = self + .resolve_location(&location, Some(frame), interpreter)? + .clone(); + let effects = self.register_post_effects(vec![EF::Write(Write { + location: location.as_trace_location(), + root_value_after_write, + })]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::FreezeRef => { + let mut reference_ty = self.type_stack.pop()?; + reference_ty.ref_type.as_mut()?.0 = RefType::Imm; + self.type_stack.push(reference_ty); + let reference_val = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(reference_val)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::MutBorrowField(fhidx) | B::ImmBorrowField(fhidx)) => { + let value_ty = self.type_stack.pop()?; + + let MoveTypeLayout::Struct(slayout) = &value_ty.layout else { + panic!("Expected struct, got {:?}", value_ty.layout) + }; + let resolver = frame.function.get_resolver(self.link_context(), loader); + let field_offset = resolver.field_offset(*fhidx); + let field_layout = slayout.fields.get(field_offset)?.layout.clone(); + + let location = value_ty.ref_type.as_ref()?.1.clone(); + let field_location = + RuntimeLocation::Indexed(Box::new(location.clone()), field_offset); + + let ref_type = match i { + B::MutBorrowField(_) => RefType::Mut, + B::ImmBorrowField(_) => RefType::Imm, + _ => unreachable!(), + }; + let a_layout = RootedType { + layout: field_layout, + ref_type: Some((ref_type, field_location)), + }; + self.type_stack.push(a_layout); + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::MutBorrowFieldGeneric(fhidx) | B::ImmBorrowFieldGeneric(fhidx)) => { + let value_ty = self.type_stack.pop()?; + + let MoveTypeLayout::Struct(slayout) = &value_ty.layout else { + panic!("Expected struct, got {:?}", value_ty.layout) + }; + let resolver = frame.function.get_resolver(self.link_context(), loader); + let field_offset = resolver.field_instantiation_offset(*fhidx); + let field_layout = slayout.fields.get(field_offset)?.layout.clone(); + let location = value_ty.ref_type.as_ref()?.1.clone(); + let field_location = + RuntimeLocation::Indexed(Box::new(location.clone()), field_offset); + + let ref_type = match i { + B::MutBorrowFieldGeneric(_) => RefType::Mut, + B::ImmBorrowFieldGeneric(_) => RefType::Imm, + _ => unreachable!(), + }; + let a_layout = RootedType { + layout: field_layout, + ref_type: Some((ref_type, field_location)), + }; + self.type_stack.push(a_layout); + let value = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(value)]); + let ty_args = slayout.type_.type_params.clone(); + self.trace + .instruction(instruction, ty_args, effects, remaining_gas, pc); + } + + B::VecPack(tok, n) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let ty = resolver + .instantiate_single_type(*tok, &frame.ty_args) + .ok()?; + let ty = loader.type_to_fully_annotated_layout(&ty).ok()?; + let ty = MoveTypeLayout::Vector(Box::new(ty)); + let stack_len = self.type_stack.len(); + let _ = self.type_stack.split_off(stack_len - *n as usize); + let a_layout = RootedType { + layout: ty, + ref_type: None, + }; + self.type_stack.push(a_layout); + let val = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(val)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::VecImmBorrow(_) | B::VecMutBorrow(_)) => { + let ref_type = match i { + B::VecImmBorrow(_) => RefType::Imm, + B::VecMutBorrow(_) => RefType::Mut, + _ => unreachable!(), + }; + self.type_stack.pop()?; + let ref_ty = self.type_stack.pop()?; + let MoveTypeLayout::Vector(ty) = ref_ty.layout else { + panic!("Expected vector, got {:?}", ref_ty.layout,); + }; + let EF::Pop(TraceValue::RuntimeValue { + value: MoveValue::U64(i), + }) = &self.effects[0] + else { + unreachable!(); + }; + let location = + RuntimeLocation::Indexed(Box::new(ref_ty.ref_type?.1.clone()), *i as usize); + let a_layout = RootedType { + layout: (*ty).clone(), + ref_type: Some((ref_type, location)), + }; + self.type_stack.push(a_layout); + let val = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(val)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::VecLen(_) => { + self.type_stack.pop()?; + let a_layout = RootedType { + layout: MoveTypeLayout::U64, + ref_type: None, + }; + self.type_stack.push(a_layout); + let len = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(len)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::VecPushBack(_) => { + self.type_stack.pop()?; + self.type_stack.pop()?; + let EF::Pop(reference_val) = &self.effects[1] else { + unreachable!(); + }; + let location = reference_val.location()?.clone(); + let runtime_location = RuntimeLocation::as_runtime_location(location.clone()); + let snap = self.resolve_location(&runtime_location, Some(frame), interpreter)?; + let effects = self.register_post_effects(vec![EF::Write(Write { + location, + root_value_after_write: snap, + })]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::VecPopBack(_) => { + let reference_ty = self.type_stack.pop()?; + let MoveTypeLayout::Vector(ty) = reference_ty.layout else { + panic!("Expected vector, got {:?}", reference_ty.layout); + }; + let a_layout = RootedType { + layout: (*ty).clone(), + ref_type: None, + }; + self.type_stack.push(a_layout); + let v = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(v)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::VecUnpack(_, n) => { + let ty = self.type_stack.pop()?; + let MoveTypeLayout::Vector(ty) = ty.layout else { + panic!("Expected vector, got {:?}", ty.layout); + }; + for _ in 0..*n { + let a_layout = RootedType { + layout: (*ty).clone(), + ref_type: None, + }; + self.type_stack.push(a_layout); + } + let mut effects = vec![]; + for i in (0..*n).rev() { + let value = self.resolve_stack_value(Some(frame), interpreter, i as usize)?; + effects.push(EF::Push(value)); + } + let effects = self.register_post_effects(effects); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::VecSwap(_) => { + self.type_stack.pop()?; + self.type_stack.pop()?; + let v_ref = self.type_stack.pop()?; + let location = v_ref.ref_type.as_ref()?.1.clone(); + let snap = self.resolve_location(&location, Some(frame), interpreter)?; + let effects = self.register_post_effects(vec![EF::Write(Write { + location: location.as_trace_location(), + root_value_after_write: snap, + })]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::PackVariant(vidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let (field_count, _variant_tag) = resolver.variant_field_count_and_tag(*vidx); + let stack_len = self.type_stack.len(); + let _ = self.type_stack.split_off(stack_len - field_count as usize); + let ty = loader + .type_to_fully_annotated_layout(&resolver.get_enum_type(*vidx)) + .ok()?; + let a_layout = RootedType { + layout: ty, + ref_type: None, + }; + self.type_stack.push(a_layout); + let val = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(val)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::PackVariantGeneric(vidx) => { + let resolver = frame.function.get_resolver(self.link_context(), loader); + let (field_count, _variant_tag) = + resolver.variant_instantiantiation_field_count_and_tag(*vidx); + let stack_len = self.type_stack.len(); + let _ = self.type_stack.split_off(stack_len - field_count as usize); + let ty = loader + .type_to_fully_annotated_layout( + &resolver.instantiate_enum_type(*vidx, &frame.ty_args).ok()?, + ) + .ok()?; + let a_layout = RootedType { + layout: ty, + ref_type: None, + }; + self.type_stack.push(a_layout); + let val = self.resolve_stack_value(Some(frame), interpreter, 0)?; + let effects = self.register_post_effects(vec![EF::Push(val)]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::UnpackVariant(_) | B::UnpackVariantGeneric(_)) => { + let ty = self.type_stack.pop()?; + let resolver = frame.function.get_resolver(self.link_context(), loader); + let (field_count, tag) = match i { + B::UnpackVariant(vidx) => resolver.variant_field_count_and_tag(*vidx), + B::UnpackVariantGeneric(vidx) => { + resolver.variant_instantiantiation_field_count_and_tag(*vidx) + } + _ => unreachable!(), + }; + let MoveTypeLayout::Enum(e) = ty.layout else { + panic!("Expected enum, got {:#?}", ty.layout); + }; + let variant_layout = e.variants.iter().find(|v| v.0 .1 == tag)?; + let mut effects = vec![]; + for f_layout in variant_layout.1.iter() { + let a_layout = RootedType { + layout: f_layout.layout.clone(), + ref_type: None, + }; + self.type_stack.push(a_layout); + } + for i in 0..field_count { + let value = self.resolve_stack_value(Some(frame), interpreter, i as usize)?; + effects.push(EF::Push(value)); + } + let effects = self.register_post_effects(effects); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + i @ (B::UnpackVariantImmRef(_) + | B::UnpackVariantMutRef(_) + | B::UnpackVariantGenericImmRef(_) + | B::UnpackVariantGenericMutRef(_)) => { + let ty = self.type_stack.pop()?; + let resolver = frame.function.get_resolver(self.link_context(), loader); + let ((field_count, tag), ref_type) = match i { + B::UnpackVariantImmRef(vidx) => { + (resolver.variant_field_count_and_tag(*vidx), RefType::Imm) + } + B::UnpackVariantMutRef(vidx) => { + (resolver.variant_field_count_and_tag(*vidx), RefType::Mut) + } + B::UnpackVariantGenericImmRef(vidx) => ( + resolver.variant_instantiantiation_field_count_and_tag(*vidx), + RefType::Imm, + ), + B::UnpackVariantGenericMutRef(vidx) => ( + resolver.variant_instantiantiation_field_count_and_tag(*vidx), + RefType::Mut, + ), + _ => unreachable!(), + }; + let MoveTypeLayout::Enum(e) = ty.layout else { + panic!("Expected enum, got {:#?}", ty.layout); + }; + let variant_layout = e.variants.iter().find(|v| v.0 .1 == tag)?; + let location = ty.ref_type.as_ref()?.1.clone(); + + let mut effects = vec![]; + for (i, f_layout) in variant_layout.1.iter().enumerate() { + let location = RuntimeLocation::Indexed(Box::new(location.clone()), i); + let a_layout = RootedType { + layout: f_layout.layout.clone(), + ref_type: Some((ref_type.clone(), location)), + }; + self.type_stack.push(a_layout); + } + for i in 0..field_count { + let value = self.resolve_stack_value(Some(frame), interpreter, i as usize)?; + effects.push(EF::Push(value)); + } + let effects = self.register_post_effects(effects); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::VariantSwitch(_) => { + self.type_stack.pop()?; + let effects = self.register_post_effects(vec![]); + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } + B::ExistsDeprecated(_) + | B::ExistsGenericDeprecated(_) + | B::MoveFromDeprecated(_) + | B::MoveFromGenericDeprecated(_) + | B::MoveToDeprecated(_) + | B::MoveToGenericDeprecated(_) + | B::MutBorrowGlobalDeprecated(_) + | B::MutBorrowGlobalGenericDeprecated(_) + | B::ImmBorrowGlobalDeprecated(_) + | B::ImmBorrowGlobalGenericDeprecated(_) => unreachable!(), + } + + // At this point the type stack and the operand stack should be in sync. + assert_eq!(self.type_stack.len(), interpreter.operand_stack.value.len()); + Some(()) + } +} + +/// The (public crate) API for the VM tracer. +impl<'a> VMTracer<'a> { + pub(crate) fn new(trace: &'a mut MoveTraceBuilder) -> Self { + Self { + trace, + link_context: None, + pc: None, + active_frames: BTreeMap::new(), + type_stack: vec![], + loaded_data: BTreeMap::new(), + effects: vec![], + } + } + + pub(crate) fn open_initial_frame( + &mut self, + args: &[Value], + ty_args: &[Type], + function: &Function, + loader: &Loader, + remaining_gas: u64, + link_context: AccountAddress, + ) { + let opt = + self.open_initial_frame_(args, ty_args, function, loader, remaining_gas, link_context); + self.emit_trace_error_if_err(opt.is_none()); + } + + pub(crate) fn close_initial_frame( + &mut self, + return_values: &VMResult>, + remaining_gas: u64, + ) { + let return_values = match return_values { + Ok(values) => values, + Err(err) => { + self.trace + .effect(EF::ExecutionError(format!("{:?}", err.major_status()))); + return; + } + }; + let opt = self.close_initial_frame_(return_values, remaining_gas); + self.emit_trace_error_if_err(opt.is_none()); + } + + pub(crate) fn open_frame( + &mut self, + ty_args: &[Type], + function: &Function, + calling_frame: &Frame, + interpreter: &Interpreter, + loader: &Loader, + remaining_gas: u64, + link_context: AccountAddress, + ) { + let opt = self.open_frame_( + ty_args, + function, + calling_frame, + interpreter, + loader, + remaining_gas, + link_context, + ); + self.emit_trace_error_if_err(opt.is_none()) + } + + pub(crate) fn close_frame( + &mut self, + frame: &Frame, + function: &Function, + interpreter: &Interpreter, + loader: &Loader, + remaining_gas: u64, + link_context: AccountAddress, + err: Option<&VMError>, + ) { + if let Some(err) = err { + self.trace + .effect(EF::ExecutionError(format!("{:?}", err.major_status()))); + return; + } + let opt = self.close_frame_( + frame, + function, + interpreter, + loader, + remaining_gas, + link_context, + ); + self.emit_trace_error_if_err(opt.is_none()) + } + + pub(crate) fn open_instruction( + &mut self, + frame: &Frame, + interpreter: &Interpreter, + loader: &Loader, + remaining_gas: u64, + ) { + let opt = self.open_instruction_(frame, interpreter, loader, remaining_gas); + self.emit_trace_error_if_err(opt.is_none()); + } + + pub(crate) fn close_instruction( + &mut self, + frame: &Frame, + interpreter: &Interpreter, + loader: &Loader, + remaining_gas: u64, + err: Option<&PartialVMError>, + ) { + if self + .close_instruction_(frame, interpreter, loader, remaining_gas) + .is_none() + { + // If we fail to close the instruction, we need to emit an error event. + // This can be the case where the instruction itself failed -- e.g. with a division by + // zero, invalid cast, etc. + let error_string = match err { + Some(err) => format!("{:?}", err.major_status()), + None => "VM tracer failed to close instruction but interpreter was OK -- this is most likely a bug in the tracer".to_string(), + }; + let pc = self + .pc + .expect("PC always set by this point by `open_instruction`"); + let instruction = &frame.function.code()[pc as usize]; + let effects = self.register_post_effects(vec![EF::ExecutionError(error_string)]); + // TODO: type params here? + self.trace + .instruction(instruction, vec![], effects, remaining_gas, pc); + } else if let Some(err) = err { + self.trace + .effect(EF::ExecutionError(format!("{:?}", err.major_status()))); + } + } +} + +impl FunctionTypeInfo { + /// Resolve a function to all of its type information (type arguments, local types, and return + /// types). + fn new( + function: &Function, + loader: &Loader, + ty_args: &[Type], + link_context: AccountAddress, + ) -> Option { + // Split a `Type` into its inner type and reference type. + let deref_ty = |ty: Type| -> (Type, Option) { + match ty { + Type::Reference(r) => (*r, Some(RefType::Imm)), + Type::MutableReference(t) => (*t, Some(RefType::Mut)), + Type::TyParam(_) => unreachable!("Type parameters should be fully substituted"), + _ => (ty, None), + } + }; + + let (module, _) = loader.get_module(link_context, function.module_id()); + let fdef = module.function_def_at(function.index()); + let f_handle = module.function_handle_at(fdef.function); + let get_types_for_sig = |si: SignatureIndex| -> Option> { + let signatures = &module.signature_at(si).0; + signatures + .iter() + .map(|tok| { + let ty = loader.make_type(&module, tok).ok()?; + let subst_ty = loader.subst(&ty, ty_args).ok()?; + let (ty, ref_type) = deref_ty(subst_ty); + let tag = loader.type_to_type_tag(&ty).ok()?; + // NB: This may fail if the type represents a value greater than the max + // value depth. + let type_layout = loader.type_to_fully_annotated_layout(&ty).ok(); + let layout = (type_layout, ref_type); + Some(TagWithLayoutInfoOpt { tag, layout }) + }) + .collect::>>() + }; + let mut local_types = get_types_for_sig(f_handle.parameters)?; + + if let Some(code) = fdef.code.as_ref() { + local_types.extend(get_types_for_sig(code.locals)?); + } + + let return_types = { + let signatures = &module.signature_at(f_handle.return_).0; + signatures + .iter() + .map(|tok| { + let ty = loader.make_type(&module, tok).ok()?; + let subst_ty = loader.subst(&ty, ty_args).ok()?; + let (ty, ref_type) = deref_ty(subst_ty); + let tag = loader.type_to_type_tag(&ty).ok()?; + let type_layout = loader.type_to_fully_annotated_layout(&ty).ok(); + let layout = (type_layout, ref_type); + Some(TagWithLayoutInfoOpt { tag, layout }) + }) + .collect::>>()? + }; + + let ty_args = ty_args + .iter() + .cloned() + .map(|ty| { + let (ty, ref_type) = deref_ty(ty); + assert!(ref_type.is_none()); + loader.type_to_type_tag(&ty).ok() + }) + .collect::>()?; + + Some(FunctionTypeInfo { + ty_args, + local_types, + return_types, + }) + } +} + +/// Get the type layout of a constant. +fn get_constant_type_layout( + function: &Function, + loader: &Loader, + link_context: AccountAddress, + const_idx: ConstantPoolIndex, +) -> Option { + let (module, _loaded_module) = loader.get_module(link_context, function.module_id()); + let constant = module.constant_at(const_idx); + let ty = loader.make_type(&module, &constant.type_).ok()?; + loader.type_to_fully_annotated_layout(&ty).ok() +} diff --git a/external-crates/move/crates/move-vm-test-utils/Cargo.toml b/external-crates/move/crates/move-vm-test-utils/Cargo.toml index a69b5f0f42f..2b92a6a5e7e 100644 --- a/external-crates/move/crates/move-vm-test-utils/Cargo.toml +++ b/external-crates/move/crates/move-vm-test-utils/Cargo.toml @@ -22,4 +22,4 @@ move-vm-types.workspace = true [features] default = [] tiered-gas = [] -gas-profiler = [] +tracing = [] diff --git a/external-crates/move/crates/move-vm-test-utils/src/tiered_gas_schedule.rs b/external-crates/move/crates/move-vm-test-utils/src/tiered_gas_schedule.rs index 900b3af8b3a..c88f1b3b067 100644 --- a/external-crates/move/crates/move-vm-test-utils/src/tiered_gas_schedule.rs +++ b/external-crates/move/crates/move-vm-test-utils/src/tiered_gas_schedule.rs @@ -67,6 +67,8 @@ pub const INSTRUCTION_TIER_DEFAULT: u64 = 1; pub const STACK_HEIGHT_TIER_DEFAULT: u64 = 1; pub const STACK_SIZE_TIER_DEFAULT: u64 = 1; +pub const NATIVE_FUNCTION_THRESHOLD: u64 = 700; + // The cost table holds the tiers and curves for instruction costs. #[derive(Clone, Debug, Serialize, PartialEq, Eq, Deserialize)] pub struct CostTable { @@ -186,6 +188,7 @@ pub struct GasStatus<'a> { instructions_current_tier_mult: u64, profiler: Option, + num_native_calls: u64, } impl<'a> GasStatus<'a> { @@ -217,6 +220,7 @@ impl<'a> GasStatus<'a> { stack_size_next_tier_start, instructions_next_tier_start, profiler: None, + num_native_calls: 0, } } @@ -241,6 +245,7 @@ impl<'a> GasStatus<'a> { stack_size_next_tier_start: None, instructions_next_tier_start: None, profiler: None, + num_native_calls: 0, } } @@ -472,9 +477,16 @@ impl<'b> GasMeter for GasStatus<'b> { // Charge for the stack operations. We don't count this as an "instruction" // since we already accounted for the `Call` instruction in the // `charge_native_function_before_execution` call. - self.charge(0, pushes, 0, size_increase.into(), 0)?; - // Now charge the gas that the native function told us to charge. - self.deduct_gas(amount) + // The amount returned by the native function is viewed as the "virtual" instruction cost + // for the native function, and will be charged and contribute to the overall cost tier of + // the transaction accordingly. + self.num_native_calls = self.num_native_calls.saturating_add(1); + if self.num_native_calls > NATIVE_FUNCTION_THRESHOLD { + self.charge(amount.into(), pushes, 0, size_increase.into(), 0) + } else { + self.charge(0, pushes, 0, size_increase.into(), 0)?; + self.deduct_gas(amount) + } } fn charge_native_function_before_execution( diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/signer_runtime_dummy.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/signer_runtime_dummy.mvir index f4ca4998555..d3793600881 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/signer_runtime_dummy.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/signer_runtime_dummy.mvir @@ -1,5 +1,5 @@ //# run --signers 0x1 -module 0x1.m { +module 0x5.m { entry foo(s: signer) { label b0: @@ -8,7 +8,7 @@ label b0: } //# run --signers 0x1 --args 0 -module 0x2.m { +module 0x6.m { entry foo(s: signer, u: u64) { label b0: @@ -17,7 +17,7 @@ label b0: } //# run --signers 0x1 --args 0 @0x1 -module 0x3.m { +module 0x7.m { entry foo(s: signer, u: u64, b: address) { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_borrow_and_modify.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_borrow_and_modify.mvir index 85033dc4c07..96b245fddef 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_borrow_and_modify.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_borrow_and_modify.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { import 0x1.vector; public new(): vector { @@ -25,8 +25,8 @@ module 0x1.M { } //# publish -module 0x2.test { - import 0x1.M; +module 0x6.test { + import 0x5.M; public test() { let v: vector; label b0: @@ -37,4 +37,4 @@ module 0x2.test { } } -//# run 0x2::test::test +//# run 0x6::test::test diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_pop.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_pop.mvir index 55c59d41756..08feb8f824a 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_pop.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_pop.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { import 0x1.vector; public new(): vector { @@ -25,8 +25,8 @@ module 0x1.M { } //# publish -module 0x2.test { - import 0x1.M; +module 0x6.test { + import 0x5.M; public test() { let v: vector; label b0: @@ -37,4 +37,4 @@ module 0x2.test { } } -//# run 0x2::test::test +//# run 0x6::test::test diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_push.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_push.mvir index de00433effc..eac2be70ec1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_push.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_push.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { import 0x1.vector; public new(): vector { @@ -23,8 +23,8 @@ module 0x1.M { } //# publish -module 0x2.test { - import 0x1.M; +module 0x6.test { + import 0x5.M; public test() { let v: vector; label b0: @@ -35,4 +35,4 @@ module 0x2.test { } } -//# run 0x2::test::test +//# run 0x6::test::test diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_swap.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_swap.mvir index 2532ed5599a..91079e9dc4b 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_swap.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vec_swap.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { import 0x1.vector; public new(): vector { @@ -26,8 +26,8 @@ module 0x1.M { } //# publish -module 0x2.test { - import 0x1.M; +module 0x6.test { + import 0x5.M; public test() { let v: vector; label b0: @@ -38,4 +38,4 @@ module 0x2.test { } } -//# run 0x2::test::test +//# run 0x6::test::test diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_borrow_and_modify_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_borrow_and_modify_ok.mvir index 692081b64bd..29a79e2c8f9 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_borrow_and_modify_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_borrow_and_modify_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { public new(): vector { let v: vector; @@ -23,8 +23,8 @@ module 0x1.M { } //# publish -module 0x2.test { - import 0x1.M; +module 0x6.test { + import 0x5.M; public test() { let v: vector; label b0: @@ -35,4 +35,4 @@ module 0x2.test { } } -//# run 0x2::test::test +//# run 0x6::test::test diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_bound_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_bound_ok.mvir index 9e82c815f19..9f3c5601a6a 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_bound_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_bound_ok.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { let v: vector; @@ -13,7 +13,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { let v: vector; @@ -26,7 +26,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { let v: vector; @@ -40,7 +40,7 @@ label b0: } //# run -module 0x4.m { +module 0x9.m { entry foo() { let v: vector; @@ -53,7 +53,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { let v: vector; @@ -67,7 +67,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_len_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_len_ok.mvir index 578ea3dfe63..dd5442a9548 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_len_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_len_ok.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -12,7 +12,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; @@ -25,7 +25,7 @@ label b0: } //# run -module 0x3.m { +module 0x7.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.exp index 7762627f9d1..451d2e9a19e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.exp @@ -5,7 +5,7 @@ task 0, lines 1-14: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(1), - location: 0x1::m, + location: 0x5::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 7)], } @@ -15,7 +15,7 @@ task 1, lines 15-28: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(1), - location: 0x2::m, + location: 0x6::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 7)], } @@ -25,7 +25,7 @@ task 2, lines 29-41: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(1), - location: 0x3::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 5)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.mvir index 8ee3e8c82c8..d67ae9e94a4 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_out_of_bound.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -13,7 +13,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; @@ -27,7 +27,7 @@ label b0: } //# run -module 0x3.m { +module 0x7.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pack_unpack_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pack_unpack_ok.mvir index c22505d68cf..a1b6643bab6 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pack_unpack_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pack_unpack_ok.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v1: vector; @@ -16,7 +16,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v1: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.exp index c8d9fff04e7..bbb0c744ee8 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.exp @@ -5,7 +5,7 @@ task 0, lines 1-13: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(2), - location: 0x1::m, + location: 0x5::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 3)], } @@ -15,7 +15,7 @@ task 1, lines 14-27: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(2), - location: 0x2::m, + location: 0x6::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 7)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.mvir index 3f85985204f..f109463eb5e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_empty.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -12,7 +12,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_ok.mvir index e3c5ef62fcc..9cfe0f5dd01 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_pop_ok.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -11,8 +11,9 @@ label b0: } } + //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.exp index d3a05993394..75552becc8f 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.exp @@ -5,7 +5,7 @@ task 0, lines 1-13: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(3), - location: 0x1::m, + location: 0x5::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 4)], } @@ -15,7 +15,7 @@ task 1, lines 14-26: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(3), - location: 0x2::m, + location: 0x6::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 5)], } @@ -25,7 +25,7 @@ task 2, lines 27-40: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(3), - location: 0x3::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 7)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.mvir index ea0d0a56b24..e8ec936fd78 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_less.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -12,7 +12,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; @@ -25,7 +25,7 @@ label b0: } //# run -module 0x3.m { +module 0x7.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.exp index 0e73733403b..06dd5011d5f 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.exp @@ -5,7 +5,7 @@ task 0, lines 1-13: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(3), - location: 0x1::m, + location: 0x5::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 3)], } @@ -15,7 +15,7 @@ task 1, lines 14-26: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(3), - location: 0x2::m, + location: 0x6::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 4)], } @@ -25,7 +25,7 @@ task 2, lines 27-40: Error: Function execution failed with VMError: { major_status: VECTOR_OPERATION_ERROR, sub_status: Some(3), - location: 0x3::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 7)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.mvir index 1435bd8a8ce..d407be0d3d6 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_more.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -12,7 +12,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; @@ -25,7 +25,7 @@ label b0: } //# run -module 0x3.m { +module 0x7.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_ok.mvir index a9112e3c85e..317bb3e2194 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/builtins/vector_ops_unpack_ok.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x5.m { entry foo() { let v: vector; @@ -12,7 +12,7 @@ label b0: } //# run -module 0x2.m { +module 0x6.m { entry foo() { let v: vector; @@ -25,7 +25,7 @@ label b0: } //# run -module 0x3.m { +module 0x7.m { entry foo() { let v: vector; @@ -40,7 +40,7 @@ label b0: } //# run -module 0x4.m { +module 0x8.m { entry foo() { let v: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.exp index 2fdf39797a6..9124a5b50c9 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.exp @@ -5,7 +5,7 @@ task 1, lines 10-20: Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(22), - location: 0x1::M, + location: 0x5::M, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.mvir index 014f4d67c67..f723a0f0732 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/commands/abort_in_module.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { public foo() { label b0: abort 22; @@ -9,7 +9,7 @@ module 0x1.M { //# run module 0x42.m { -import 0x1.M; +import 0x5.M; entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.exp index b404d5e0208..ebd37c53c34 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.exp @@ -5,7 +5,7 @@ task 1, lines 19-28: Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), - location: 0x1::M, + location: 0x6::M, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.mvir index 9d65194b567..6052b388365 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/fields_packed_in_order.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct T has drop { b: u64, a: u64 @@ -18,7 +18,7 @@ module 0x1.M { //# run module 0x42.m { -import 0x1.M; +import 0x6.M; entry foo() { let m: M.T; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken.mvir index cd9253e1ffe..705f6f63ca6 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { public t(): u64 { let x: u64; label b0: @@ -14,7 +14,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.mvir index 98c2d044950..5e67212b772 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x6.Test { public t(): u64 { label b0: jump_if_false (true) b2; @@ -12,7 +12,7 @@ module 0x1.Test { //# run module 0x42.m { -import 0x1.Test; +import 0x6.Test; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/address_arg_is_not_signer.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/address_arg_is_not_signer.mvir index 8ab5af8cd12..83e408cfd7d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/address_arg_is_not_signer.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/address_arg_is_not_signer.mvir @@ -1,5 +1,5 @@ //# run --args @0x1 -module 0x1.m { +module 0x5.m { entry foo(s: signer) { label b0: @@ -9,7 +9,7 @@ label b0: }// DEPRECATED signers can now be passed in as addrs //# run --args @0x0 @0x2 -module 0x2.m { +module 0x6.m { entry foo(s: signer, s2: signer) { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/expected_2_signer_args_got_1.move b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/expected_2_signer_args_got_1.move index 32c12bd69ec..d0ccfd8bf9d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/expected_2_signer_args_got_1.move +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/expected_2_signer_args_got_1.move @@ -1,6 +1,6 @@ //# run --signers 0x1 // should fail, missing signer -module 0x42::m { +module 0x47::m { fun main(_s1: signer, _s2: signer) { } } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/mixed_signer_inputs_scripts.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/mixed_signer_inputs_scripts.mvir index a6cb00ffc63..9ff4b7695ec 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/mixed_signer_inputs_scripts.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/mixed_signer_inputs_scripts.mvir @@ -1,5 +1,5 @@ //# run --args @0x1 @0x1 @0x1 -module 0x1.m { +module 0x5.m { // tests various mixed usage of signer in script arguments entry foo(s1: signer, s2: &signer, s3: signer) { @@ -9,7 +9,7 @@ entry foo(s1: signer, s2: &signer, s3: signer) { } //# run --args @0x1 0 @0x1 false @0x1 -module 0x2.m { +module 0x6.m { entry foo(s1: &signer, u: u64, s2: signer, f: bool, s3: &signer) { label l0: @@ -18,7 +18,7 @@ entry foo(s1: &signer, u: u64, s2: signer, f: bool, s3: &signer) { } //# run --args 0 false @0x1 @0x2 @0x3 -module 0x3.m { +module 0x7.m { entry foo(u: u64, f: bool, a: address, s1: signer, s2: &signer) { label l0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/modify_mutable_ref_inputs.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/modify_mutable_ref_inputs.mvir index 7fb30e4fa30..13fb4e1f60e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/modify_mutable_ref_inputs.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/modify_mutable_ref_inputs.mvir @@ -26,7 +26,7 @@ module 0x42.M { } //# run --args 0 1 b"xyz" -module 0x1.m { +module 0x5.m { import 0x42.M; entry foo( u: &mut u64, diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/ref_inputs.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/ref_inputs.mvir index 80d481d2b67..8d0b5d13f8e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/ref_inputs.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/ref_inputs.mvir @@ -27,7 +27,7 @@ module 0x42.M { } //# run --args 0 -module 0x2.m { +module 0x6.m { entry foo(r1: &u64) { label l0: @@ -36,7 +36,7 @@ entry foo(r1: &u64) { } //# run --args false -module 0x3.m { +module 0x7.m { entry foo(r1: &mut bool) { label l0: @@ -45,7 +45,7 @@ entry foo(r1: &mut bool) { } //# run --args 0 false 0 0 -module 0x5.m { +module 0x8.m { import 0x42.M; entry foo(r1: &u64, r2: &mut bool, r3: &M.S, r4: &mut M.S) { label l0: @@ -54,7 +54,7 @@ entry foo(r1: &u64, r2: &mut bool, r3: &M.S, r4: &mut M.S) { } //# run --type-args u64 bool 0x42::M::S 0x42::M::S --args 0 false 0 0 -module 0x6.m { +module 0x9.m { entry foo(r1: &T1, r2: &mut T2, r3: &T3, r4: &mut T4) { label l0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.exp index dd7e266900f..4adf6d72dde 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.exp @@ -1,7 +1,7 @@ processed 2 tasks task 1, lines 6-14: -//# run --type-args 0x1::M::Ex +//# run --type-args 0x5::M::Ex Error: Function execution failed with VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.mvir index ba93f6dd42e..332454bcf03 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_few_type_args_inner.mvir @@ -1,9 +1,9 @@ //# publish -module 0x1.M { +module 0x5.M { struct Ex { flag: bool } } -//# run --type-args 0x1::M::Ex +//# run --type-args 0x5::M::Ex module 0x42.m { entry foo() { // too few type args for inner type diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.exp index 5984802c3ed..303587fef3f 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.exp @@ -1,7 +1,7 @@ processed 2 tasks task 1, lines 6-14: -//# run --type-args 0x1::M::Ex +//# run --type-args 0x5::M::Ex Error: Function execution failed with VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.mvir index e399c873035..138dd43fcab 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_too_many_type_args_inner.mvir @@ -1,9 +1,9 @@ //# publish -module 0x1.M { +module 0x5.M { struct Ex { flag: bool } } -//# run --type-args 0x1::M::Ex +//# run --type-args 0x5::M::Ex module 0x42.m { entry foo() { // too many type args diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.exp index ffe63af7454..d5b446b5c92 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.exp @@ -1,7 +1,7 @@ processed 2 tasks task 1, lines 20-28: -//# run --type-args 0x1::Coin::Coin +//# run --type-args 0x5::Coin::Coin Error: Function execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.mvir index 334277b0f9c..d6cc95f7347 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/script_type_arg_kind_mismatch_1.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Coin { +module 0x5.Coin { struct Coin { value: u64 } public value(c: &Self.Coin): u64 { label b0: @@ -17,7 +17,7 @@ module 0x1.Coin { } } -//# run --type-args 0x1::Coin::Coin +//# run --type-args 0x5::Coin::Coin module 0x42.m { entry foo() { // coin does not have copy or drop diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/struct_arguments.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/struct_arguments.mvir index dba8e75bc13..c05c46dded8 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/struct_arguments.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/entry_points/struct_arguments.mvir @@ -17,7 +17,7 @@ module 0x42.M { } //# run --args 0 0 0 -module 0x1.m { +module 0x5.m { import 0x42.M; entry foo(s: M.S, i: &M.S, m: &mut M.S) { label l0: @@ -26,7 +26,7 @@ entry foo(s: M.S, i: &M.S, m: &mut M.S) { } //# run --type-args 0x42::M::S --args 0 0 0 -module 0x2.m { +module 0x6.m { entry foo(s: T, i: &T, m: &mut T) { label l0: return; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.exp index efd9aedd8ab..0f490e25719 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.exp @@ -3,8 +3,7 @@ processed 2 tasks task 0, lines 1-24: //# print-bytecode // Move bytecode v7 -module 1.MonomorphicEnums { - +module 6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, @@ -35,14 +34,16 @@ Jump tables: Variant1 => jump 9 } } + } + task 1, lines 26-49: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonomorphicEnums'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::MonomorphicEnums'. Got VMError: { major_status: PACK_TYPE_MISMATCH_ERROR, sub_status: None, - location: 0x1::MonomorphicEnums, + location: 0x6::MonomorphicEnums, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 1)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.mvir index efef81018cc..df6e0a0e20a 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: u64 } @@ -24,7 +24,7 @@ module 0x1.MonomorphicEnums { } //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: u64 } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.exp index 1130075ce55..97bcd9bdf5e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.exp @@ -3,8 +3,7 @@ processed 5 tasks task 0, lines 1-43: //# print-bytecode // Move bytecode v7 -module 1.Enums { - +module 6.Enums { enum EnumWithThreeVariants { One { }, @@ -20,8 +19,8 @@ B0: 3: MoveLoc[1](loc0: EnumWithThreeVariants) 4: Call f(EnumWithThreeVariants): Ty0 5: Ret - } + public call_fail_1(): Ty0 { L0: loc0: EnumWithThreeVariants B0: @@ -30,8 +29,8 @@ B0: 2: MoveLoc[0](loc0: EnumWithThreeVariants) 3: Call f(EnumWithThreeVariants): Ty0 4: Ret - } + public call_fail_3(): Ty0 { L0: loc0: EnumWithThreeVariants B0: @@ -40,8 +39,8 @@ B0: 2: MoveLoc[0](loc0: EnumWithThreeVariants) 3: Call f(EnumWithThreeVariants): Ty0 4: Ret - } + f(Arg0: EnumWithThreeVariants): Ty0 { B0: 0: ImmBorrowLoc[0](Arg0: EnumWithThreeVariants) @@ -59,24 +58,26 @@ Jump tables: Variant2 => jump 2 } } + } + task 3, line 101: -//# run 0x1::Enums::call_fail_1 --type-args u64 +//# run 0x6::Enums::call_fail_1 --type-args u64 Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(3), 3)], } task 4, line 103: -//# run 0x1::Enums::call_fail_3 --type-args u64 +//# run 0x6::Enums::call_fail_3 --type-args u64 Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(3), 3)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.mvir index 72dbbebe699..b008635ea5e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_jump_same_label.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.Enums { +module 0x6.Enums { enum EnumWithThreeVariants { One { }, Two { x: T }, @@ -43,7 +43,7 @@ module 0x1.Enums { } //# publish -module 0x1.Enums { +module 0x6.Enums { enum EnumWithThreeVariants { One { }, Two { x: T }, @@ -87,8 +87,8 @@ module 0x1.Enums { } //# run -module 0x2.m { -import 0x1.Enums; +module 0x7.m { +import 0x6.Enums; entry foo() { let x: u64; label b0: @@ -98,6 +98,6 @@ entry foo() { } } -//# run 0x1::Enums::call_fail_1 --type-args u64 +//# run 0x6::Enums::call_fail_1 --type-args u64 -//# run 0x1::Enums::call_fail_3 --type-args u64 +//# run 0x6::Enums::call_fail_3 --type-args u64 diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.exp index 5da6e6f7992..3af693d17be 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 1-24: //# print-bytecode // Move bytecode v7 -module 1.MonomorphicEnums { - +module 6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, @@ -35,14 +34,16 @@ Jump tables: Variant1 => jump 5 } } + } + task 2, lines 51-61: //# run Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::MonomorphicEnums, + location: 0x6::MonomorphicEnums, indices: [], offsets: [(FunctionDefinitionIndex(0), 6)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.mvir index e5d310bd026..fb2be7f9c90 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: T } @@ -24,7 +24,7 @@ module 0x1.MonomorphicEnums { } //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: T } @@ -49,8 +49,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x7.m { +import 0x6.MonomorphicEnums; entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.exp index 711880ea712..3464c885b9d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.exp @@ -1,121 +1,121 @@ processed 14 tasks task 2, line 222: -//# run 0x1::Enums::poly_invalid1_mut_ref +//# run 0x6::Enums::poly_invalid1_mut_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(4), 1)], } task 3, line 224: -//# run 0x1::Enums::poly_invalid1_imm_ref +//# run 0x6::Enums::poly_invalid1_imm_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(5), 1)], } task 4, line 226: -//# run 0x1::Enums::poly_invalid1 +//# run 0x6::Enums::poly_invalid1 Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(3), 1)], } task 5, line 228: -//# run 0x1::Enums::poly_invalid2_mut_ref +//# run 0x6::Enums::poly_invalid2_mut_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } task 6, line 230: -//# run 0x1::Enums::poly_invalid2_imm_ref +//# run 0x6::Enums::poly_invalid2_imm_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(2), 1)], } task 7, line 232: -//# run 0x1::Enums::poly_invalid2 +//# run 0x6::Enums::poly_invalid2 Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } task 8, line 234: -//# run 0x1::Enums::mono_invalid1_mut_ref +//# run 0x6::Enums::mono_invalid1_mut_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(10), 1)], } task 9, line 236: -//# run 0x1::Enums::mono_invalid1_imm_ref +//# run 0x6::Enums::mono_invalid1_imm_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(11), 1)], } task 10, line 238: -//# run 0x1::Enums::mono_invalid1 +//# run 0x6::Enums::mono_invalid1 Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(9), 1)], } task 11, line 240: -//# run 0x1::Enums::mono_invalid2_mut_ref +//# run 0x6::Enums::mono_invalid2_mut_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(7), 1)], } task 12, line 242: -//# run 0x1::Enums::mono_invalid2_imm_ref +//# run 0x6::Enums::mono_invalid2_imm_ref Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(8), 1)], } task 13, line 244: -//# run 0x1::Enums::mono_invalid2 +//# run 0x6::Enums::mono_invalid2 Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::Enums, + location: 0x6::Enums, indices: [], offsets: [(FunctionDefinitionIndex(6), 1)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.mvir index 4ea010e4a20..77c51f044ba 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_tag_unpack_invalid.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Enums { +module 0x6.Enums { enum PolyEnum { One { }, Two { x: T }, @@ -217,28 +217,28 @@ module 0x1.Enums { } } -//# run 0x1::Enums::all_valid +//# run 0x6::Enums::all_valid -//# run 0x1::Enums::poly_invalid1_mut_ref +//# run 0x6::Enums::poly_invalid1_mut_ref -//# run 0x1::Enums::poly_invalid1_imm_ref +//# run 0x6::Enums::poly_invalid1_imm_ref -//# run 0x1::Enums::poly_invalid1 +//# run 0x6::Enums::poly_invalid1 -//# run 0x1::Enums::poly_invalid2_mut_ref +//# run 0x6::Enums::poly_invalid2_mut_ref -//# run 0x1::Enums::poly_invalid2_imm_ref +//# run 0x6::Enums::poly_invalid2_imm_ref -//# run 0x1::Enums::poly_invalid2 +//# run 0x6::Enums::poly_invalid2 -//# run 0x1::Enums::mono_invalid1_mut_ref +//# run 0x6::Enums::mono_invalid1_mut_ref -//# run 0x1::Enums::mono_invalid1_imm_ref +//# run 0x6::Enums::mono_invalid1_imm_ref -//# run 0x1::Enums::mono_invalid1 +//# run 0x6::Enums::mono_invalid1 -//# run 0x1::Enums::mono_invalid2_mut_ref +//# run 0x6::Enums::mono_invalid2_mut_ref -//# run 0x1::Enums::mono_invalid2_imm_ref +//# run 0x6::Enums::mono_invalid2_imm_ref -//# run 0x1::Enums::mono_invalid2 +//# run 0x6::Enums::mono_invalid2 diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.exp index a5d7e0983a3..4bb5bddfb28 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.exp @@ -3,16 +3,17 @@ processed 3 tasks task 0, lines 1-33: //# print-bytecode // Move bytecode v7 -module 1.MonomorphicEnums { - +module 6.MonomorphicEnums { enum EnumWithOneVariant { One { } } + enum EnumWithTwoVariants { One { }, Two { x: u64 } } + enum EnumWithTwoVariantsPlusAbilities has copy, drop, store, key { One { }, Two { x: u64 } @@ -44,4 +45,6 @@ Jump tables: Variant1 => jump 9 } } + } + diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.mvir index 5aaee4a507c..5177598f377 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithOneVariant { One { } } @@ -33,7 +33,7 @@ module 0x1.MonomorphicEnums { } //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithOneVariant { One { } } @@ -67,8 +67,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x7.m { +import 0x6.MonomorphicEnums; entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.exp index a81fde32caf..548a1975c6f 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.exp @@ -2,14 +2,14 @@ processed 2 tasks task 0, lines 1-23: //# publish -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonomorphicEnums'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000006::MonomorphicEnums'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, - location: 0x1::MonomorphicEnums, + location: 0x6::MonomorphicEnums, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 6)], } task 1, lines 25-35: //# run -Error: Dependency not provided for 0000000000000000000000000000000000000000000000000000000000000001.MonomorphicEnums +Error: Dependency not provided for 0000000000000000000000000000000000000000000000000000000000000006.MonomorphicEnums diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.mvir index 5121fd928a1..1ccda56650e 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: u64 } @@ -23,8 +23,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x7.m { +import 0x6.MonomorphicEnums; entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.exp index 424c48fe430..bca76469d3c 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.exp @@ -5,7 +5,7 @@ task 1, lines 26-36: Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::MonomorphicEnums, + location: 0x6::MonomorphicEnums, indices: [], offsets: [(FunctionDefinitionIndex(0), 11)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.mvir index 66c89f2c445..8ae734c21a1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: u64 } @@ -24,8 +24,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x7.m { +import 0x6.MonomorphicEnums; entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.exp index 88a0cd62b78..8ce670efc72 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 3-50: //# print-bytecode // Move bytecode v7 -module 1.MonomorphicEnums { - +module 6.MonomorphicEnums { enum EnumWithTwoVariants has drop { One { x: u64 }, @@ -19,8 +18,8 @@ B0: 3: MoveLoc[1](loc0: u64) 4: PackVariant(VariantHandleIndex(0)) 5: Ret - } + public mutate(Arg0: &mut EnumWithTwoVariants, Arg1: u64) { B0: 0: CopyLoc[0](Arg0: &mut EnumWithTwoVariants) @@ -49,6 +48,7 @@ Jump tables: Variant1 => jump 10 } } + public get(Arg0: &EnumWithTwoVariants): &u64 { L0: loc1: &u64 B0: @@ -73,4 +73,6 @@ Jump tables: Variant1 => jump 7 } } + } + diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.mvir index 5adacaa2797..7dd87477d2b 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.mvir @@ -1,7 +1,7 @@ // Tests that mutable borrows from enum variants work correctly. //# print-bytecode -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants has drop { One { x: u64 }, Two { x: u64, y: u64 } @@ -50,7 +50,7 @@ module 0x1.MonomorphicEnums { } //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants has drop { One { x: u64 }, Two { x: u64, y: u64 } @@ -99,8 +99,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x7.m { +import 0x6.MonomorphicEnums; entry foo() { let x: MonomorphicEnums.EnumWithTwoVariants; let y: &u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.exp index 7350d286796..034f0259275 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 3-34: //# print-bytecode // Move bytecode v7 -module 1.MonomorphicEnums { - +module 6.MonomorphicEnums { enum EnumWithTwoVariants has drop { One { x: u64 }, @@ -16,8 +15,8 @@ B0: 0: MoveLoc[0](Arg0: u64) 1: PackVariant(VariantHandleIndex(0)) 2: Ret - } + public mutate(Arg0: &mut EnumWithTwoVariants, Arg1: u64, Arg2: u64) { B0: 0: MoveLoc[1](Arg1: u64) @@ -26,8 +25,8 @@ B0: 3: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) 4: WriteRef 5: Ret - } + public is_variant_two(Arg0: &EnumWithTwoVariants): bool { L0: loc1: &u64 B0: @@ -45,4 +44,6 @@ Jump tables: Variant1 => jump 4 } } + } + diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.mvir index 8364394dee8..2ab13c6ea16 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.mvir @@ -1,7 +1,7 @@ // Tests that if taking a mutable enum that the variant inside cane be mutated. //# print-bytecode -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants has drop { One { x: u64 }, Two { x: u64, y: u64 } @@ -34,7 +34,7 @@ module 0x1.MonomorphicEnums { } //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants has drop { One { x: u64 }, Two { x: u64, y: u64 } @@ -67,8 +67,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x8.m { +import 0x6.MonomorphicEnums; entry foo() { let x: MonomorphicEnums.EnumWithTwoVariants; let y: bool; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.exp index a8432bc48ba..0688d0533ae 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 1-24: //# print-bytecode // Move bytecode v7 -module 1.MonomorphicEnums { - +module 6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, @@ -36,4 +35,6 @@ Jump tables: Variant1 => jump 9 } } + } + diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.mvir index 843c3296f08..d80e2e0a196 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: T } @@ -24,7 +24,7 @@ module 0x1.MonomorphicEnums { } //# publish -module 0x1.MonomorphicEnums { +module 0x6.MonomorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: T } @@ -49,8 +49,8 @@ module 0x1.MonomorphicEnums { } //# run -module 0x2.m { -import 0x1.MonomorphicEnums; +module 0x7.m { +import 0x6.MonomorphicEnums; entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.exp index dff9569efa6..9c37f257b20 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.exp @@ -5,7 +5,7 @@ task 1, lines 26-36: Error: Function execution failed with VMError: { major_status: VARIANT_TAG_MISMATCH, sub_status: None, - location: 0x1::PolymorphicEnums, + location: 0x6::PolymorphicEnums, indices: [], offsets: [(FunctionDefinitionIndex(0), 11)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.mvir index 0a10ebb63b4..ef8fdca745f 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.PolymorphicEnums { +module 0x6.PolymorphicEnums { enum EnumWithTwoVariants { One { }, Two { x: T } @@ -24,8 +24,8 @@ module 0x1.PolymorphicEnums { } //# run -module 0x2.m { - import 0x1.PolymorphicEnums; +module 0x7.m { + import 0x6.PolymorphicEnums; entry foo() { let x: u64; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.exp index 1609996dfc5..c4f27e66713 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 3-50: //# print-bytecode // Move bytecode v7 -module 1.PolymorphicEnums { - +module 6.PolymorphicEnums { enum EnumWithTwoVariants has drop { One { x: Ty0 }, @@ -19,8 +18,8 @@ B0: 3: MoveLoc[1](loc0: u64) 4: PackVariantGeneric(VariantInstantiationHandleIndex(0)) 5: Ret - } + public mutate(Arg0: &mut EnumWithTwoVariants, Arg1: Ty0) { B0: 0: CopyLoc[0](Arg0: &mut EnumWithTwoVariants) @@ -49,6 +48,7 @@ Jump tables: Variant1 => jump 10 } } + public get(Arg0: &EnumWithTwoVariants): &Ty0 { L0: loc1: &u64 B0: @@ -73,4 +73,6 @@ Jump tables: Variant1 => jump 7 } } + } + diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.mvir index d33b90f9b86..0b247dcc5da 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.mvir @@ -1,7 +1,7 @@ // Tests that mutable borrows from enum variants work correctly. //# print-bytecode -module 0x1.PolymorphicEnums { +module 0x6.PolymorphicEnums { enum EnumWithTwoVariants has drop { One { x: T }, Two { x: T, y: u64 } @@ -50,7 +50,7 @@ module 0x1.PolymorphicEnums { } //# publish -module 0x1.PolymorphicEnums { +module 0x6.PolymorphicEnums { enum EnumWithTwoVariants has drop { One { x: T }, Two { x: T, y: u64 } @@ -99,8 +99,8 @@ module 0x1.PolymorphicEnums { } //# run -module 0x2.m { -import 0x1.PolymorphicEnums; +module 0x7.m { +import 0x6.PolymorphicEnums; entry foo() { let x: PolymorphicEnums.EnumWithTwoVariants; let y: &u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.exp index 973254dceca..08e6081ba33 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 3-34: //# print-bytecode // Move bytecode v7 -module 1.PolymorphicEnums { - +module 6.PolymorphicEnums { enum EnumWithTwoVariants has drop { One { x: Ty0 }, @@ -16,8 +15,8 @@ B0: 0: MoveLoc[0](Arg0: u64) 1: PackVariantGeneric(VariantInstantiationHandleIndex(0)) 2: Ret - } + public mutate(Arg0: &mut EnumWithTwoVariants, Arg1: u64, Arg2: u64) { B0: 0: MoveLoc[1](Arg1: u64) @@ -26,8 +25,8 @@ B0: 3: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) 4: WriteRef 5: Ret - } + public is_variant_two(Arg0: &EnumWithTwoVariants): bool { L0: loc1: &u64 B0: @@ -45,4 +44,6 @@ Jump tables: Variant1 => jump 4 } } + } + diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.mvir index 60c48171b0f..9e65f366234 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.mvir @@ -1,7 +1,7 @@ // Tests that if taking a mutable enum that the variant inside cane be mutated. //# print-bytecode -module 0x1.PolymorphicEnums { +module 0x6.PolymorphicEnums { enum EnumWithTwoVariants has drop { One { x: T }, Two { x: T, y: T } @@ -34,7 +34,7 @@ module 0x1.PolymorphicEnums { } //# publish -module 0x1.PolymorphicEnums { +module 0x6.PolymorphicEnums { enum EnumWithTwoVariants has drop { One { x: T }, Two { x: T, y: T } @@ -67,8 +67,8 @@ module 0x1.PolymorphicEnums { } //# run -module 0x2.m { -import 0x1.PolymorphicEnums; +module 0x7.m { +import 0x6.PolymorphicEnums; entry foo() { let x: PolymorphicEnums.EnumWithTwoVariants; let y: bool; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/unpack_mut_ref_alias.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/unpack_mut_ref_alias.mvir index a7f3191d0e6..9abe27d3a21 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/unpack_mut_ref_alias.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/unpack_mut_ref_alias.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.o { +module 0x6.o { enum X has drop { One { x: u64, y: u64 }, Two { x: u64, y: u64}, @@ -60,6 +60,6 @@ module 0x1.o { } -//# run 0x1::o::test1 +//# run 0x6::o::test1 -//# run 0x1::o::test2 +//# run 0x6::o::test2 diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.exp index fb83a96e61d..b690af1c0b2 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.exp @@ -3,8 +3,7 @@ processed 3 tasks task 0, lines 1-22: //# print-bytecode // Move bytecode v7 -module 1.InfiniteSwith { - +module 6.InfiniteSwith { enum EnumWithOneVariant { One { } @@ -21,6 +20,7 @@ Jump tables: Variant0 => jump 0 } } + public start(): EnumWithOneVariant { L0: loc0: EnumWithOneVariant B0: @@ -28,16 +28,17 @@ B0: 1: StLoc[0](loc0: EnumWithOneVariant) 2: MoveLoc[0](loc0: EnumWithOneVariant) 3: Ret - } + } + task 2, lines 48-58: //# run --gas-budget 10000 Error: Function execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, - location: 0x1::InfiniteSwith, + location: 0x6::InfiniteSwith, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.mvir index 07ab9642c5d..8ceeb01b02d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.mvir @@ -1,5 +1,5 @@ //# print-bytecode -module 0x1.InfiniteSwith { +module 0x6.InfiniteSwith { enum EnumWithOneVariant { One { } } @@ -22,7 +22,7 @@ module 0x1.InfiniteSwith { } //# publish -module 0x1.InfiniteSwith { +module 0x6.InfiniteSwith { enum EnumWithOneVariant { One { } } @@ -46,8 +46,8 @@ module 0x1.InfiniteSwith { //# run --gas-budget 10000 -module 0x2.m { -import 0x1.InfiniteSwith; +module 0x7.m { +import 0x6.InfiniteSwith; entry foo() { let x: InfiniteSwith.EnumWithOneVariant; label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.exp index 836503a7365..4d9e42e5846 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.exp @@ -5,7 +5,7 @@ task 1, lines 20-29: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 30-39: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 60-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -35,7 +35,7 @@ task 5, lines 70-79: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x42::m, + location: 0x47::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 99-108: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 8, lines 109-118: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 10, lines 139-148: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 11, lines 149-158: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 12, lines 161-170: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 14, lines 190-199: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 15, lines 200-209: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -115,7 +115,7 @@ task 16, lines 210-219: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.mvir index 6fc272a3533..dd64baabfb1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u128.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -18,7 +18,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -28,7 +28,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -40,7 +40,7 @@ label b0: //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -58,7 +58,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -68,7 +68,7 @@ label b0: } //# run -module 0x42.m { +module 0x47.m { entry foo() { label b0: @@ -80,7 +80,7 @@ label b0: //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -97,7 +97,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -107,7 +107,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -119,7 +119,7 @@ label b0: //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -137,7 +137,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -147,7 +147,7 @@ label b0: } //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -159,7 +159,7 @@ label b0: //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -170,7 +170,7 @@ label b0: } //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -188,7 +188,7 @@ label b0: } //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -198,7 +198,7 @@ label b0: } //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -208,7 +208,7 @@ label b0: } //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.exp index 8845a3099df..e7087cab6e3 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.exp @@ -5,7 +5,7 @@ task 1, lines 20-29: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 30-39: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 60-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 98-107: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 8, lines 108-117: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 10, lines 138-147: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 11, lines 148-157: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 12, lines 158-167: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 14, lines 187-196: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 15, lines 197-206: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -115,7 +115,7 @@ task 16, lines 207-216: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.mvir index d84cdb4aa92..aa1619b31cb 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u16.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -18,7 +18,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -28,7 +28,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -40,7 +40,7 @@ label b0: //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -58,7 +58,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -79,7 +79,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -96,7 +96,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -106,7 +106,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -118,7 +118,7 @@ label b0: //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -136,7 +136,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -146,7 +146,7 @@ label b0: } //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -156,7 +156,7 @@ label b0: } //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -167,7 +167,7 @@ label b0: } //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -185,7 +185,7 @@ label b0: } //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -195,7 +195,7 @@ label b0: } //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -205,7 +205,7 @@ label b0: } //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.exp index 836503a7365..6bdad25cbce 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.exp @@ -5,7 +5,7 @@ task 1, lines 20-29: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 30-39: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 60-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 99-108: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 8, lines 109-118: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 10, lines 139-148: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 11, lines 149-158: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 12, lines 161-170: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 14, lines 190-199: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 15, lines 200-209: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -115,7 +115,7 @@ task 16, lines 210-219: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.mvir index b555ef55084..777fe8456e1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u256.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -18,7 +18,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -28,7 +28,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -40,7 +40,7 @@ label b0: //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -58,7 +58,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -80,7 +80,7 @@ label b0: //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -97,7 +97,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -107,7 +107,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -119,7 +119,7 @@ label b0: //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -137,7 +137,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -147,7 +147,7 @@ label b0: } //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -159,7 +159,7 @@ label b0: //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -170,7 +170,7 @@ label b0: } //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -188,7 +188,7 @@ label b0: } //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -198,7 +198,7 @@ label b0: } //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -208,7 +208,7 @@ label b0: } //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.exp index 8845a3099df..e7087cab6e3 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.exp @@ -5,7 +5,7 @@ task 1, lines 20-29: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 30-39: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 60-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 98-107: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 8, lines 108-117: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 10, lines 138-147: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 11, lines 148-157: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 12, lines 158-167: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 14, lines 187-196: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 15, lines 197-206: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -115,7 +115,7 @@ task 16, lines 207-216: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.mvir index 0c3aace54b0..84c840bfe12 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u32.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -18,7 +18,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -28,7 +28,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -40,7 +40,7 @@ label b0: //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -58,7 +58,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -79,7 +79,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -96,7 +96,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -106,7 +106,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -118,7 +118,7 @@ label b0: //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -136,7 +136,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -146,7 +146,7 @@ label b0: } //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -156,7 +156,7 @@ label b0: } //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -167,7 +167,7 @@ label b0: } //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -185,7 +185,7 @@ label b0: } //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -195,7 +195,7 @@ label b0: } //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -205,7 +205,7 @@ label b0: } //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.exp index 8845a3099df..e7087cab6e3 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.exp @@ -5,7 +5,7 @@ task 1, lines 20-29: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 30-39: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 60-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 98-107: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 8, lines 108-117: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 10, lines 138-147: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 11, lines 148-157: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 12, lines 158-167: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 14, lines 187-196: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 15, lines 197-206: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -115,7 +115,7 @@ task 16, lines 207-216: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.mvir index 3d6dcfa32ad..a3899be8c6a 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u64.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -18,7 +18,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -28,7 +28,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -40,7 +40,7 @@ label b0: //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -58,7 +58,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -79,7 +79,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -96,7 +96,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -106,7 +106,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -118,7 +118,7 @@ label b0: //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -136,7 +136,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -146,7 +146,7 @@ label b0: } //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -156,7 +156,7 @@ label b0: } //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -167,7 +167,7 @@ label b0: } //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -185,7 +185,7 @@ label b0: } //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -195,7 +195,7 @@ label b0: } //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -205,7 +205,7 @@ label b0: } //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.exp index c54c3461396..37c2089c9af 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.exp @@ -5,7 +5,7 @@ task 1, lines 20-29: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 2, lines 30-39: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 4, lines 60-69: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 7, lines 98-107: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 8, lines 108-117: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 10, lines 138-147: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 11, lines 148-157: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 12, lines 158-167: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 14, lines 188-197: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -105,7 +105,7 @@ task 15, lines 198-207: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -115,7 +115,7 @@ task 16, lines 208-217: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.mvir index 0111987aa11..afb19cb5525 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/arithmetic_operators_u8.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -18,7 +18,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -28,7 +28,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -40,7 +40,7 @@ label b0: //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -58,7 +58,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -79,7 +79,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -96,7 +96,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -106,7 +106,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -118,7 +118,7 @@ label b0: //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -136,7 +136,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -146,7 +146,7 @@ label b0: } //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -156,7 +156,7 @@ label b0: } //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -168,7 +168,7 @@ label b0: //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -186,7 +186,7 @@ label b0: } //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -196,7 +196,7 @@ label b0: } //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -206,7 +206,7 @@ label b0: } //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.exp index 1dd4bd705ba..b6c034d0be1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.exp @@ -2,10 +2,10 @@ processed 2 tasks task 1, lines 27-49: //# run -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, - location: 0x42::m, + location: 0x43::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 19)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.mvir index 5f12d7f9c07..4901f6c288f 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/assign_struct_field.mvir @@ -25,7 +25,7 @@ module 0x42.Tester { } //# run -module 0x42.m { +module 0x43.m { import 0x42.Tester; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/bitwise_operators.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/bitwise_operators.mvir index bfa04d89657..e0139eebde3 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/bitwise_operators.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/bitwise_operators.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -106,7 +106,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.exp index 1dff1e7d822..48b640809eb 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.exp @@ -5,7 +5,7 @@ task 6, lines 193-202: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -15,7 +15,7 @@ task 7, lines 204-213: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -25,7 +25,7 @@ task 8, lines 215-224: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x9::m, + location: 0xe::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -35,7 +35,7 @@ task 9, lines 226-235: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -45,7 +45,7 @@ task 10, lines 237-246: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x11::m, + location: 0x16::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -55,7 +55,7 @@ task 11, lines 248-257: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x12::m, + location: 0x17::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -65,7 +65,7 @@ task 12, lines 259-268: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x13::m, + location: 0x18::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -75,7 +75,7 @@ task 13, lines 270-279: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x14::m, + location: 0x19::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -85,7 +85,7 @@ task 14, lines 281-290: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x15::m, + location: 0x1a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -95,7 +95,7 @@ task 15, lines 292-301: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x16::m, + location: 0x1b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -105,7 +105,7 @@ task 16, lines 303-312: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x17::m, + location: 0x1c::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -115,7 +115,7 @@ task 17, lines 314-325: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x18::m, + location: 0x1d::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -125,7 +125,7 @@ task 18, lines 326-335: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x19::m, + location: 0x1e::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -135,7 +135,7 @@ task 19, lines 337-346: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x20::m, + location: 0x25::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -145,7 +145,7 @@ task 20, lines 348-357: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x21::m, + location: 0x26::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -155,7 +155,7 @@ task 21, lines 359-368: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x22::m, + location: 0x27::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -165,7 +165,7 @@ task 22, lines 370-379: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x23::m, + location: 0x28::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -175,7 +175,7 @@ task 23, lines 381-392: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x24::m, + location: 0x29::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -185,7 +185,7 @@ task 24, lines 393-402: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x25::m, + location: 0x2a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -195,7 +195,7 @@ task 25, lines 404-413: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x26::m, + location: 0x2b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -205,7 +205,7 @@ task 26, lines 415-424: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x27::m, + location: 0x2c::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -215,7 +215,7 @@ task 27, lines 426-435: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x28::m, + location: 0x2d::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -225,7 +225,7 @@ task 28, lines 437-446: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x29::m, + location: 0x2e::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -235,7 +235,7 @@ task 29, lines 448-457: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x30::m, + location: 0x35::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -245,7 +245,7 @@ task 30, lines 459-468: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x31::m, + location: 0x36::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -255,7 +255,7 @@ task 31, lines 470-481: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x32::m, + location: 0x37::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -265,7 +265,7 @@ task 32, lines 482-491: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x33::m, + location: 0x38::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -275,7 +275,7 @@ task 33, lines 493-502: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x34::m, + location: 0x39::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -285,7 +285,7 @@ task 34, lines 504-513: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x35::m, + location: 0x3a::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -295,7 +295,7 @@ task 35, lines 515-524: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x36::m, + location: 0x3b::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -305,7 +305,7 @@ task 36, lines 526-535: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x37::m, + location: 0x3c::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } @@ -315,7 +315,7 @@ task 37, lines 537-546: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x38::m, + location: 0x3d::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.mvir index dfa2dab4240..00645aa26fd 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/casting_operators.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { // Casting to u8. entry foo() { @@ -35,7 +35,7 @@ label b0: // Casting to u16. //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -70,7 +70,7 @@ label b0: // Casting to u32. //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -105,7 +105,7 @@ label b0: // Casting to u64. //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -130,7 +130,7 @@ label b0: // Casting to u128. //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -156,7 +156,7 @@ label b0: // Casting to u256. //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -191,7 +191,7 @@ label b0: // Casting to u8, overflowing. //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -202,7 +202,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -213,7 +213,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -224,7 +224,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -235,7 +235,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -246,7 +246,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -257,7 +257,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -268,7 +268,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -279,7 +279,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -290,7 +290,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: @@ -301,7 +301,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x17.m { +module 0x1c.m { entry foo() { label b0: @@ -312,7 +312,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x18.m { +module 0x1d.m { entry foo() { label b0: @@ -324,7 +324,7 @@ label b0: // Casting to u64, overflowing. //# run -module 0x19.m { +module 0x1e.m { entry foo() { label b0: @@ -335,7 +335,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x20.m { +module 0x25.m { entry foo() { label b0: @@ -346,7 +346,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x21.m { +module 0x26.m { entry foo() { label b0: @@ -357,7 +357,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x22.m { +module 0x27.m { entry foo() { label b0: @@ -368,7 +368,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x23.m { +module 0x28.m { entry foo() { label b0: @@ -379,7 +379,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x24.m { +module 0x29.m { entry foo() { label b0: @@ -391,7 +391,7 @@ label b0: // Casting to u16, overflowing. //# run -module 0x25.m { +module 0x2a.m { entry foo() { label b0: @@ -402,7 +402,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x26.m { +module 0x2b.m { entry foo() { label b0: @@ -413,7 +413,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x27.m { +module 0x2c.m { entry foo() { label b0: @@ -424,7 +424,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x28.m { +module 0x2d.m { entry foo() { label b0: @@ -435,7 +435,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x29.m { +module 0x2e.m { entry foo() { label b0: @@ -446,7 +446,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x30.m { +module 0x35.m { entry foo() { label b0: @@ -457,7 +457,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x31.m { +module 0x36.m { entry foo() { label b0: @@ -468,7 +468,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x32.m { +module 0x37.m { entry foo() { label b0: @@ -480,7 +480,7 @@ label b0: // Casting to u32, overflowing. //# run -module 0x33.m { +module 0x38.m { entry foo() { label b0: @@ -491,7 +491,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x34.m { +module 0x39.m { entry foo() { label b0: @@ -502,7 +502,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x35.m { +module 0x3a.m { entry foo() { label b0: @@ -513,7 +513,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x36.m { +module 0x3b.m { entry foo() { label b0: @@ -524,7 +524,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x37.m { +module 0x3c.m { entry foo() { label b0: @@ -535,7 +535,7 @@ label b0: }// check: ARITHMETIC_ERROR //# run -module 0x38.m { +module 0x3d.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/comparison_operators.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/comparison_operators.mvir index 6a296632c7f..bd42710996b 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/comparison_operators.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/comparison_operators.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { label b0: @@ -19,7 +19,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -39,7 +39,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -59,7 +59,7 @@ label b0: } //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -79,7 +79,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -99,7 +99,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value.mvir index a0836820812..2018ecee9f7 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { struct T has drop {f: u64} public new(f: u64): Self.T { @@ -21,7 +21,7 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; +import 0x6.A; entry foo() { let x: A.T; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value_nested.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value_nested.mvir index f2fdef33fb5..eb86bc680a1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value_nested.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/deref_value_nested.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.B { +module 0x6.B { struct T has drop {g: u64} public new(g: u64): Self.T { @@ -19,8 +19,8 @@ module 0x1.B { } //# publish -module 0x1.A { - import 0x1.B; +module 0x7.A { + import 0x6.B; struct T has drop {f: B.T} @@ -40,8 +40,8 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; -import 0x1.B; +import 0x7.A; +import 0x6.B; entry foo() { let b: B.T; let x: A.T; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.exp index d045a82ca3a..0efd7445c23 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.exp @@ -1,15 +1,15 @@ processed 3 tasks task 1, line 15: -//# run 0x1::test::test --args 0 +//# run 0x6::test::test --args 0 mutable inputs after call: local#0: 0 task 2, line 17: -//# run 0x1::test::test --args 1 +//# run 0x6::test::test --args 1 Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), - location: 0x1::test, + location: 0x6::test, indices: [], offsets: [(FunctionDefinitionIndex(0), 10)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.mvir index 83b4bbfa1cd..b7e7c7aa05b 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/equality_reference_value.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.test { +module 0x6.test { public test(external: &mut u64) { let local: u64; let local_ref: &mut u64; @@ -12,6 +12,6 @@ module 0x1.test { } } -//# run 0x1::test::test --args 0 +//# run 0x6::test::test --args 0 -//# run 0x1::test::test --args 1 +//# run 0x6::test::test --args 1 diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_reads.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_reads.mvir index 066dbdfb352..ba575c82694 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_reads.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_reads.mvir @@ -34,7 +34,7 @@ module 0x42.VTest { //# publish -module 0x42.RTest { +module 0x43.RTest { struct T{fint: u64, fv: bool} public new(x: u64, y: bool): Self.T { @@ -77,8 +77,8 @@ module 0x42.RTest { //# run -module 0x42.m { -import 0x42.RTest; +module 0x44.m { +import 0x43.RTest; import 0x42.VTest; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_writes.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_writes.mvir index 8f024050c92..32a2609aba8 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_writes.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/field_writes.mvir @@ -42,7 +42,7 @@ module 0x42.VTest { //# publish -module 0x42.RTest { +module 0x43.RTest { struct T{fint: u64, fr: bool} public new(x: u64, y: bool): Self.T { @@ -94,9 +94,9 @@ module 0x42.RTest { } //# run -module 0x42.m { +module 0x44.m { -import 0x42.RTest; +import 0x43.RTest; import 0x42.VTest; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/inaccessible_borrowed_local.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/inaccessible_borrowed_local.mvir index 8f450d189cd..d67840859c8 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/inaccessible_borrowed_local.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/inaccessible_borrowed_local.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { entry foo() { let x: vector; @@ -16,7 +16,7 @@ entry foo() { } //# run -module 0x2.m { +module 0x7.m { entry foo() { let x: vector; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/pack_unpack.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/pack_unpack.mvir index bf604e969e9..59a655cb373 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/pack_unpack.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/pack_unpack.mvir @@ -18,7 +18,7 @@ module 0x42.Test { } //# run -module 0x42.m { +module 0x43.m { import 0x42.Test; entry foo() { let t: Test.T; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.exp index e11e90d9bee..3574f2256de 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.exp @@ -5,7 +5,7 @@ task 0, lines 1-9: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x1::m, + location: 0x6::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -15,7 +15,7 @@ task 1, lines 11-20: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x2::m, + location: 0x7::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -25,7 +25,7 @@ task 2, lines 21-30: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x3::m, + location: 0x8::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -35,7 +35,7 @@ task 3, lines 31-40: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x4::m, + location: 0x9::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -45,7 +45,7 @@ task 4, lines 41-50: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x5::m, + location: 0xa::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -55,7 +55,7 @@ task 5, lines 51-60: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x6::m, + location: 0xb::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -65,7 +65,7 @@ task 6, lines 61-70: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x7::m, + location: 0xc::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -75,7 +75,7 @@ task 7, lines 71-80: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x8::m, + location: 0xd::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -85,7 +85,7 @@ task 8, lines 81-90: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x9::m, + location: 0xe::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } @@ -95,7 +95,7 @@ task 9, lines 91-102: Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, - location: 0x10::m, + location: 0x15::m, indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.mvir index f68a7733760..09246106d34 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/shift_operators.mvir @@ -1,5 +1,5 @@ //# run -module 0x1.m { +module 0x6.m { // Number of bits shifted >= total number of bits in the number. entry foo() { label b0: @@ -9,7 +9,7 @@ label b0: } //# run -module 0x2.m { +module 0x7.m { entry foo() { label b0: @@ -19,7 +19,7 @@ label b0: } //# run -module 0x3.m { +module 0x8.m { entry foo() { label b0: @@ -29,7 +29,7 @@ label b0: } //# run -module 0x4.m { +module 0x9.m { entry foo() { label b0: @@ -39,7 +39,7 @@ label b0: } //# run -module 0x5.m { +module 0xa.m { entry foo() { label b0: @@ -49,7 +49,7 @@ label b0: } //# run -module 0x6.m { +module 0xb.m { entry foo() { label b0: @@ -59,7 +59,7 @@ label b0: } //# run -module 0x7.m { +module 0xc.m { entry foo() { label b0: @@ -69,7 +69,7 @@ label b0: } //# run -module 0x8.m { +module 0xd.m { entry foo() { label b0: @@ -79,7 +79,7 @@ label b0: } //# run -module 0x9.m { +module 0xe.m { entry foo() { label b0: @@ -89,7 +89,7 @@ label b0: } //# run -module 0x10.m { +module 0x15.m { entry foo() { label b0: @@ -101,7 +101,7 @@ label b0: // Shifting 0 results in 0. //# run -module 0x11.m { +module 0x16.m { entry foo() { label b0: @@ -126,7 +126,7 @@ label b0: // Shifting by 0 bits results in the same number. //# run -module 0x12.m { +module 0x17.m { entry foo() { label b0: @@ -151,7 +151,7 @@ label b0: // shl/shr by 1 equivalent to mul/div by 2. //# run -module 0x13.m { +module 0x18.m { entry foo() { label b0: @@ -176,7 +176,7 @@ label b0: // Underflowing results in 0. //# run -module 0x14.m { +module 0x19.m { entry foo() { label b0: @@ -194,7 +194,7 @@ label b0: // Overflowing results are truncated. //# run -module 0x15.m { +module 0x1a.m { entry foo() { label b0: @@ -212,7 +212,7 @@ label b0: // Some random tests. //# run -module 0x16.m { +module 0x1b.m { entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/vec_copy_nested.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/vec_copy_nested.mvir index c207849e000..cf03f472103 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/vec_copy_nested.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/instructions/vec_copy_nested.mvir @@ -98,7 +98,7 @@ module 0x42.DeepCopy { } //# run -module 0x42.m { +module 0x43.m { import 0x42.DeepCopy; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use.mvir index aa7c37474cf..ba2e172bb72 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Coin { +module 0x5.Coin { struct Coin { value: u64 } public value(c: &Self.Coin): u64 { label b0: @@ -18,8 +18,8 @@ module 0x1.Coin { } //# publish -module 0x42.MoneyHolder { - import 0x1.Coin; +module 0x43.MoneyHolder { + import 0x5.Coin; struct T { money: Coin.Coin } @@ -48,9 +48,9 @@ module 0x42.MoneyHolder { } //# run -module 0x42.m { -import 0x42.MoneyHolder; -import 0x1.Coin; +module 0x44.m { +import 0x43.MoneyHolder; +import 0x5.Coin; entry foo() { let coin: Coin.Coin; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_2.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_2.mvir index d2e5c0a1624..6f8edc96c08 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_2.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_2.mvir @@ -18,7 +18,7 @@ module 0x42.M { } //# run -module 0x42.m { +module 0x43.m { import 0x42.M; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_3.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_3.mvir index 6ddeb8dba1e..d65c70d6800 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_3.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_3.mvir @@ -13,7 +13,7 @@ module 0x42.M { } //# run -module 0x42.m { +module 0x43.m { import 0x42.M; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_with_multiple_return_values.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_with_multiple_return_values.mvir index d4047b58f7a..236f32f502d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_with_multiple_return_values.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_module_and_use_with_multiple_return_values.mvir @@ -7,7 +7,7 @@ module 0x42.M { } //# run -module 0x42.m { +module 0x43.m { import 0x42.M; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_two_modules.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_two_modules.mvir index 8f0d9387075..b133d087cbf 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_two_modules.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/publish_two_modules.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Coin { +module 0x5.Coin { struct Coin { value: u64 } public value(c: &Self.Coin): u64 { label b0: @@ -19,7 +19,7 @@ module 0x1.Coin { //# publish module 0x42.MoneyHolder { - import 0x1.Coin; + import 0x5.Coin; struct T { money: Coin.Coin } @@ -48,7 +48,7 @@ module 0x42.MoneyHolder { } //# publish -module 0x42.Bar { +module 0x43.Bar { struct T has drop {baz: u64} public new(m: u64): Self.T { label b0: @@ -63,10 +63,10 @@ module 0x42.Bar { } //# run -module 0x42.m { +module 0x44.m { import 0x42.MoneyHolder; -import 0x42.Bar; -import 0x1.Coin; +import 0x43.Bar; +import 0x5.Coin; entry foo() { let coin: Coin.Coin; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/use_modules_published.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/use_modules_published.mvir index dcdebd065d3..68e3faee41d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/use_modules_published.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/module_publishing/use_modules_published.mvir @@ -31,7 +31,7 @@ module 0x44.M { } //# run -module 0x42.m { +module 0x45.m { import 0x42.M; entry foo() { @@ -42,7 +42,7 @@ label b0: } //# publish -module 0x45.M { +module 0x46.M { public baz(): u64 { label b0: return 9; @@ -50,7 +50,7 @@ module 0x45.M { } //# run -module 0x42.m { +module 0x47.m { import 0x42.M as M1; import 0x43.M as M2; import 0x44.M as M3; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/native_functions/vector_module.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/native_functions/vector_module.mvir index a34e162230c..83102440b63 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/native_functions/vector_module.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/native_functions/vector_module.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Coin { +module 0x5.Coin { struct Coin has store { value: u64 } public value(c: &Self.Coin): u64 { label b0: @@ -19,7 +19,7 @@ module 0x1.Coin { //# publish module 0x42.M { - import 0x1.Coin; + import 0x5.Coin; import 0x1.vector; struct Coins has key { f: vector } @@ -56,9 +56,9 @@ module 0x42.M { } //# publish -module 0x42.Test { +module 0x43.Test { import 0x42.M; - import 0x1.Coin; + import 0x5.Coin; test() { let coins: M.Coins; label b0: @@ -69,4 +69,4 @@ module 0x42.Test { } } -//# run 0x42::Test::test +//# run 0x43::Test::test diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/direct_recursion.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/direct_recursion.mvir index e08ad043836..aecb629fb3c 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/direct_recursion.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/direct_recursion.mvir @@ -26,7 +26,7 @@ module 0x42.Math { } //# run -module 0x42.m { +module 0x43.m { import 0x42.Math; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/mutual_recursion.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/mutual_recursion.mvir index d10b4ba6073..25e80f542b7 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/mutual_recursion.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/mutual_recursion.mvir @@ -25,7 +25,7 @@ module 0x42.Math { } //# run -module 0x42.m { +module 0x43.m { import 0x42.Math; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/runtime_type_deeply_nested.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/runtime_type_deeply_nested.mvir index 66a7ce0076d..4acff3c9076 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/runtime_type_deeply_nested.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/recursion/runtime_type_deeply_nested.mvir @@ -70,7 +70,7 @@ module 0x42.M { // check: "Keep(EXECUTED)" //# run -module 0x1.m { +module 0x43.m { import 0x42.M; entry foo() { @@ -81,7 +81,7 @@ label b0: } //# run -module 0x2.m { +module 0x44.m { import 0x42.M; entry foo() { diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.exp index 12d7f4b3fe6..5fdcd3de1af 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.exp +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.exp @@ -22,10 +22,10 @@ Error: Function execution failed with VMError: { task 2, lines 27-45: //# run --gas-budget 100000 -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, - location: 0x42::m, + location: 0x43::m, indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.mvir index fd08cbacccb..e7fef2669e1 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/references/borrow_in_loop.mvir @@ -25,7 +25,7 @@ public foo() { //# run 0x42::m::foo --gas-budget 100000 //# run --gas-budget 100000 -module 0x42.m { +module 0x43.m { entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/references/deref_move_module_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/references/deref_move_module_ok.mvir index b4e16544872..70903e9a935 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/references/deref_move_module_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/references/deref_move_module_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x6.M { struct T has drop {v : u64} public new(v: u64): Self.T { @@ -18,7 +18,7 @@ module 0x1.M { //# run module 0x42.m { -import 0x1.M; +import 0x6.M; entry foo() { let x: M.T; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/references/mixed_lvalue.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/references/mixed_lvalue.mvir index 73af8a2084f..269ae5edbd2 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/references/mixed_lvalue.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/references/mixed_lvalue.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x6.A { struct S { f: u64 } @@ -47,7 +47,7 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; +import 0x6.A; entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/references/mutate_move_ok.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/references/mutate_move_ok.mvir index e503936458f..f1579072bc2 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/references/mutate_move_ok.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/references/mutate_move_ok.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.B { +module 0x6.B { struct T has drop {g: u64} public new(v: u64): Self.T { @@ -26,7 +26,7 @@ module 0x1.B { //# run module 0x42.m { -import 0x1.B; +import 0x6.B; entry foo() { let x: B.T; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/add_function_calls.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/add_function_calls.mvir index 638dc3d0193..e2413c7a8d5 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/add_function_calls.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/add_function_calls.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.M { +module 0x5.M { public foo(u: u64): u64 * u64 * u64 { let twice: u64; let quadruple: u64; @@ -17,8 +17,8 @@ module 0x1.M { //# run -module 0x42.m { -import 0x1.M; +module 0x43.m { +import 0x5.M; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/assign_function_call.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/assign_function_call.mvir index 23de1570157..eeb8dbf8604 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/assign_function_call.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/assign_function_call.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public ones_tens(f: u64): u64 * u64 { let k: u64; let m: u64; @@ -12,8 +12,8 @@ module 0x1.A { //# run -module 0x42.m { -import 0x1.A; +module 0x43.m { +import 0x5.A; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/binop_function_calls_as_args.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/binop_function_calls_as_args.mvir index a5ab28c31b8..43e479849cd 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/binop_function_calls_as_args.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/binop_function_calls_as_args.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public div_by_two(v: u64): bool { label b0: jump_if (move(v) % 2 == 0) b2; @@ -27,7 +27,7 @@ module 0x1.A { //# run module 0x42.m { -import 0x1.A; +import 0x5.A; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/function_composition.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/function_composition.mvir index 9e2d582a416..1fcb87dc094 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/function_composition.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/function_composition.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.Test { +module 0x5.Test { public foo(v: u64): u64 * u64 { let one_less: u64; let one_more: u64; @@ -19,8 +19,8 @@ module 0x1.Test { //# run -module 0x42.m { -import 0x1.Test; +module 0x43.m { +import 0x5.Test; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/many_function_calls_as_args.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/many_function_calls_as_args.mvir index 7c91b3b266b..8cf8459454d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/many_function_calls_as_args.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/many_function_calls_as_args.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { struct T has drop {value: u64, even: bool} public new(): Self.T { @@ -40,8 +40,8 @@ module 0x1.A { //# run -module 0x42.m { -import 0x1.A; +module 0x43.m { +import 0x5.A; entry foo() { let x: A.T; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/multiple_composite_functions.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/multiple_composite_functions.mvir index 95159be8b19..7f05f023aeb 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/multiple_composite_functions.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/multiple_composite_functions.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { struct T has drop {value: u64} public new(v: u64): Self.T { @@ -22,8 +22,8 @@ module 0x1.A { //# run -module 0x42.m { -import 0x1.A; +module 0x43.m { +import 0x5.A; entry foo() { let z: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pass_args_on_stack_as_expressions.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pass_args_on_stack_as_expressions.mvir index fc5e86cf6ef..e5337fbeedf 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pass_args_on_stack_as_expressions.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pass_args_on_stack_as_expressions.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public sum(o: u64, k: u64, t: u64): u64 { label b0: return move(o) + move(k) + move(t); @@ -8,8 +8,8 @@ module 0x1.A { //# run -module 0x42.m { -import 0x1.A; +module 0x43.m { +import 0x5.A; entry foo() { let s: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pop_weird.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pop_weird.mvir index ae5a2d1e0ad..c3f603b9e3c 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pop_weird.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/pop_weird.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { three(): u64 * u64 * u64 { label b0: return 0, 1, 2; @@ -16,8 +16,8 @@ module 0x1.A { //# run -module 0x42.m { -import 0x1.A; +module 0x43.m { +import 0x5.A; entry foo() { label b0: diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_call.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_call.mvir index 3e0ad217080..6cafc621c23 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_call.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_call.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public push_u64(): u64 { label b0: return 42; @@ -22,9 +22,9 @@ module 0x1.A { //# run -module 0x42.m { +module 0x43.m { -import 0x1.A; +import 0x5.A; entry foo() { let ans: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_composition.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_composition.mvir index 98e21227bf0..8c8043bb320 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_composition.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/push_args_before_function_composition.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public push_u64(): u64 { label b0: return 42; @@ -22,9 +22,9 @@ module 0x1.A { //# run -module 0x42.m { +module 0x43.m { -import 0x1.A; +import 0x5.A; entry foo() { let k: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_expression_lists.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_expression_lists.mvir index a7066128939..6307ef9c70d 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_expression_lists.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_expression_lists.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public foo(t: u64): u64 * u64 { let k: u64; label b0: @@ -17,9 +17,9 @@ module 0x1.A { //# run -module 0x42.m { +module 0x43.m { -import 0x1.A; +import 0x5.A; entry foo() { let y: u64; diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_function_in_if_binop_in_else.mvir b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_function_in_if_binop_in_else.mvir index 8c6f8b6da1e..803acdb4808 100644 --- a/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_function_in_if_binop_in_else.mvir +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/stack_and_function_calls/return_function_in_if_binop_in_else.mvir @@ -1,5 +1,5 @@ //# publish -module 0x1.A { +module 0x5.A { public foo(t: u64): u64 * u64 { label b0: return (copy(t), 2 * move(t)); @@ -17,9 +17,9 @@ module 0x1.A { //# run -module 0x1.m { +module 0x6.m { -import 0x1.A; +import 0x5.A; entry foo() { let x: u64; diff --git a/external-crates/move/crates/move-vm-types/Cargo.toml b/external-crates/move/crates/move-vm-types/Cargo.toml index 0804f5fb672..1c180f4a5bf 100644 --- a/external-crates/move/crates/move-vm-types/Cargo.toml +++ b/external-crates/move/crates/move-vm-types/Cargo.toml @@ -21,6 +21,3 @@ move-vm-profiler.workspace = true [features] default = [] fuzzing = ["proptest", "move-binary-format/fuzzing"] -gas-profiler = [ - "move-vm-profiler/gas-profiler", -] diff --git a/external-crates/move/crates/move-vm-types/src/values/values_impl.rs b/external-crates/move/crates/move-vm-types/src/values/values_impl.rs index ca458d6d54b..2180822bfd0 100644 --- a/external-crates/move/crates/move-vm-types/src/values/values_impl.rs +++ b/external-crates/move/crates/move-vm-types/src/values/values_impl.rs @@ -3,29 +3,32 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::{ - loaded_data::runtime_types::Type, - views::{ValueView, ValueVisitor}, +use std::{ + cell::RefCell, + fmt::{self, Debug, Display}, + iter, + ops::Add, + rc::Rc, }; + use move_binary_format::{ errors::*, file_format::{Constant, SignatureToken, VariantTag}, }; use move_core_types::{ + VARIANT_COUNT_MAX, account_address::AccountAddress, + annotated_value as A, effects::Op, gas_algebra::AbstractMemorySize, runtime_value::{MoveEnumLayout, MoveStructLayout, MoveTypeLayout}, u256, - vm_status::{sub_status::NFE_VECTOR_ERROR_BASE, StatusCode}, - VARIANT_COUNT_MAX, + vm_status::{StatusCode, sub_status::NFE_VECTOR_ERROR_BASE}, }; -use std::{ - cell::RefCell, - fmt::{self, Debug, Display}, - iter, - ops::Add, - rc::Rc, + +use crate::{ + loaded_data::runtime_types::Type, + views::{ValueView, ValueVisitor}, }; /// **************************************************************************** @@ -233,13 +236,15 @@ pub struct Variant { #[derive(Debug)] pub struct VariantRef(ContainerRef); -/*************************************************************************************** - * - * Misc - * - * Miscellaneous helper functions. - * - **************************************************************************************/ +/// **************************************************************************** +/// ********* +/// +/// Misc +/// +/// Miscellaneous helper functions. +/// +/// **************************************************************************** +/// ******* impl Container { fn len(&self) -> usize { @@ -883,7 +888,7 @@ impl ContainerRef { ) .with_message( "failed to write_ref: container type mismatch".to_string(), - )) + )); } }, Container::Vec(r) => assign!(r, Vec), @@ -1141,15 +1146,13 @@ impl VariantRef { }), x @ (ValueImpl::ContainerRef(_) | ValueImpl::IndexedRef(_) - | ValueImpl::Invalid) => { - return Err(PartialVMError::new( - StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR, - ) - .with_message(format!( + | ValueImpl::Invalid) => return Err(PartialVMError::new( + StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR, + ) + .with_message(format!( "cannot unpack a reference value {:?} held inside a variant ref {:?}", x, self - ))) - } + ))), }; res.push(Value(ref_)); } @@ -1403,7 +1406,8 @@ impl Value { )))) } - // TODO: consider whether we want to replace these with fn vector(v: Vec). + // TODO: consider whether we want to replace these with fn vector(v: + // Vec). pub fn vector_u8(it: impl IntoIterator) -> Self { Self(ValueImpl::Container(Container::VecU8(Rc::new( RefCell::new(it.into_iter().collect()), @@ -2763,13 +2767,15 @@ impl Struct { } } -/*************************************************************************************** - * - * Variant Operations - * - * Public APIs for Enums. - * - **************************************************************************************/ +/// **************************************************************************** +/// ********* +/// +/// Variant Operations +/// +/// Public APIs for Enums. +/// +/// **************************************************************************** +/// ******* impl Variant { pub fn pack>(tag: VariantTag, vals: I) -> Self { Self { @@ -2792,15 +2798,18 @@ impl Variant { } } -/*************************************************************************************** - * - * Global Value Operations - * - * Public APIs for GlobalValue. They allow global values to be created from external - * source (a.k.a. storage), and references to be taken from them. At the end of the - * transaction execution the dirty ones can be identified and wrote back to storage. - * - **************************************************************************************/ +/// **************************************************************************** +/// ********* +/// +/// Global Value Operations +/// +/// Public APIs for GlobalValue. They allow global values to be created from +/// external source (a.k.a. storage), and references to be taken from them. At +/// the end of the transaction execution the dirty ones can be identified and +/// wrote back to storage. +/// +/// **************************************************************************** +/// ******* #[allow(clippy::unnecessary_wraps)] impl GlobalValueImpl { fn cached( @@ -3312,9 +3321,9 @@ pub mod debug { /// **************************************************************************** /// ******* use serde::{ + Deserialize, de::Error as DeError, ser::{Error as SerError, SerializeSeq, SerializeTuple}, - Deserialize, }; impl Value { @@ -3356,7 +3365,7 @@ impl<'a, 'b> serde::Serialize for AnnotatedValue<'a, 'b, MoveTypeLayout, ValueIm (MoveTypeLayout::Struct(struct_layout), ValueImpl::Container(Container::Struct(r))) => { (AnnotatedValue { - layout: struct_layout, + layout: &**struct_layout, val: &*r.borrow(), }) .serialize(serializer) @@ -3364,7 +3373,7 @@ impl<'a, 'b> serde::Serialize for AnnotatedValue<'a, 'b, MoveTypeLayout, ValueIm (MoveTypeLayout::Enum(enum_layout), ValueImpl::Container(Container::Variant(r))) => { (AnnotatedValue { - layout: enum_layout, + layout: &**enum_layout, val: &*r.borrow(), }) .serialize(serializer) @@ -3533,12 +3542,12 @@ impl<'d> serde::de::DeserializeSeed<'d> for SeedWrapper<&MoveTypeLayout> { L::Signer => AccountAddress::deserialize(deserializer).map(Value::signer), L::Struct(struct_layout) => Ok(SeedWrapper { - layout: struct_layout, + layout: &**struct_layout, } .deserialize(deserializer)?), L::Enum(enum_layout) => Ok(SeedWrapper { - layout: enum_layout, + layout: &**enum_layout, } .deserialize(deserializer)?), @@ -3673,7 +3682,7 @@ impl<'d, 'a> serde::de::Visitor<'d> for EnumFieldVisitor<'a> { return Err(A::Error::invalid_type( serde::de::Unexpected::Other(&format!("{val:?}")), &self, - )) + )); } None => return Err(A::Error::invalid_length(0, &self)), }; @@ -3704,13 +3713,15 @@ impl<'d, 'a> serde::de::DeserializeSeed<'d> for &MoveRuntimeVariantFieldLayout<' } } -/*************************************************************************************** -* -* Constants -* -* Implementation of deserialization of constant data into a runtime value -* -**************************************************************************************/ +/// **************************************************************************** +/// ********* +/// +/// Constants +/// +/// Implementation of deserialization of constant data into a runtime value +/// +/// **************************************************************************** +/// ******* impl Value { fn constant_sig_token_to_layout(constant_signature: &SignatureToken) -> Option { @@ -3955,7 +3966,8 @@ impl ValueView for VariantRef { } } -// Note: We may want to add more helpers to retrieve value views behind references here. +// Note: We may want to add more helpers to retrieve value views behind +// references here. impl Struct { #[allow(clippy::needless_lifetimes)] @@ -4169,7 +4181,7 @@ pub mod prop { prop_oneof![ 1 => inner.clone().prop_map(|layout| L::Vector(Box::new(layout))), 1 => vec(inner, 0..1).prop_map(|f_layouts| { - L::Struct(MoveStructLayout::new(f_layouts))}), + L::Struct(Box::new(MoveStructLayout::new(f_layouts)))}), ] }) } @@ -4198,10 +4210,11 @@ impl ValueImpl { (L::Bool, ValueImpl::Bool(x)) => MoveValue::Bool(*x), (L::Address, ValueImpl::Address(x)) => MoveValue::Address(*x), - (L::Enum(MoveEnumLayout(variants)), ValueImpl::Container(Container::Variant(r))) => { + (L::Enum(enum_layout), ValueImpl::Container(Container::Variant(r))) => { + let MoveEnumLayout(variants) = &**enum_layout; let (tag, values) = &*r.borrow(); let tag = *tag; - let field_layouts = &variants[tag as usize]; + let field_layouts = &variants.as_slice()[tag as usize]; let mut fields = vec![]; for (v, field_layout) in values.iter().zip(field_layouts) { fields.push(v.as_move_value(field_layout)); @@ -4262,4 +4275,141 @@ impl Value { pub fn as_move_value(&self, layout: &MoveTypeLayout) -> MoveValue { self.0.as_move_value(layout) } + + pub fn as_annotated_move_value_for_tracing_only( + &self, + layout: &A::MoveTypeLayout, + ) -> Option { + self.0.as_annotated_move_value(layout) + } +} + +impl ValueImpl { + /// Converts the value to an annotated move value. This is only needed for + /// tracing and care should be taken when using this function as it can + /// possibly inflate the size of the value. + fn as_annotated_move_value(&self, layout: &A::MoveTypeLayout) -> Option { + use move_core_types::annotated_value::{MoveTypeLayout as L, MoveValue}; + Some(match (layout, self) { + (L::U8, ValueImpl::U8(x)) => MoveValue::U8(*x), + (L::U16, ValueImpl::U16(x)) => MoveValue::U16(*x), + (L::U32, ValueImpl::U32(x)) => MoveValue::U32(*x), + (L::U64, ValueImpl::U64(x)) => MoveValue::U64(*x), + (L::U128, ValueImpl::U128(x)) => MoveValue::U128(*x), + (L::U256, ValueImpl::U256(x)) => MoveValue::U256(*x), + (L::Bool, ValueImpl::Bool(x)) => MoveValue::Bool(*x), + (L::Address, ValueImpl::Address(x)) => MoveValue::Address(*x), + (l, ValueImpl::Container(c)) => return c.as_annotated_move_value(l), + ( + _, + ValueImpl::ContainerRef( + ContainerRef::Local(c) | ContainerRef::Global { container: c, .. }, + ), + ) => return c.as_annotated_move_value(layout), + ( + _, + ValueImpl::IndexedRef(IndexedRef { + container_ref: + ContainerRef::Local(c) | ContainerRef::Global { container: c, .. }, + idx, + }), + ) => { + use Container::*; + let idx = *idx; + let res = match c { + Locals(r) | Vec(r) | Struct(r) => r.borrow()[idx].copy_value().unwrap(), + Variant(r) => r.borrow().1[idx].copy_value().unwrap(), + VecU8(r) => ValueImpl::U8(r.borrow()[idx]), + VecU16(r) => ValueImpl::U16(r.borrow()[idx]), + VecU32(r) => ValueImpl::U32(r.borrow()[idx]), + VecU64(r) => ValueImpl::U64(r.borrow()[idx]), + VecU128(r) => ValueImpl::U128(r.borrow()[idx]), + VecU256(r) => ValueImpl::U256(r.borrow()[idx]), + VecBool(r) => ValueImpl::Bool(r.borrow()[idx]), + VecAddress(r) => ValueImpl::Address(r.borrow()[idx]), + }; + return res.as_annotated_move_value(layout); + } + (_layout, _val) => return None, + }) + } +} + +impl Container { + fn as_annotated_move_value(&self, layout: &A::MoveTypeLayout) -> Option { + use move_core_types::annotated_value::MoveTypeLayout as L; + Some(match (layout, self) { + (L::Enum(e_layout), Container::Variant(r)) => { + let A::MoveEnumLayout { type_, variants } = e_layout.as_ref(); + let (tag, values) = &*r.borrow(); + let tag = *tag; + let ((name, _), field_layouts) = + variants.iter().find(|((_, t), _)| *t == tag).unwrap(); + let mut fields = vec![]; + for (v, field_layout) in values.iter().zip(field_layouts) { + fields.push(( + field_layout.name.clone(), + v.as_annotated_move_value(&field_layout.layout)?, + )); + } + A::MoveValue::Variant(A::MoveVariant { + tag, + fields, + type_: type_.clone(), + variant_name: name.clone(), + }) + } + (L::Struct(struct_layout), Container::Struct(r)) => { + let mut fields = vec![]; + for (v, field_layout) in r.borrow().iter().zip(struct_layout.fields.iter()) { + fields.push(( + field_layout.name.clone(), + v.as_annotated_move_value(&field_layout.layout)?, + )); + } + A::MoveValue::Struct(A::MoveStruct::new(struct_layout.type_.clone(), fields)) + } + + (L::Vector(inner_layout), c) => A::MoveValue::Vector(match c { + Container::VecU8(r) => r.borrow().iter().map(|u| A::MoveValue::U8(*u)).collect(), + Container::VecU16(r) => r.borrow().iter().map(|u| A::MoveValue::U16(*u)).collect(), + Container::VecU32(r) => r.borrow().iter().map(|u| A::MoveValue::U32(*u)).collect(), + Container::VecU64(r) => r.borrow().iter().map(|u| A::MoveValue::U64(*u)).collect(), + Container::VecU128(r) => { + r.borrow().iter().map(|u| A::MoveValue::U128(*u)).collect() + } + Container::VecU256(r) => { + r.borrow().iter().map(|u| A::MoveValue::U256(*u)).collect() + } + Container::VecBool(r) => { + r.borrow().iter().map(|u| A::MoveValue::Bool(*u)).collect() + } + Container::VecAddress(r) => r + .borrow() + .iter() + .map(|u| A::MoveValue::Address(*u)) + .collect(), + Container::Vec(r) => r + .borrow() + .iter() + .map(|v| v.as_annotated_move_value(inner_layout)) + .collect::>()?, + Container::Struct(_) | Container::Variant { .. } | Container::Locals(_) => { + return None; + } + }), + + (L::Signer, Container::Struct(r)) => { + let v = r.borrow(); + if v.len() != 1 { + return None; + } + match &v[0] { + ValueImpl::Address(a) => A::MoveValue::Signer(*a), + _ => return None, + } + } + (_layout, _val) => return None, + }) + } } diff --git a/external-crates/move/documentation/book/src/packages.md b/external-crates/move/documentation/book/src/packages.md index f6c052dc314..461f8ab5603 100644 --- a/external-crates/move/documentation/book/src/packages.md +++ b/external-crates/move/documentation/book/src/packages.md @@ -24,10 +24,11 @@ a_move_package └── tests (optional, test mode) ``` -The directories and files labeled "required" must be present for a directory to be considered a Move -package and built. Optional directories may be present, and if so, they will be included in the -compilation process depending on the mode used to build the package. For instance, when built in -"dev" or "test" modes, the `tests` and `examples` directories will also be included. +The directories and files labeled "required" must be present for a directory to be +considered a Move package and built. Optional directories may be present, +and if so, they will be included in the compilation process depending on the +mode used to build the package. For instance, when built in "dev" or "test" +modes, the `tests` and `examples` directories will also be included. Going through each of these in turn: diff --git a/external-crates/move/documentation/coding_guidelines.md b/external-crates/move/documentation/coding_guidelines.md index 7c83259a643..6995f66f1b6 100644 --- a/external-crates/move/documentation/coding_guidelines.md +++ b/external-crates/move/documentation/coding_guidelines.md @@ -129,9 +129,11 @@ In the following sections, we have suggested some best practices for a uniform c Make sure to use the appropriate attributes for handling dead code: ``` -// For code that is intended for production usage in the future #[allow(dead_code)] +// For code that is intended for production usage in the future +#[allow(dead_code)] // For code that is only intended for testing and -// has no intended production use #[cfg(test)] +// has no intended production use +#[cfg(test)] ```` ### Avoid Deref polymorphism @@ -208,10 +210,10 @@ we use checked arithmetic instead of directly using math symbols. It forces us to think of edge-cases, and handle them explicitly. This is a brief and simplified mini guide of the different functions that exist to handle integer arithmetic: -- [checked\_](https://doc.rust-lang.org/std/primitive.u32.html#method.checked_add): use this function if you want to handle overflows and underflows as a special edge-case. It returns `None` if an underflow or overflow has happened, and `Some(operation_result)` otherwise. -- [overflowing\_](https://doc.rust-lang.org/std/primitive.u32.html#method.overflowing_add): use this function if you want the result of an overflow to potentially wrap around (e.g. `u64::MAX.overflow_add(10) == (9, true)`). It returns the underflowed or overflowed result as well as a flag indicating if an overflow has occurred or not. -- [wrapping\_](https://doc.rust-lang.org/std/primitive.u32.html#method.wrapping_add): this is similar to overflowing operations, except that it returns the result directly. Use this function if you are sure that you want to handle underflows and overflows by wrapping around. -- [saturating\_](https://doc.rust-lang.org/std/primitive.u32.html#method.saturating_add): if an overflow occurs, the result is kept within the boundary of the type (e.g. `u64::MAX.saturating_add(1) == u64::MAX`). +- [checked_](https://doc.rust-lang.org/std/primitive.u32.html#method.checked_add): use this function if you want to handle overflows and underflows as a special edge-case. It returns `None` if an underflow or overflow has happened, and `Some(operation_result)` otherwise. +- [overflowing_](https://doc.rust-lang.org/std/primitive.u32.html#method.overflowing_add): use this function if you want the result of an overflow to potentially wrap around (e.g. `u64::MAX.overflow_add(10) == (9, true)`). It returns the underflowed or overflowed result as well as a flag indicating if an overflow has occured or not. +- [wrapping_](https://doc.rust-lang.org/std/primitive.u32.html#method.wrapping_add): this is similar to overflowing operations, except that it returns the result directly. Use this function if you are sure that you want to handle underflows and overflows by wrapping around. +- [saturating_](https://doc.rust-lang.org/std/primitive.u32.html#method.saturating_add): if an overflow occurs, the result is kept within the boundary of the type (e.g. `u64::MAX.saturating_add(1) == u64::MAX`). ### Logging diff --git a/external-crates/move/tooling/prettier-extension/.gitignore b/external-crates/move/tooling/prettier-extension/.gitignore new file mode 100644 index 00000000000..10686ce457e --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/.gitignore @@ -0,0 +1,3 @@ +node_modules +.vscode-test/ +*.vsix diff --git a/external-crates/move/tooling/prettier-extension/.vscodeignore b/external-crates/move/tooling/prettier-extension/.vscodeignore new file mode 100644 index 00000000000..d3378c17dc3 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/.vscodeignore @@ -0,0 +1,10 @@ +.vscode/** +.vscode-test/** +test/** +.gitignore +.yarnrc +vsc-extension-quickstart.md +**/jsconfig.json +**/*.map +**/.eslintrc.json +**/.vscode-test.* diff --git a/external-crates/move/tooling/prettier-extension/CHANGELOG.md b/external-crates/move/tooling/prettier-extension/CHANGELOG.md new file mode 100644 index 00000000000..f5b25b2cd70 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/CHANGELOG.md @@ -0,0 +1,7 @@ +# Change Log + +All notable changes to the "prettier-move" extension will be documented in this file. + +## v0.1.0 + +- alpha release of the Prettier Move extension diff --git a/external-crates/move/tooling/prettier-extension/CONTRIBUTING.md b/external-crates/move/tooling/prettier-extension/CONTRIBUTING.md new file mode 100644 index 00000000000..8d291ec22cc --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing + +## Building locally + +To build and package the extension locally, run: + +```shell +npm i +npm run package +``` + +> Note: `vsce` does not work with `pnpm`, make sure to use `npm` when building. + +You will find the `*.vsce` file with the current version of the package. + +## Submitting changes + +To submit your changes, please, open a PR to the https://github.com/iotaledger/iota.git repository. diff --git a/external-crates/move/tooling/prettier-extension/LICENSE b/external-crates/move/tooling/prettier-extension/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/external-crates/move/tooling/prettier-extension/README.md b/external-crates/move/tooling/prettier-extension/README.md new file mode 100644 index 00000000000..cbe21840e92 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/README.md @@ -0,0 +1,58 @@ +# Move Formatter + +This is an alpha build of the Move Formatter extension. Note that this extension is not final, should not be considered a production-grade tool, and is intended only for early access testing of the Prettier formatter in Move. + +# Using the formatter + +After installing the extension, you should be ready to start using the formatter without installing any other tools. + +To use the formatter, enter Command-Shift-P or Control-Shift-P to bring up the VSCode Command Palette, then type 'Format Document'. The default hotkey for this command in VSCode is Control-Shift-I or Command-Shift-I. + +# Configuring the formatter + +Extension looks for `.prettierrc` (or similar prettier configuration files) in the workspace. If a configuration file is not found, it will fallback to extension settings, and, if not, to `prettier` configuration if a separate Prettier extension is installed. + +## VSCode Configuration + +VSCode configuration for the extension is placed under `prettierMove`, these are the default settings of the +extension: + +```json +{ + "prettierMove.tabWidth": 4, + "prettierMove.printWidth": 100, + "prettierMove.useModuleLabel": true, + "prettierMove.autoGroupImports": "module", + "prettierMove.enableErrorDebug": false, + "prettierMove.wrapComments": false +} +``` + +### Option: `useModuleLabel` + +Boolean. When set to `true`, will convert old module blocks to a module label. Won't be applied to files containing more than one module. + +### Option: `autoGroupImports` + +Possible values: `package`, `module`. When set to `module`, each module dependency will be on a separate line. When +set to `package`, dependencies will be grouped by package address. + +```move +// value: `module` +use std::string::String; +use std::type_name; + +// value: `package` +use std::{string::String, std::type_name}; +``` + +# Reporting problems + +This is an alpha release. While it has been tested to the best of our ability, IT IS STILL POSSIBLE TO LOSE WORK because of bugs in the formatter. Please take steps to avoid deletion of your work, including only running the formatter over code that has been committed or otherwise backed-up. + +If you encounter a problem where the formatter emits malformed code or otherwise makes things worse for you, please report an issue on Github on the repo https://github.com/iotaledger/iota/ using a title beginning with [formatter]. +You can also leave a note on [Discord](https://discord.com/invite/iota) or [Telegram](https://t.me/+pxh89f8xU5RmYjNh). + +# License + +Apache-2.0 diff --git a/external-crates/move/tooling/prettier-extension/img/move.png b/external-crates/move/tooling/prettier-extension/img/move.png new file mode 100644 index 0000000000000000000000000000000000000000..c6bfb341aefabd117af3a2081d29495f5d540b1a GIT binary patch literal 256463 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

, +> = vector[1, 2, 3]; + +// blocks are supported, both single and +// multi line +const CONSTANT: u64 = { 100 + 200 }; +const CONSTANT: u64 = { + 100 + 200 + 500 +}; + +// vectors of numbers will be "filled" +// instead of being expanded vertically +const CONSTANT: vector = vector[ + 10000, 20000, 30000, 40000, 50000, + 60000, 70000, 80000, 90000, 100000, +]; + +// same applies to vectors of "bool"s +const CONSTANT: vector = vector[ + true, false, true, false, true, +]; + +// but does not apply to addresses +const CONSTANT: vector
= + vector[ + @0xA11CE, + @0xB0B, + @0xCA41, + @0xB004, + ]; + +// comments break the list always +const MOVES_POWER: vector = vector[ + 40, // Rock + 60, // Paper + 80, // Scissors +]; + +// === Comments === + +const /* A */ CONSTANT: /* B */ u8 = + /* C */ 1000; // trailing + +const CONSTANT: u8 = // line comment + 1000; + +// === Misc / Leftovers === + +/// this is a line +const A: u8 = 42; +const T: u8 = 100; // trailing comment + +/// This is another comment; +/// it should be attached to the node too. +const CONSTANT: u64 = 42; + +// bytestring literal +const CONSTANT: vector = + b"hello cruel world!"; + +// hex literal +const CONSTANT: vector = + x"AAAAAAAAAAAAAAAAAA"; + +// block +const CONSTANT: u64 = { + 100 + 200 // trailing comment in a block +}; + +// expression without a block +const CONSTANT: u8 = 5 + 100 / 2 * 3; + +// expressions will be kept on a single +// line whenever possible and not break +const CONSTANT: u8 = + 100000 * 200000 * 30000; + +// different vectors +const CONSTANT: vector = vector[ + 1, 2, 3, 4, 5, 6, +]; +const CONSTANT: vector = vector[ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, +]; +const CONSTANT: vector> = + vector[ + vector[1, 2, 3], + vector[4, 5, 6], + vector[7, 8, 9], + ]; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/constant.move b/external-crates/move/tooling/prettier-move/tests/module-members/constant.move new file mode 100644 index 00000000000..ac6ba721801 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/constant.move @@ -0,0 +1,119 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +/// Covers `constant` node in grammar +module test::constants; + +// standard constant, fits the line +const CONSTANT: vector = b"const"; // trailing + +// breaks on long value, trying to break +// the value first +const CONSTANT: vector = vector[ + 100, 200 +]; + +// alternatively will newline the value +const CONSTANT: vector = + b"constant_too_long"; + +// if there's a risk of breaking the type +// it will first try to break the value +const CONSTANT: vector> = + vector[]; + +// however, types will still break if +// there's no other option. A rare case. +const CONSTANT_ADDRESS: vector< + vector
+> = vector[1, 2, 3]; + +// blocks are supported, both single and +// multi line +const CONSTANT: u64 = { 100 + 200 }; +const CONSTANT: u64 = { + 100 + 200 + 500 +}; + +// vectors of numbers will be "filled" +// instead of being expanded vertically +const CONSTANT: vector = vector[ + 10000, 20000, 30000, 40000, 50000, + 60000, 70000, 80000, 90000, 100000, +]; + +// same applies to vectors of "bool"s +const CONSTANT: vector = vector[ + true, false, true, false, true, +]; + +// but does not apply to addresses +const CONSTANT: vector
= + vector[ + @0xA11CE, + @0xB0B, + @0xCA41, + @0xB004 + ]; + +// comments break the list always +const MOVES_POWER: vector = vector[ + 40, // Rock + 60, // Paper + 80, // Scissors +]; + +// === Comments === + +const /* A */ CONSTANT: /* B */ u8 = /* C */ 1000; // trailing + +const CONSTANT: u8 = + // line comment + 1000; + + +// === Misc / Leftovers === + +/// this is a line +const A: u8 = 42; +const T: u8 = 100; // trailing comment + +/// This is another comment; +/// it should be attached to the node too. +const CONSTANT: u64 = 42; + +// bytestring literal +const CONSTANT: vector = + b"hello cruel world!"; + +// hex literal +const CONSTANT: vector = + x"AAAAAAAAAAAAAAAAAA"; + +// block +const CONSTANT: u64 = { + 100 + 200 // trailing comment in a block +}; + +// expression without a block +const CONSTANT: u8 = 5 + 100 / 2 * 3; + +// expressions will be kept on a single +// line whenever possible and not break +const CONSTANT: u8 = + 100000 * 200000 * 30000; + +// different vectors +const CONSTANT: vector = vector[ + 1, 2, 3, 4, 5, 6 +]; +const CONSTANT: vector = vector[ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +]; +const CONSTANT: vector> = + vector[ + vector[1, 2, 3], + vector[4, 5, 6], + vector[7, 8, 9], + ]; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/enum.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/enum.exp.move new file mode 100644 index 00000000000..9a804886ebe --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/enum.exp.move @@ -0,0 +1,71 @@ +// options: +// printWidth: 30 +// useModuleLabel: true + +// Covers `enum_definition` node in grammar +module tests::enum; + +use iota::vec_map::VecMap; + +// empty enum example. +// gets fomatted but +// illegal in Move +public enum Empty {} + +// enum variants will always +// new line, and end with a +// comma +public enum Test { + // comments + A, // are kept + B, +} + +// abilities do not break +public enum Test has copy, drop, store { + A, +} + +// trailing abilities are +// supported +public enum Test { + A, +} has copy, drop, store; + +// type parameters can break +public enum LongEnum< + phantom A, + phantom B, +> { + A, + B, +} + +// positional, named and empty +// variants are supported +public enum Test { + // comments don't break + A, + B { a: u8, b: u64 }, // trailing comments don't break + C(u8, vector), // trailing comments don't break +} + +// positional fields break +// same applies to named +public enum Test { + VeryLongEnumVariantDoesntBreak, + // breaks and keeps indent + Positional( + vector, + VecMap, + ), + // breaks and keeps indent + NamedFields { + field_one: vector, // trailing doesn't break the field + field_two: u64, + }, + // doesn't break on colon + UltraLongNamed { + long_field_decl: LongTypeName, + }, +} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/enum.move b/external-crates/move/tooling/prettier-move/tests/module-members/enum.move new file mode 100644 index 00000000000..f4a8708afc5 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/enum.move @@ -0,0 +1,70 @@ +// options: +// printWidth: 30 +// useModuleLabel: true + +// Covers `enum_definition` node in grammar +module tests::enum; + +use iota::vec_map::VecMap; + +// empty enum example. +// gets fomatted but +// illegal in Move +public enum Empty {} + +// enum variants will always +// new line, and end with a +// comma +public enum Test { + // comments + A, // are kept + B, +} + +// abilities do not break +public enum Test has store, copy, drop { + A, +} + +// trailing abilities are +// supported +public enum Test { + A, +} has store, copy, drop; + +// type parameters can break +public enum LongEnum< + phantom A, + phantom B, +> { + A, + B, +} + +// positional, named and empty +// variants are supported +public enum Test { // comments don't break + A, + B { a: u8, b: u64 }, // trailing comments don't break + C(u8, vector), // trailing comments don't break +} + +// positional fields break +// same applies to named +public enum Test { + VeryLongEnumVariantDoesntBreak, + // breaks and keeps indent + Positional( + vector, + VecMap, + ), + // breaks and keeps indent + NamedFields { + field_one: vector, // trailing doesn't break the field + field_two: u64, + }, + // doesn't break on colon + UltraLongNamed { + long_field_decl: LongTypeName, + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/friend.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/friend.exp.move new file mode 100644 index 00000000000..d0dd9f9329b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/friend.exp.move @@ -0,0 +1,8 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::friend; + +friend prettier::something; +friend 0x2::haha; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/friend.move b/external-crates/move/tooling/prettier-move/tests/module-members/friend.move new file mode 100644 index 00000000000..d0dd9f9329b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/friend.move @@ -0,0 +1,8 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::friend; + +friend prettier::something; +friend 0x2::haha; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/function.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/function.exp.move new file mode 100644 index 00000000000..b9b88ac00ed --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/function.exp.move @@ -0,0 +1,116 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::function; + +// simple function, no body +fun function() {} + +// function with body +fun function() { + let x = 10; +} + +// function modifiers are aplied sorted correctly +entry fun function() {} + +// public fun +public fun function() {} + +// public(package) fun +public(package) fun function() {} + +// public(friend) fun +public(friend) fun function() {} + +// keeps no body, preserves native keyword +native fun function(); + +// sorts correctly, public first +public(package) native fun function(); + +// sorts correctly, public first +public native fun function(); + +// sorts correctly, public first +public entry fun function() {} + +// sorts correctly, public(package) first +public(package) entry fun function() {} + +// works as expected, single line +public fun function(a: u8) {} + +// still fits on the same line +public fun function(a: vector) {} + +// breaks on arguments +public fun function( + param1: vector, + param2: vector, +) {} + +// breaks on arguments instead of return type +public fun function( + a: vector, +): vector {} + +// breaks on arguments instead of type parameters +public fun function( + a: vector, +) {} + +// breaks on both arguments and type parameters +public fun function< + MyStruct, + MyOtherStruct, +>( + a: vector, + b: vector, +): vector {} + +// breaks on arguments, type params and return type +public fun function< + MyStruct, + MyOtherStruct, +>( + a: vector, + b: vector, +): Collection< + MyStruct, + MyOtherStruct, +> {} + +// keeps comments in place +public fun function( + // comment + a: vector, // comment + // comment + b: vector, // comment + // comment +): vector {} // comment + +// correctly breaks on types and preserves abilities +public fun function< + Token: store + copy + drop, +>( + a: vector, +): Collection {} + +// correctly breaks on tuple return with comments +public fun function( + a: vector, +): ( + // comment + u64, // comment + vector, // comment +) {} + +// === Misc === + +// removes space +public(friend) fun function() {} + +// removes space +public(package) fun function() {} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/function.move b/external-crates/move/tooling/prettier-move/tests/module-members/function.move new file mode 100644 index 00000000000..bf18ad19e0b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/function.move @@ -0,0 +1,113 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::function; + +// simple function, no body +fun function() {} + +// function with body +fun function() { + let x = 10; +} + +// function modifiers are aplied sorted correctly +entry fun function() {} + +// public fun +public fun function() {} + +// public(package) fun +public(package) fun function() {} + +// public(friend) fun +public(friend) fun function() {} + +// keeps no body, preserves native keyword +native fun function(); + +// sorts correctly, public first +public(package) native fun function(); + +// sorts correctly, public first +public native fun function(); + +// sorts correctly, public first +public entry fun function() {} + +// sorts correctly, public(package) first +public(package) entry fun function() {} + +// works as expected, single line +public fun function(a: u8) {} + +// still fits on the same line +public fun function(a: vector) {} + +// breaks on arguments +public fun function( + param1: vector, + param2: vector, +) {} + +// breaks on arguments instead of return type +public fun function( + a: vector, +): vector {} + +// breaks on arguments instead of type parameters +public fun function( + a: vector, +) {} + +// breaks on both arguments and type parameters +public fun function< + MyStruct, + MyOtherStruct +>( + a: vector, + b: vector, +): vector {} + +// breaks on arguments, type params and return type +public fun function< + MyStruct, + MyOtherStruct +>( + a: vector, + b: vector, +): Collection< + MyStruct, + MyOtherStruct, +> {} + +// keeps comments in place +public fun function( + // comment + a: vector, // comment + // comment + b: vector, // comment + // comment +): vector {} // comment + +// correctly breaks on types and preserves abilities +public fun function( + a: vector, +): Collection {} + +// correctly breaks on tuple return with comments +public fun function( + a: vector, +): ( // comment + u64, // comment + vector, // comment +) {} + +// === Misc === + +// removes space +public (friend) fun function() {} + +// removes space +public (package) fun function() {} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.exp.move new file mode 100644 index 00000000000..2bd839fd5fa --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.exp.move @@ -0,0 +1,26 @@ +// options: +// printWidth: 40 +// useModuleLabel: true +// autoGroupImports: package + +module prettier::group_imports; + +use iota::{ + clock::Clock, + coin::Coin, + dynamic_field as df, + dynamic_object_field as dof, + iota::IOTA, + table::{Self, Table}, + table_vec::{Self, TableVec as TV} +}; + +#[test_only] +use std::{ + string::String as UTF8, + ascii::String as ASCII, + vector as vec, + vector as haha, + option::{Self as opt, Option}, + type_name::get as type_name_get, +}; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.move b/external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.move new file mode 100644 index 00000000000..2bd839fd5fa --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/group_annotation_ignore.move @@ -0,0 +1,26 @@ +// options: +// printWidth: 40 +// useModuleLabel: true +// autoGroupImports: package + +module prettier::group_imports; + +use iota::{ + clock::Clock, + coin::Coin, + dynamic_field as df, + dynamic_object_field as dof, + iota::IOTA, + table::{Self, Table}, + table_vec::{Self, TableVec as TV} +}; + +#[test_only] +use std::{ + string::String as UTF8, + ascii::String as ASCII, + vector as vec, + vector as haha, + option::{Self as opt, Option}, + type_name::get as type_name_get, +}; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/group_imports.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports.exp.move new file mode 100644 index 00000000000..c2f69ab041c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports.exp.move @@ -0,0 +1,27 @@ +// options: +// printWidth: 40 +// useModuleLabel: true +// autoGroupImports: package + +module prettier::group_imports; + +use 0x0::{ + Account::{Self, Account}, + Something +}; +use std::{ + ascii::String as ASCII, + option::{Self as opt, Option}, + string::String as UTF8, + type_name::get as type_name_get, + vector::{Self as vec, Self as haha} +}; +use iota::{ + clock::Clock, + coin::Coin, + dynamic_field as df, + dynamic_object_field as dof, + iota::IOTA, + table::{Self, Table}, + table_vec::{Self, TableVec as TV} +}; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/group_imports.move b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports.move new file mode 100644 index 00000000000..04b3e8a5518 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports.move @@ -0,0 +1,29 @@ +// options: +// printWidth: 40 +// useModuleLabel: true +// autoGroupImports: package + +module prettier::group_imports; + +use iota::{ + clock::Clock, + coin::Coin, + dynamic_field as df, + dynamic_object_field as dof, + iota::IOTA, + table::{Self, Table}, + table_vec::{Self, TableVec as TV} +}; + +use std::{ + string::String as UTF8, + ascii::String as ASCII, + vector as vec, + vector as haha, + option::{Self as opt, Option}, + type_name::get as type_name_get, +}; + +use 0x0::Account; +use 0x0::Something; +use 0x0::Account::Account; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.exp.move new file mode 100644 index 00000000000..c87fc4a8334 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.exp.move @@ -0,0 +1,31 @@ +// options: +// printWidth: 40 +// useModuleLabel: true +// autoGroupImports: module + +module prettier::group_imports; + +use a::b::{ + Self as c, + e as f, + g as f, + h as i +}; +use std::ascii::String as ASCII; +use std::option::{Self as opt, Option}; +use std::string::String; +use std::type_name::get as type_name_get; +use std::vector as vec; +use iota::balance::{Self, Balance}; +use iota::coin::{Self, Coin}; +use iota::dynamic_field as df; +use iota::dynamic_object_field as dof; +use iota::event; +use iota::iota::IOTA; +use iota::transfer_policy::{ + Self, + TransferPolicy, + TransferRequest +}; + +public fun do_something() {} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.move b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.move new file mode 100644 index 00000000000..8bb45325a99 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/group_imports_module.move @@ -0,0 +1,28 @@ +// options: +// printWidth: 40 +// useModuleLabel: true +// autoGroupImports: module + +module prettier::group_imports; + +use a::b as c; +use a::b::e as f; +use a::{b::g as f, b::h as i}; + +use iota::balance::{Self, Balance}; +use iota::coin::{Self, Coin}; +use iota::dynamic_field as df; +use iota::dynamic_object_field as dof; +use iota::event; +use iota::iota::IOTA; +use iota::transfer_policy::{Self, TransferPolicy, TransferRequest}; + +use std::{ + string::String, + ascii::String as ASCII, + vector as vec, + option::{Self as opt, Option}, + type_name::get as type_name_get, +}; + +public fun do_something() {} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/members.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/members.exp.move new file mode 100644 index 00000000000..05d444cc361 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/members.exp.move @@ -0,0 +1,22 @@ +// options: +// useModuleLabel: true + +// correctly adds empty lines: +// - one after the module label +// - one between different members +// - allows glueing similar members + +module prettier::members; + +use std::string::String; +use iota::coin::Coin; + +const I: u8 = 0; // together with const B +const B: u16 = 100; // empty line after + +public struct Point(u8) // together with Point2 +public struct Point2(u8) // empty line after + +public fun call_something() {} // followed by empty line + +public fun call_something_else() {} // empty line after diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/members.move b/external-crates/move/tooling/prettier-move/tests/module-members/members.move new file mode 100644 index 00000000000..91bc4a1cbf2 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/members.move @@ -0,0 +1,17 @@ +// options: +// useModuleLabel: true + +// correctly adds empty lines: +// - one after the module label +// - one between different members +// - allows glueing similar members + +module prettier::members; +use iota::coin::Coin; // glued with other import +use std::string::String; // empty line follows +const I: u8 = 0; // together with const B +const B: u16 = 100; // empty line after +public struct Point(u8) // together with Point2 +public struct Point2(u8) // empty line after +public fun call_something() {} // followed by empty line +public fun call_something_else() {} // empty line after diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/struct.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/struct.exp.move new file mode 100644 index 00000000000..3bd00db969d --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/struct.exp.move @@ -0,0 +1,127 @@ +// options: +// useModuleLabel: true +// printWidth: 40 + +module prettier::struct; + +use std::string::String; + +// struct and abilities never break the line +public struct Default has key, drop, store { + id: UID, + field: String, +} + +// we allow postfix ability declaration for +// structs as well +public struct Default2 { + id: UID, + field: String, +} has key, drop, store; + +// abilities are always sorted in `key`, +// copy`, `drop`, `store` order +public struct Sort has key, copy, drop, store {} + +// abilities support comments in between +public struct Cmt has /* please */ key /* don't */ , /* do */ store /* this */ {} + +// line comments are also possible, but +// let's hope no one ever uses them +public struct Cmt2 has copy, drop, // kill me +store // trailing + {} + +// empty struct can be with comemtns +// both single and multi-line +public struct Cmt3 { /* block cmmt */ } +public struct Cmt4 { + // line cmmt +} + +// struct can be single line, and breaks +// automatically +public struct Struct has key { id: UID } + +// broken into multiple lines +public struct Struct2 has key { + id: UID, + field: String, +} + +// struct will first try to break on fields +// and then break on type arguments +public struct Struct3 { + field: String, +} + +// struct can break on type arguments +public struct Struct4< + phantom Token, + Coin, +> { field: String } + +// inner fields of the struct also break +// when possible - on type arguments +public struct Struct5< + FirstParam, + SecondParam, +> { + field_name: ExtraLongType< + FirstParam, + SecondParam, + >, + another_field: String, +} + +// === Positional === + +// positional struct breaks on fields and +// not on abilities +public struct Point( + u64, + u64, +) has key, drop, store; + +// prefix abilities are also an option +public struct Point2 has key, drop, store ( + u64, + u64, +) + +// breaks on type arguments, but first +// tries on fields +public struct Container( + u64, + T, +) + +// will break on type arguments, not fields +public struct Container2< + phantom T, + phantom C, +>(u64, T) + +// will reformat into single line +public struct Point(u64, u64) + +// allows line comments, they break the list +public struct Point( + u64, // X + u64, // Y +) + +// allows block comments before types +/* what about this? */ public struct /* oh my god */ Point /* hello */ ( + /* X */ u64, /* post */ + /* Y */ u64, /* post okay */ + // trailing +) // trailing for Point + +// allows block comments before types +public struct /* kill me */ Point( + /* Leading Block */ + u64, // trailing + /* Leading Block 2 */ + u64, // trailing +) // trailing diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/struct.move b/external-crates/move/tooling/prettier-move/tests/module-members/struct.move new file mode 100644 index 00000000000..2f08da8f19c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/struct.move @@ -0,0 +1,116 @@ +// options: +// useModuleLabel: true +// printWidth: 40 + +module prettier::struct; + +use std::string::String; + +// struct and abilities never break the line +public struct Default has key, store, drop { + id: UID, + field: String, +} + +// we allow postfix ability declaration for +// structs as well +public struct Default2 { + id: UID, + field: String, +} has key, store, drop; + +// abilities are always sorted in `key`, +// copy`, `drop`, `store` order +public struct Sort has key, store, drop, copy {} + +// abilities support comments in between +public struct Cmt has /* please */ key /* don't */, /* do */ store /* this */ {} + +// line comments are also possible, but +// let's hope no one ever uses them +public struct Cmt2 has copy, +// kill me +store, // trailing +drop, +{} + +// empty struct can be with comemtns +// both single and multi-line +public struct Cmt3 { /* block cmmt */ } +public struct Cmt4 { + // line cmmt +} + +// struct can be single line, and breaks +// automatically +public struct Struct has key { id: UID } + +// broken into multiple lines +public struct Struct2 has key { id: UID, field: String } + +// struct will first try to break on fields +// and then break on type arguments +public struct Struct3 { field: String } + +// struct can break on type arguments +public struct Struct4< + phantom Token, + Coin +> { field: String } + +// inner fields of the struct also break +// when possible - on type arguments +public struct Struct5< + FirstParam, + SecondParam +> { + field_name: ExtraLongType< + FirstParam, + SecondParam + >, + another_field: String, +} + +// === Positional === + +// positional struct breaks on fields and +// not on abilities +public struct Point(u64, u64) has key, store, drop; + +// prefix abilities are also an option +public struct Point2 has key, store, drop ( + u64, + u64, +) + +// breaks on type arguments, but first +// tries on fields +public struct Container(u64, T) + +// will break on type arguments, not fields +public struct Container2(u64, T) + +// will reformat into single line +public struct Point( + u64, u64, +) + +// allows line comments, they break the list +public struct Point( + u64, // X + u64, // Y +) + +// allows block comments before types +/* what about this? */ public struct /* oh my god */ Point /* hello */ ( + /* X */ u64 /* post */, // trailing + /* Y */ u64 /* post okay */, // trailing +) // trailing for Point + +// allows block comments before types +public struct /* kill me */ Point( + /* Leading Block */ + u64, // trailing + /* Leading Block 2 */ + u64, // trailing +) // trailing diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.exp.move new file mode 100644 index 00000000000..32fba8a9491 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.exp.move @@ -0,0 +1,31 @@ +// options: +// printWidth: 50 +// useModuleLabel: true +// autoGroupImports: module + +module prettier::use_declaration; + +use beep::staked_iota::StakedIota; +use iota::coin::{ + Self as c, + Coin, + Coin as C, + very_long_function_name_very_long_function_name as short_name +}; +use iota::transfer_policy::{ + Self as policy, + TransferPolicy, + TransferPolicyCap, + TransferRequest, + TransferPolicyCap as cap, + Kek as KEK +}; + +public use fun my_custom_function_with_a_long_name as + TransferPolicyCap.very_long_function_name; + +friend has_been::here; + +// will break before `as` +public use fun my_custom_function_with_a_long_name as + TransferPolicyCap.very_long_function_name; diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.move b/external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.move new file mode 100644 index 00000000000..a89eacf3960 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/use_declaration.move @@ -0,0 +1,27 @@ +// options: +// printWidth: 50 +// useModuleLabel: true +// autoGroupImports: module + +module prettier::use_declaration; + +use iota::coin::Coin; +use iota::coin::Coin as C; +use iota::coin::{Self as c, Coin as C}; +use iota::coin::very_long_function_name_very_long_function_name as short_name; +use beep::staked_iota::StakedIota; + +use iota::transfer_policy::{Self as policy, TransferPolicy, TransferPolicyCap, TransferRequest}; +use iota::transfer_policy::TransferPolicyCap as cap; +use iota::{ + transfer_policy::{TransferPolicy, TransferPolicyCap, TransferRequest, Kek as KEK}, + transfer_policy::TransferPolicyCap as cap, +}; + +public use fun my_custom_function_with_a_long_name as TransferPolicyCap.very_long_function_name; + +friend has_been::here; + +// will break before `as` +public use fun my_custom_function_with_a_long_name + as TransferPolicyCap.very_long_function_name; diff --git a/external-crates/move/tooling/prettier-move/tests/run.test.ts b/external-crates/move/tooling/prettier-move/tests/run.test.ts new file mode 100644 index 00000000000..376362da4a4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/run.test.ts @@ -0,0 +1,123 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import * as assert from 'assert'; +import * as diff from 'diff'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as plugin from '../'; +import * as prettier from 'prettier'; +import { describe, it } from 'vitest'; +import { MoveOptions } from '../src/printer'; + +const UB = process.env['UB']; +const FILTER = process.env['FILTER']; +const OPTIONS_HEADER = '// options:'; + +// Read the current directory and run the tests in each subdirectory. +fs.readdirSync(__dirname).forEach((dir) => { + const dirname = path.join(__dirname, dir); + const isDir = fs.statSync(dirname).isDirectory(); + + if (isDir) { + const files = fs + .readdirSync(dirname) + .filter((f) => f.endsWith('.move') && !f.endsWith('.exp.move')) + .map((f) => path.join(dirname, f)) + .filter((f) => fs.statSync(f).isFile()) + .filter((f) => (FILTER ? f.includes(FILTER) : true)) + .map((path) => [path, fs.readFileSync(path).toString()]); + + if (files.length) { + describe(dir, () => { + files.forEach(([path, content]) => runSpec(path, content)); + }); + } + } + + // const matches = FILTER ? dir.includes(FILTER) : true; + // if (isDir && matches) { + // describe(dir, () => runSpec(dirname)); + // } +}); + +/** + * Runs the tests in the given directory. + */ +function runSpec(filepath: string, content: string) { + it(filepath.split('/').slice(-1)[0], async () => { + const expFile = filepath.replace('.move', '.exp.move'); + + // allows `// options:` header in the test file to set prettier options + // e.g. + // ``` + // // options: + // // printWidth: 80 + // // tabWidth: 2 + // // useModuleLabel: true + // ``` + let config = { + printWidth: 80, + tabWidth: 4, + wrapComments: false, + useModuleLabel: false, + autoGroupImports: 'module', + }; + + if (content.startsWith(OPTIONS_HEADER)) { + let lines = content.split('\n').slice(0, 10); + while (lines.length) { + let line = lines.shift(); + if (line?.startsWith('// ')) { + let value = + /(printWidth|wrapComments|tabWidth|useModuleLabel|autoGroupImports)\:\ (true|module|package|[0-9]+)/.exec( + line, + ); + if (value) { + let [_, key, val] = value || []; + switch (key) { + case 'wrapComments': + case 'useModuleLabel': + config[key] = val == 'true'; + break; + case 'autoGroupImports': + config[key] = val; + break; + case 'printWidth': + case 'tabWidth': + config[key] = parseInt(val); + break; + } + } + } + } + } + + const result = await prettier.format(content, { + // @ts-ignore + plugins: [plugin], + parser: 'move', + printWidth: config.printWidth, + tabWidth: config.tabWidth, + wrapComments: config.wrapComments, + useModuleLabel: config.useModuleLabel, + autoGroupImports: config.autoGroupImports as MoveOptions['autoGroupImports'], + }); + + // user asked to regenerate output + if (UB == '1') return fs.writeFileSync(expFile, result, 'utf8'); + if (!fs.existsSync(expFile)) { + return assert.fail(`\n${result}\nNo expected output file`); + } + + const expected = fs.readFileSync(expFile, { encoding: 'utf8' }); + + if (result != expected) { + const [snapshot, actual] = diff.diffLines(expected, result); + assert.fail( + `\nEXPECTED\n>${snapshot.value.split('\n').join('\n>')}\nGOT:\n>${actual.value.split('\n').join('\n >')}\nCurrent output does not match the expected one (run with UB=1 to save the current output)`, + ); + } + }); +} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/module_label.exp.move b/external-crates/move/tooling/prettier-move/tests/special-features/module_label.exp.move new file mode 100644 index 00000000000..0548545d370 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/module_label.exp.move @@ -0,0 +1,14 @@ +// options: +// printWidth: 80 +// useModuleLabel: true + +module prettier::module_label; + +use std::string::String; + +/// Hey there, this is the first time we meet. +public struct Hey {} + +public fun another_public_fun() {} + +fun ignored_vec() {} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/module_label.move b/external-crates/move/tooling/prettier-move/tests/special-features/module_label.move new file mode 100644 index 00000000000..443f145ede1 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/module_label.move @@ -0,0 +1,11 @@ +// options: +// printWidth: 80 +// useModuleLabel: true + +module prettier::module_label { + use std::string::String; + /// Hey there, this is the first time we meet. + public struct Hey {} + public fun another_public_fun() {} + fun ignored_vec() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.exp.move b/external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.exp.move new file mode 100644 index 00000000000..d92ceaa14ab --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.exp.move @@ -0,0 +1,21 @@ +// options: +// printWidth: 80 +// useModuleLabel: true + +module prettier::module_label { + /// Hey there, this is the first time we meet. + public struct Hey {} + + public fun another_public_fun() {} + + fun ignored_vec() {} +} + +module prettier::module_label_v2 { + /// Hey there, this is the first time we meet. + public struct Hey {} + + public fun another_public_fun() {} + + fun ignored_vec() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.move b/external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.move new file mode 100644 index 00000000000..a2fe4d6120e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/module_label_two_modules.move @@ -0,0 +1,17 @@ +// options: +// printWidth: 80 +// useModuleLabel: true + +module prettier::module_label { + /// Hey there, this is the first time we meet. + public struct Hey {} + public fun another_public_fun() {} + fun ignored_vec() {} +} + +module prettier::module_label_v2 { + /// Hey there, this is the first time we meet. + public struct Hey {} + public fun another_public_fun() {} + fun ignored_vec() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.exp.move b/external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.exp.move new file mode 100644 index 00000000000..ae6ed4a8ba4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.exp.move @@ -0,0 +1,17 @@ +// options: +// printWidth: 80 + +module prettier::prettier_ignore { + fun ignored_vec() { + // prettier-ignore + let a = vector[ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + ]; + } +} + +// prettier-ignore +module prettier::another { + } diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.move b/external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.move new file mode 100644 index 00000000000..ae6ed4a8ba4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/prettier_ignore.move @@ -0,0 +1,17 @@ +// options: +// printWidth: 80 + +module prettier::prettier_ignore { + fun ignored_vec() { + // prettier-ignore + let a = vector[ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + ]; + } +} + +// prettier-ignore +module prettier::another { + } diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/tab_width.exp.move b/external-crates/move/tooling/prettier-move/tests/special-features/tab_width.exp.move new file mode 100644 index 00000000000..9a4abc400a2 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/tab_width.exp.move @@ -0,0 +1,7 @@ +// options: +// printWidth: 80 +// tabWidth: 2 + +module prettier::tab_width { + fun move() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/tab_width.move b/external-crates/move/tooling/prettier-move/tests/special-features/tab_width.move new file mode 100644 index 00000000000..05d9baa3c80 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/tab_width.move @@ -0,0 +1,7 @@ +// options: +// printWidth: 80 +// tabWidth: 2 + +module prettier::tab_width { + fun move() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.exp.move b/external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.exp.move new file mode 100644 index 00000000000..91e36752b2e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.exp.move @@ -0,0 +1,44 @@ +// options: +// printWidth: 40 +// tabWidth: 4 +// wrapComments: true +// useModuleLabel: true + +// Lorem Ipsum is simply dummy text of +// the printing and typesetting +// industry. Lorem Ipsum has been the +// industry's standard dummy text ever +// since the 1500s, when an unknown +// printer took a galley of type and +// scrambled it to make a type specimen +// book. It has survived not only five +// centuries, but also the leap into +// electronic typesetting, remaining +// essentially unchanged. It was +// popularised in the 1960s with the +// release of Letraset sheets containing +// Lorem Ipsum passages, and more +// recently with desktop publishing +// software like Aldus PageMaker +// including versions of Lorem Ipsum. +module prettier::wrap_comments; + +// It is a long established fact that a +// reader will be distracted by the +// readable content of a page when +// looking at its layout. The point of +// using Lorem Ipsum is that it has a +// more-or-less normal distribution of +// letters, as opposed to using 'Content +// here, content here', making it look +// like readable English. Many desktop +// publishing packages and web page +// editors now use Lorem Ipsum as their +// default model text, and a search for +// 'lorem ipsum' will uncover many web +// sites still in their infancy. Various +// versions have evolved over the years, +// sometimes by accident, sometimes on +// purpose (injected humour and the +// like). +fun move() {} diff --git a/external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.move b/external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.move new file mode 100644 index 00000000000..7fa61c9d734 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/special-features/wrap_comments.move @@ -0,0 +1,12 @@ +// options: +// printWidth: 40 +// tabWidth: 4 +// wrapComments: true +// useModuleLabel: true + + +// Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. +module prettier::wrap_comments { + // It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). + fun move() {} +} diff --git a/external-crates/move/tooling/prettier-move/tree-sitter-move.wasm b/external-crates/move/tooling/prettier-move/tree-sitter-move.wasm new file mode 100755 index 0000000000000000000000000000000000000000..c0afd7dc456ee0a73640090ad4d8b45a9fcbaae6 GIT binary patch literal 344314 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 TgeUeZHY Date: Fri, 20 Dec 2024 15:00:17 +0200 Subject: [PATCH 2/5] fix: license headers --- .../move/crates/move-binary-format/src/compatibility_mode.rs | 4 ++++ .../crates/move-core-types/src/unit_tests/parsing_test.rs | 4 ++++ .../move/crates/move-vm-runtime/src/tracing2/mod.rs | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs b/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs index d273f5a3d39..fd3e2cb91db 100644 --- a/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs +++ b/external-crates/move/crates/move-binary-format/src/compatibility_mode.rs @@ -1,3 +1,7 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + use crate::compatibility::Compatibility; use crate::file_format::Visibility; use crate::normalized::{Enum, Function, Struct}; diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs index 2d69de0be29..bb50669ad45 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs @@ -1,3 +1,7 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + use crate::{ account_address::AccountAddress, identifier::Identifier, diff --git a/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs b/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs index 408ec299ff4..37571959014 100644 --- a/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs +++ b/external-crates/move/crates/move-vm-runtime/src/tracing2/mod.rs @@ -1,3 +1,7 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + pub(crate) mod tracer; #[cfg(feature = "tracing")] From b69133571f70f53e3701c227f82abfb87b08fd4a Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Mon, 23 Dec 2024 12:32:36 +0200 Subject: [PATCH 3/5] fix(move-trace-format): updated authors --- external-crates/move/crates/move-trace-format/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external-crates/move/crates/move-trace-format/Cargo.toml b/external-crates/move/crates/move-trace-format/Cargo.toml index 1df80526546..cf562e792b9 100644 --- a/external-crates/move/crates/move-trace-format/Cargo.toml +++ b/external-crates/move/crates/move-trace-format/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "move-trace-format" version = "0.0.1" -authors = ["Move Core Contributors"] +authors = ["IOTA Foundation "] edition = "2021" license = "Apache-2.0" description = "Move Trace Format" From 1ec4282e951760797b82fe8ec0a59f2d23dd7a64 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Mon, 23 Dec 2024 12:18:23 +0200 Subject: [PATCH 4/5] fix(move-analyzer): several fixes for SVCode extension after update --- .../move-analyzer/editors/code/package.json | 2 +- .../editors/code/tests/lsp.test.ts | 4 ++-- .../editors/code/tests/runTests.ts | 21 ++++++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/external-crates/move/crates/move-analyzer/editors/code/package.json b/external-crates/move/crates/move-analyzer/editors/code/package.json index 976eb5edfcd..4a96ad5e301 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/package.json +++ b/external-crates/move/crates/move-analyzer/editors/code/package.json @@ -159,7 +159,7 @@ }, "extensionDependencies": [ "damirka.move-syntax", - "iota.move-trace-debug" + "mysten.move-trace-debug" ], "dependencies": { "semver": "^7.6.2", diff --git a/external-crates/move/crates/move-analyzer/editors/code/tests/lsp.test.ts b/external-crates/move/crates/move-analyzer/editors/code/tests/lsp.test.ts index f824eb30d98..47db4f8f456 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/tests/lsp.test.ts +++ b/external-crates/move/crates/move-analyzer/editors/code/tests/lsp.test.ts @@ -103,7 +103,7 @@ Mocha.suite('LSP', () => { assert.ok(hoverResult); assert.deepStrictEqual((hoverResult.contents as MarkupContent).value, // eslint-disable-next-line max-len - '```rust\nfun Symbols::M2::other_doc_struct(): Symbols::M3::OtherDocStruct\n```\n\nThis is a multiline docstring\n\nThis docstring has empty lines.\n\nIt uses the ** format instead of ///\n\n'); + '```rust\nfun Symbols::M2::other_doc_struct(): Symbols::M3::OtherDocStruct\n```\n\n This is a multiline docstring\n\n This docstring has empty lines.\n\n It uses the ** format instead of ///\n '); }); @@ -143,7 +143,7 @@ Mocha.suite('LSP', () => { assert.ok(hoverResult); assert.deepStrictEqual((hoverResult.contents as MarkupContent).value, // eslint-disable-next-line max-len - '```rust\nstruct Symbols::M3::OtherDocStruct has drop {\n\tsome_field: u64\n}\n```\nDocumented struct in another module\n'); + '```rust\nstruct Symbols::M3::OtherDocStruct has drop {\n\tsome_field: u64\n}\n```\n Documented struct in another module'); }); Mocha.test('textDocument/completion', async () => { diff --git a/external-crates/move/crates/move-analyzer/editors/code/tests/runTests.ts b/external-crates/move/crates/move-analyzer/editors/code/tests/runTests.ts index a5a3c91bdbe..f814ee3cb7c 100644 --- a/external-crates/move/crates/move-analyzer/editors/code/tests/runTests.ts +++ b/external-crates/move/crates/move-analyzer/editors/code/tests/runTests.ts @@ -51,10 +51,21 @@ async function runVSCodeTest(vscodeVersion: string): Promise { const vscodeExecutablePath = await downloadAndUnzipVSCode(vscodeVersion); const [cli, ...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath); const newCli = cli ?? 'code'; - cp.spawnSync(newCli, [...args, '--install-extension', 'damirka.move-syntax', '--force'], { - encoding: 'utf-8', - stdio: 'inherit', - }); + cp.spawnSync( + newCli, + [ + ...args, + '--install-extension', + 'damirka.move-syntax', + '--install-extension', + 'mysten.move-trace-debug', + '--force', + ], + { + encoding: 'utf-8', + stdio: 'inherit', + }, + ); // Because the default vscode userDataDir is too long, // v1.69.2 will report an error when running test. @@ -78,7 +89,7 @@ async function runVSCodeTest(vscodeVersion: string): Promise { } async function main(): Promise { - await runVSCodeTest('1.82.0'); // Test with vscode v1.82.0, the minimal supported version + await runVSCodeTest('1.92.0'); // Test with vscode v1.92.0, the minimal supported version } void main(); From 7582996e592d6b374a438518a373dabcd8aaf6b5 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Fri, 20 Dec 2024 14:53:32 +0200 Subject: [PATCH 5/5] fix: fix workspace build after the external crates updating --- Cargo.lock | 17 ++++- .../src/unit_tests/authority_tests.rs | 21 ++++-- .../move_package_management_tests.rs | 4 +- .../unit_tests/move_package_publish_tests.rs | 16 ++-- .../unit_tests/subscription_handler_tests.rs | 14 ++-- .../iota-framework/packages_compiled/bridge | Bin 19740 -> 19718 bytes .../packages_compiled/iota-framework | Bin 70097 -> 70092 bytes .../packages_compiled/iota-system | Bin 42215 -> 42221 bytes .../packages_compiled/move-stdlib | Bin 11177 -> 11152 bytes crates/iota-framework/src/lib.rs | 23 +----- .../tests/packages/modules.exp | 2 +- .../tests/packages/types.exp | 2 +- .../iota-graphql-rpc/src/types/move_type.rs | 4 +- .../iota-graphql-rpc/src/types/move_value.rs | 8 +- .../src/handlers/checkpoint_handler.rs | 2 +- crates/iota-indexer/src/models/objects.rs | 2 +- crates/iota-json/src/lib.rs | 56 +++++++------- crates/iota-json/src/tests.rs | 50 ++++++------ crates/iota-move-build/src/lib.rs | 21 +++--- crates/iota-node/src/main.rs | 4 +- crates/iota-open-rpc/src/examples.rs | 2 +- crates/iota-package-resolver/src/lib.rs | 10 +-- crates/iota-replay/src/data_fetcher.rs | 4 +- .../iota-source-validation/src/toolchain.rs | 2 +- .../src/args.rs | 8 +- .../parser.rs | 11 ++- .../token.rs | 3 +- .../src/test_adapter.rs | 5 +- crates/iota-types/Cargo.toml | 7 +- crates/iota-types/src/balance.rs | 4 +- crates/iota-types/src/coin.rs | 8 +- crates/iota-types/src/id.rs | 10 +-- crates/iota-types/src/layout_resolver.rs | 2 +- crates/iota-types/src/lib.rs | 12 +-- crates/iota-types/src/object.rs | 2 +- .../src/object/balance_traversal.rs | 21 ++++-- .../iota-types/src/object/bounded_visitor.rs | 71 ++++++++++++++---- .../tests__constant_name_change.snap | 20 +---- .../tests__constant_value_changed.snap | 20 +---- .../tests__friend_entry_changed.snap | 26 +------ .../tests__friend_function_change.snap | 26 +------ .../tests__large_package_equality_check.snap | 20 +---- ...e_package_equality_check_alpha_rename.snap | 20 +---- ..._package_equality_check_local_shuffle.snap | 20 +---- .../tests__large_package_inclusion_check.snap | 20 +---- ...kage_invalid_equality_inclusion_check.snap | 20 +---- ...sts__private_entry_and_friend_changes.snap | 28 ++----- ...ests__private_entry_fun_entry_removed.snap | 26 +------ .../tests__public_fun_param_alpha_rename.snap | 20 +---- .../tests__public_fun_param_permute.snap | 20 +---- .../snapshots/tests__public_fun_rename.snap | 20 +---- .../tests__struct_field_name_change.snap | 20 +---- .../tests__struct_field_reorder.snap | 20 +---- ...__struct_field_reorder_no_name_change.snap | 20 +---- .../tests__struct_layout_change.snap | 20 +---- .../snapshots/tests__struct_name_change.snap | 20 +---- .../tests/tests.rs | 46 ++---------- crates/iota/Cargo.toml | 2 +- crates/iota/src/client_commands.rs | 6 +- crates/iota/src/client_ptb/ast.rs | 10 ++- crates/iota/src/client_ptb/builder.rs | 12 +-- crates/iota/src/client_ptb/parser.rs | 2 +- crates/iota/src/unit_tests/profiler_tests.rs | 26 +++---- crates/iota/tests/cli_tests.rs | 5 +- docs/content/developer/dev-cheat-sheet.mdx | 2 +- docs/content/references/cli.mdx | 4 +- docs/content/references/cli/client.mdx | 4 +- iota-execution/Cargo.toml | 12 +-- iota-execution/latest/iota-adapter/Cargo.toml | 11 ++- .../latest/iota-adapter/src/adapter.rs | 7 +- .../src/programmable_transactions/context.rs | 2 +- .../programmable_transactions/execution.rs | 11 +-- .../src/object_runtime/mod.rs | 15 +++- 73 files changed, 385 insertions(+), 626 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9aeac640356..785ef0803c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5762,6 +5762,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "inline_colorization" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1804bdb6a9784758b200007273a8b84e2b0b0b97a8f1e18e763eceb3e9f98a" + [[package]] name = "inotify" version = "0.9.6" @@ -9513,6 +9519,7 @@ dependencies = [ "lsp-types", "move-command-line-common", "move-compiler", + "move-core-types", "move-ir-types", "move-package", "move-symbol-pool", @@ -9557,6 +9564,7 @@ dependencies = [ "move-ir-types", "move-symbol-pool", "serde", + "serde_json", ] [[package]] @@ -9564,6 +9572,7 @@ name = "move-bytecode-utils" version = "0.1.0" dependencies = [ "anyhow", + "indexmap 2.5.0", "move-binary-format", "move-core-types", "petgraph 0.5.1", @@ -9684,11 +9693,13 @@ dependencies = [ "move-symbol-pool", "once_cell", "petgraph 0.5.1", + "rayon", "regex", "serde", "serde_json", "similar", "stacker", + "tempfile", "vfs", ] @@ -9713,6 +9724,7 @@ dependencies = [ "ref-cast", "serde", "serde_bytes", + "serde_with", "thiserror", "uint", ] @@ -9726,6 +9738,7 @@ dependencies = [ "clap", "codespan", "colored", + "indexmap 2.5.0", "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", @@ -9743,8 +9756,8 @@ dependencies = [ "anyhow", "bcs", "clap", - "colored", "hex", + "inline_colorization", "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", @@ -10035,6 +10048,7 @@ dependencies = [ "move-ir-types", "move-stdlib-natives", "move-symbol-pool", + "move-trace-format", "move-vm-profiler", "move-vm-runtime", "move-vm-test-utils", @@ -10073,6 +10087,7 @@ dependencies = [ "move-binary-format", "move-bytecode-verifier", "move-core-types", + "move-trace-format", "move-vm-config", "move-vm-profiler", "move-vm-types", diff --git a/crates/iota-core/src/unit_tests/authority_tests.rs b/crates/iota-core/src/unit_tests/authority_tests.rs index 208a4631bf5..19624c399ac 100644 --- a/crates/iota-core/src/unit_tests/authority_tests.rs +++ b/crates/iota-core/src/unit_tests/authority_tests.rs @@ -3,7 +3,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::{collections::HashSet, convert::TryInto, env, fs}; +use std::{collections::HashSet, convert::TryInto, env, fs, str::FromStr}; use bcs; use fastcrypto::traits::KeyPair; @@ -47,7 +47,6 @@ use move_core_types::{ ident_str, identifier::{IdentStr, Identifier}, language_storage::{StructTag, TypeTag}, - parser::parse_type_tag, }; use rand::{ Rng, SeedableRng, @@ -3676,7 +3675,7 @@ async fn test_dynamic_field_struct_name_parsing() { assert!(matches!(fields[0].type_, DynamicFieldType::DynamicField)); assert_eq!(json!({"name_str": "Test Name"}), fields[0].name.value); assert_eq!( - parse_type_tag("0x0::object_basics::Name").unwrap(), + TypeTag::from_str("0x0::object_basics::Name").unwrap(), fields[0].name.type_ ) } @@ -3688,7 +3687,10 @@ async fn test_dynamic_field_bytearray_name_parsing() { assert_eq!(fields.len(), 1); assert!(matches!(fields[0].type_, DynamicFieldType::DynamicField)); - assert_eq!(parse_type_tag("vector").unwrap(), fields[0].name.type_); + assert_eq!( + TypeTag::from_str("vector").unwrap(), + fields[0].name.type_ + ); assert_eq!(json!("Test Name".as_bytes()), fields[0].name.value); } @@ -3699,7 +3701,7 @@ async fn test_dynamic_field_address_name_parsing() { assert_eq!(fields.len(), 1); assert!(matches!(fields[0].type_, DynamicFieldType::DynamicField)); - assert_eq!(parse_type_tag("address").unwrap(), fields[0].name.type_); + assert_eq!(TypeTag::from_str("address").unwrap(), fields[0].name.type_); assert_eq!(json!(sender), fields[0].name.value); } @@ -3711,7 +3713,7 @@ async fn test_dynamic_object_field_struct_name_parsing() { assert!(matches!(fields[0].type_, DynamicFieldType::DynamicObject)); assert_eq!(json!({"name_str": "Test Name"}), fields[0].name.value); assert_eq!( - parse_type_tag("0x0::object_basics::Name").unwrap(), + TypeTag::from_str("0x0::object_basics::Name").unwrap(), fields[0].name.type_ ) } @@ -3723,7 +3725,10 @@ async fn test_dynamic_object_field_bytearray_name_parsing() { assert_eq!(fields.len(), 1); assert!(matches!(fields[0].type_, DynamicFieldType::DynamicObject)); - assert_eq!(parse_type_tag("vector").unwrap(), fields[0].name.type_); + assert_eq!( + TypeTag::from_str("vector").unwrap(), + fields[0].name.type_ + ); assert_eq!(json!("Test Name".as_bytes()), fields[0].name.value); } @@ -3734,7 +3739,7 @@ async fn test_dynamic_object_field_address_name_parsing() { assert_eq!(fields.len(), 1); assert!(matches!(fields[0].type_, DynamicFieldType::DynamicObject)); - assert_eq!(parse_type_tag("address").unwrap(), fields[0].name.type_); + assert_eq!(TypeTag::from_str("address").unwrap(), fields[0].name.type_); assert_eq!(json!(sender), fields[0].name.value); } diff --git a/crates/iota-core/src/unit_tests/move_package_management_tests.rs b/crates/iota-core/src/unit_tests/move_package_management_tests.rs index 8c5d0a6b170..ce0faadb336 100644 --- a/crates/iota-core/src/unit_tests/move_package_management_tests.rs +++ b/crates/iota-core/src/unit_tests/move_package_management_tests.rs @@ -52,13 +52,13 @@ async fn test_manage_package_update() { # @generated by Move, please check-in and do not edit manually. [move] - version = 2 + version = 3 manifest_digest = "919A5B078B47AD46674F36E1605578927D5BC4536A7646D78D1320A25DDD57CC" deps_digest = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" [move.toolchain-version] compiler-version = "0.0.1" - edition = "2024.beta" + edition = "2024" flavor = "iota" [env] diff --git a/crates/iota-core/src/unit_tests/move_package_publish_tests.rs b/crates/iota-core/src/unit_tests/move_package_publish_tests.rs index 6edfad49565..5a896876bbb 100644 --- a/crates/iota-core/src/unit_tests/move_package_publish_tests.rs +++ b/crates/iota-core/src/unit_tests/move_package_publish_tests.rs @@ -205,32 +205,32 @@ async fn test_generate_lock_file() { # @generated by Move, please check-in and do not edit manually. [move] - version = 2 + version = 3 manifest_digest = "78ED00C216B5A73463BD935B7AD1AB6CAF8ECA9ACD7FFCC19F3462EBD1D83EC3" deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" dependencies = [ - { name = "Examples" }, - { name = "Iota" }, + { id = "Examples", name = "Examples" }, + { id = "Iota", name = "Iota" }, ] [[move.package]] - name = "Examples" + id = "Examples" source = { local = "../object_basics" } dependencies = [ - { name = "Iota" }, + { id = "Iota", name = "Iota" }, ] [[move.package]] - name = "Iota" + id = "Iota" source = { local = "../../../../../iota-framework/packages/iota-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [[move.package]] - name = "MoveStdlib" + id = "MoveStdlib" source = { local = "../../../../../iota-framework/packages/move-stdlib" } [move.toolchain-version] diff --git a/crates/iota-core/src/unit_tests/subscription_handler_tests.rs b/crates/iota-core/src/unit_tests/subscription_handler_tests.rs index c2015b9d508..65678f92bca 100644 --- a/crates/iota-core/src/unit_tests/subscription_handler_tests.rs +++ b/crates/iota-core/src/unit_tests/subscription_handler_tests.rs @@ -82,11 +82,11 @@ impl TestEvent { fn layout() -> MoveStructLayout { MoveStructLayout { type_: Self::type_(), - fields: vec![ + fields: Box::new(vec![ MoveFieldLayout::new(ident_str!("creator").to_owned(), MoveTypeLayout::Address), MoveFieldLayout::new( ident_str!("name").to_owned(), - MoveTypeLayout::Struct(UTF8String::layout()), + MoveTypeLayout::Struct(Box::new(UTF8String::layout())), ), MoveFieldLayout::new( ident_str!("data").to_owned(), @@ -94,9 +94,11 @@ impl TestEvent { ), MoveFieldLayout::new( ident_str!("coins").to_owned(), - MoveTypeLayout::Vector(Box::new(MoveTypeLayout::Struct(GasCoin::layout()))), + MoveTypeLayout::Vector(Box::new(MoveTypeLayout::Struct(Box::new( + GasCoin::layout(), + )))), ), - ], + ]), } } } @@ -128,10 +130,10 @@ impl UTF8String { fn layout() -> MoveStructLayout { MoveStructLayout { type_: Self::type_(), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("bytes").to_owned(), MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - )], + )]), } } } diff --git a/crates/iota-framework/packages_compiled/bridge b/crates/iota-framework/packages_compiled/bridge index 79a3989d1ddfadf4aae635c9fa84280a0a796b3e..81161c0986f1ffa98f9627e9ff12e61d1be9b182 100644 GIT binary patch delta 167 zcmbO;i?MAMor8ywRUOD?RAk|Uv6&QE xL}6@ZMHU$tn?;dD8O-KpU}sh2VdQ3H(PGt^+|3ip$T9gLj|3yf=3hKY4gg198$SR5 delta 209 zcmWm8y-EW?6o%pRyE8lI7*uT3q?j#4Oc4|X%U~s9n<`gfp_gElZo5TBXXz8C@h(AtEFn6om5|!Fr=&B=wpxM<_ZuGW&^~qVCtP~!D^HJ^8qaNP_m1L-wYj4IoA}JeR diff --git a/crates/iota-framework/packages_compiled/iota-framework b/crates/iota-framework/packages_compiled/iota-framework index b1dfb3584d4d47b710fce677f615890408a6f5f1..0585fe92a8cc91401961f2b0b1fe299b76b187b5 100644 GIT binary patch delta 1019 zcmZ`%y^9n{6z^B{s=B(WcBXe{re=0mXQy|jyJz;p4m`a@SlAgqVFOWFP&|+`F!25W zGffN*?%1T#y9L=q^o|oIHV};D5DW|iLBv2|1HJGt@r~ntBoC8I4q+@y__WIfqO#mXJNsH5D{-?Rs;h%F``~nm@h?$0%C72WCM0tWOqDT}IoHju$48$U_Oe`A! z6F~GmYMB4EU0jPdOfcE7bd507qF>QrztYBv3Bd?ZmWxZf)(*DD){*E18GIX7X*F_b zbS=IsP*RwQq7E4jz`CC~MIcrOi4$13Y zmeTp>tmWTlm9MNIT+F8lPv;4`>M7@M=B+W=%nxJsBgOeo-n6cb$Am2f8c63=K3H)E z_9L($q(NpV)*}zWu-$Yum4Gs){H4`e$ENT6rEZ&^yVXt7RBUKjidSrc>qbJ!^wT}b zy2S}&@MP*AcautL)ZU4+O4KQ;|GGy>C+(ev)c?|(2RGd8{k<}SqD5MfMT1nlo?+uQ z;D!%3u0Owh{EzCrLpx^l(FTGkHr3z@PXKqIB>snY5WeR3g}NK9$*0i`{Xn72>=;4&#@18^k5l#R4xLRN|AfT9tXtkZ+mQ M3^QtY^ut!~3;7FtSO5S3 delta 1025 zcmYjP&5K+`5P#KO-Thv7&&=DMH`6n_$?UwHc^@+yvm+X_1QvG2O;8pOA=yJzh1BL{%#muq+UJMo4NVx}QxDOO13r1I1`=H}W)c)>b2}DC!{3$p1X=`p0>Fu5A+EDB8r&7b&`A*ZJ#3_fWZAoW$ZR)%l?4 zSjvA!*lM7GaDFK!Th74C3M>d|kQu6V^Bx#>)UKvsQ^(Z5v|8)fjGez!_9)$rGR<E;^;$-#*yW;SR8!7^KJ@!@xXPoOHE!C#<$<6n#L(`ZM2 zAAO|n>8|}je;!qSonHCl8#+#y;-Bv!T=O41Zr=*2EwGV}VwNlxm*N^3_%Q=jkvG=1+;{uq z`)0nqnc28x{Cdea{f?MjnLSzG1PdWVF=`sk{e?%*5VCHLm>0~=f_=L9RoOY#Shjv@ zoWbsE+g34scl(b6-t)U-|C98Zc-XjOUmdwG7dPQ9Skui3#e~S z7yoAfpTy=YFl;+**R%a$GH))bpLW}&wiqUb`^@{3eXTt|VU`)j4!M}eD8oqNH(Rl*U$EAi z)azSSV=YTn_(wlfb)Pl*^g`nzS1gws@4On)KAI`X8$G zp3P$|%T#!w2SH6*19hxqS!#fh+#DUjOKE%TuL3@hHh1p23!h3JI#eILVcF-{^@g)P zzHI$7e#HHG;xT%4a>MsNo*VZ!($^2&Yhjjt_sAQSAn*tTv4>scJ29nY&xCTaax@;O zFf(S_0GW37c!6AF;ll} z_GxAZf;(FuQ82Hl-CW!f0FbY-c@^8mHi-0Q=a|4hB+nebZSZ`-{>=Koc7E}etuI;N zUSop(&fd4YwwTfV$TSoetZu`v=PgDp4DdMxGjvLTGSj2 zqk1?PR-;C^b7pd8`>u5Q)mL!(dGfS1M~CFfkvwilv`JmYSRE29Z;A>a!2t{2l(*sz by~Bzv5ykP8}&j|(So z)T|m0fG`^31|=90B^qPW#Q2B_DiT+tsL06}iI@l)0tfLGB>vTvnDO8wQ&aPQshYp4 z{;s*Op#QX>zj-*C`g`(F{TDPfO%qIO>8*9f{YN=}5r*Jn*v+j|&Q~S-aAUJM*F4JH zw-@haVxc$h@vcl{!O{Fov_)UKuCBSe+1hChAM6{^#KSXvO!I29Gt~C4Uq$WMY)I|+ zY`!g-W2VLAt8*!Rs@W*I|JUT(%T>|d;X5}CTVX#(-z_>K0M8Kt20ZmqMM9`JBE*m{ z_CZA=XgMOnh%fa`6^UWQ5i!Pm%(qme1mlhxTk))* zpWgv@$?w*nE3BxWZ-h;quy2i(`e`(aX}+;<18?8D-*C0i46Vdv#Yc;Kw$PzcL~Rwd zla|m?=XG0nFi?n4B1k;+_=qj4FkXnK#3QLq8 zmS|$L&G(TRFt1F_n2;H0@PkAgUQtvohLtl4A?L3X0Z?tpy{i^fB?1Kg4v`5TbW@GU zM3bK&vfv9vH94vsO0&@7r^syhw#z~}qm4E{L*&3YMJj!fIl@7QUm$YfvLcneN93Z* z{~|(oLN8KO*$0^`5RpHv+d{w|qV~V(M`Qv8e~!$D18SIBSxn@k&kqp=a70m&eke&6 z^&3PXywy!|LRsDK5k>HkuC~3%MrJR|{1d%xix|FCmJ}w_mj!>ChLzwuMdgBI`m*wW zAWGn8Mb(1jkI6^iB2fyzcauyp#gtzmD#M&n%2?*R4AdAh+OY~eZ=ie< zYABCZ&RfAs#~K-8x8*BF{xsO_`S9|I>n4v(ciliM^_BM-FR)9%pRp$4xb>T9z3czj zuwPoX*}S@Jn|uD+2gK>obAk8%+GWA{{NTN}n0mnSvs?G4N$PP-GmnliurnbN4>0NM z-kJ53eaL*;cmsh9U3WC<6P^e~wR2|YFjfg^8G+_iJL#hX?Z}sr64tO(p`7U`f-t3J zYSBZ~jZ&=ANqK&d`DNkB36bU;ji%)f$H-k1t>|tM(+GODwJ?-TlwgEqG^ra$8_>rJ zdKkuf7C1DjB&T;0c?)aWo%C+;W3m#h%vUiPq8j{=IYrrh#%NFN|Db@A6eO3W_ceoW znB@#&oJ0HZXyW^{Ym1wD^G4&IIh{_w4p;RPhIQP0&9X0go6VDc;-2**@vHx;=^aST z;N|?-vx2d#^ZDK-D{c^)+q|A>?vhbobC-_|Y3|C=Ky$~a!J)N7ng~`;FikX8(_e{S zThnRnD?>J#^-ktf`}Q!MvHa7{4s&Y!8d{o0)uTm&JfJ?4&l{sFMu*5L?#CX~q7YdW ew&+UfRVC%ftE4kGKf_ja7UoCTRDOB>59c3ADBlVI diff --git a/crates/iota-framework/packages_compiled/move-stdlib b/crates/iota-framework/packages_compiled/move-stdlib index 63c3ce2b8c799f4a9f96a890260792a3017ba0cb..c198d17aaa31b0bbf2f7cea83d14918ff823d705 100644 GIT binary patch delta 648 zcmb8sze`*}5C`x#yR$#u&b+;QK2ZoJxxL^Ws9sCk52GP@lNn>m0S{CM_KyqKe;o-jIGDp)x| zY8oFqaAF!CIdqVFoGf>ddzR{H8W)n-R4qa<&?fA@ZynFyJ;ZU4XrZn23u^hb*?}I| zZ=#_`;;kD>&6o0%%D#73+plH|&`vnv zQZ{703HT&-Z5%7oUIm;yS7Ogi*5Nwkz8-KbzNi_`o@(9) zd=qe!uu-BH&SFq7z{md%r>%83ycE fhLM%u?g15AMWzFjIx7{@|2kMEA_ju)`OM8dT^vZ- delta 673 zcmYk3ziU)M5Xax_o7vsBGq-o|e&=$@%O>Uy)2QH&PDsScCWR6$EGz;F{sD@`VWAOh zlq=GxL9L<);$b1_1hq=3m9>rd4_LV`a&WWT%;z&KvwWXy?Qgw*xP0b=ecAubI!O|S z#4794_I?>T-pRwtFpq8KbBCY(L94zOM62Rne<+9p5$w@5{?euy> zj8kk@vFgC7RY@t&B;^#lPCLlGAoVgqMhp?C2#8iPAtoHq8f!2xWIet$cz0qan=a-c z(MsFYpQeqQ<_$ap`&BLJU+RYYmTEanA5rD|_~P)&xxy(ZD?UAYXSyQ|akqG<2PR*J z*I-n*LaN3JaMeS=s+AgbBJ(B_VechKjceGqlGCxsE5=EOE4~vX=Nyk)sne;**|5wp z`?(->uH#uN4LTpWGa@~9z89py4ZL8bNtYteOhx878~OPlO>W|*l@?u%!Wu7qw!R;v z#Vx#UrA^zB8&j19Hhv*Uo7;Gs3$W6q18~K<)n$}r4e+ijrcJV8n+Ad`(!ER;c@ZDP zVGaK$kE9v}QM3b@C|3Bi)M`ejA!a#_whZ%mY10{tAqKk_ZJF$TX>rCL8jv0moltqFGCqyW`hufBpejXGg{W diff --git a/crates/iota-framework/src/lib.rs b/crates/iota-framework/src/lib.rs index 1fb3d8da931..f4b68ba7ed8 100644 --- a/crates/iota-framework/src/lib.rs +++ b/crates/iota-framework/src/lib.rs @@ -14,10 +14,7 @@ use iota_types::{ storage::ObjectStore, }; use move_binary_format::{ - CompiledModule, - binary_config::BinaryConfig, - compatibility::Compatibility, - file_format::{Ability, AbilitySet}, + CompiledModule, binary_config::BinaryConfig, compatibility::Compatibility, }; use move_core_types::gas_algebra::InternalGas; use once_cell::sync::Lazy; @@ -222,23 +219,7 @@ pub async fn compare_system_package( return Some(cur_ref); } - let compatibility = Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: false, - // Checking `entry` linkage is required because system packages are updated in-place, and a - // transaction that was rolled back to make way for reconfiguration should still be runnable - // after a reconfiguration that upgraded the framework. - // - // A transaction that calls a system function that was previously `entry` and is now private - // will fail because its entrypoint became no longer callable. A transaction that calls a - // system function that was previously `public entry` and is now just `public` could also - // fail if one of its mutable inputs was being used in another private `entry` function. - check_private_entry_linking: true, - disallowed_new_abilities: AbilitySet::singleton(Ability::Key), - disallow_change_datatype_type_params: true, - disallow_new_variants: true, - }; + let compatibility = Compatibility::framework_upgrade_check(); let new_pkg = new_object .data diff --git a/crates/iota-graphql-e2e-tests/tests/packages/modules.exp b/crates/iota-graphql-e2e-tests/tests/packages/modules.exp index 9351971dcea..cb9814fc1e0 100644 --- a/crates/iota-graphql-e2e-tests/tests/packages/modules.exp +++ b/crates/iota-graphql-e2e-tests/tests/packages/modules.exp @@ -31,7 +31,7 @@ Response: { }, "fileFormatVersion": 6, "bytes": "oRzrCwYAAAAIAQAGAgYKAxARBCEEBSUfB0QkCGhADKgBMAAGAQMBBQEADAEAAQIBAgAABAABAQIAAgIBAAEHBQEBAAIEAAYCAwYLAAEJAAEDAQYLAAEIAQABCQABBgsAAQkAAQgBBENvaW4ESU9UQQNiYXIEY29pbgNmb28EaW90YQFtBXZhbHVlOjkcKUU8LgevHrC+/VC5A/DMFgnfiCbhp50+Hs6rZIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABAAADBQsBOAALABYCAQEAAAMIBioAAAAAAAAACgA4AQYrAAAAAAAAAAsAOAEYAgA=", - "disassembly": "// Move bytecode v6\nmodule 3a391c29453c2e07af1eb0befd50b903f0cc1609df8826e1a79d3e1eceab6481.m {\nuse 0000000000000000000000000000000000000000000000000000000000000002::coin;\nuse 0000000000000000000000000000000000000000000000000000000000000002::iota;\n\n\n\n\n\n\npublic foo(Arg0: u64, Arg1: &Coin): u64 {\nB0:\n\t0: MoveLoc[1](Arg1: &Coin)\n\t1: Call coin::value(&Coin): u64\n\t2: MoveLoc[0](Arg0: u64)\n\t3: Add\n\t4: Ret\n\n}\npublic bar(Arg0: &Coin): u64 {\nB0:\n\t0: LdU64(42)\n\t1: CopyLoc[0](Arg0: &Coin)\n\t2: Call foo(u64, &Coin): u64\n\t3: LdU64(43)\n\t4: MoveLoc[0](Arg0: &Coin)\n\t5: Call foo(u64, &Coin): u64\n\t6: Mul\n\t7: Ret\n\n}\n}" + "disassembly": "// Move bytecode v6\nmodule 3a391c29453c2e07af1eb0befd50b903f0cc1609df8826e1a79d3e1eceab6481.m {\nuse 0000000000000000000000000000000000000000000000000000000000000002::coin;\nuse 0000000000000000000000000000000000000000000000000000000000000002::iota;\n\npublic foo(Arg0: u64, Arg1: &Coin): u64 {\nB0:\n\t0: MoveLoc[1](Arg1: &Coin)\n\t1: Call coin::value(&Coin): u64\n\t2: MoveLoc[0](Arg0: u64)\n\t3: Add\n\t4: Ret\n}\n\npublic bar(Arg0: &Coin): u64 {\nB0:\n\t0: LdU64(42)\n\t1: CopyLoc[0](Arg0: &Coin)\n\t2: Call foo(u64, &Coin): u64\n\t3: LdU64(43)\n\t4: MoveLoc[0](Arg0: &Coin)\n\t5: Call foo(u64, &Coin): u64\n\t6: Mul\n\t7: Ret\n}\n\n}\n" } } } diff --git a/crates/iota-graphql-e2e-tests/tests/packages/types.exp b/crates/iota-graphql-e2e-tests/tests/packages/types.exp index f8cbbd79690..90d7942421a 100644 --- a/crates/iota-graphql-e2e-tests/tests/packages/types.exp +++ b/crates/iota-graphql-e2e-tests/tests/packages/types.exp @@ -141,7 +141,7 @@ Response: { "data": null, "errors": [ { - "message": "Bad type: unexpected token Name(\"not_a_type\"), expected type tag", + "message": "Bad type: unexpected end of tokens", "locations": [ { "line": 3, diff --git a/crates/iota-graphql-rpc/src/types/move_type.rs b/crates/iota-graphql-rpc/src/types/move_type.rs index 44227f90de5..758f06b9352 100644 --- a/crates/iota-graphql-rpc/src/types/move_type.rs +++ b/crates/iota-graphql-rpc/src/types/move_type.rs @@ -260,8 +260,8 @@ impl TryFrom for MoveTypeLayout { TL::Address => Self::Address, TL::Vector(v) => Self::Vector(Box::new(Self::try_from(*v)?)), - TL::Struct(s) => Self::Struct(s.try_into()?), - TL::Enum(e) => Self::Enum(e.try_into()?), + TL::Struct(s) => Self::Struct((*s).try_into()?), + TL::Enum(e) => Self::Enum((*e).try_into()?), }) } } diff --git a/crates/iota-graphql-rpc/src/types/move_value.rs b/crates/iota-graphql-rpc/src/types/move_value.rs index d0e31fe47e4..cacbf7b7d86 100644 --- a/crates/iota-graphql-rpc/src/types/move_value.rs +++ b/crates/iota-graphql-rpc/src/types/move_value.rs @@ -487,13 +487,13 @@ mod tests { macro_rules! struct_layout { ($type:literal { $($name:literal : $layout:expr),* $(,)?}) => { - A::MoveTypeLayout::Struct(S { + A::MoveTypeLayout::Struct(Box::new(S { type_: StructTag::from_str($type).expect("Failed to parse struct"), - fields: vec![$(MoveFieldLayout { + fields: Box::new(vec![$(MoveFieldLayout { name: ident_str!($name).to_owned(), layout: $layout, - }),*] - }) + }),*]) + })) } } diff --git a/crates/iota-indexer/src/handlers/checkpoint_handler.rs b/crates/iota-indexer/src/handlers/checkpoint_handler.rs index 3d8489f03b9..29b959a5767 100644 --- a/crates/iota-indexer/src/handlers/checkpoint_handler.rs +++ b/crates/iota-indexer/src/handlers/checkpoint_handler.rs @@ -746,7 +746,7 @@ async fn get_move_struct_layout_map( move_core_types::annotated_value::MoveStructLayout, ), IndexerError, - >((struct_tag, move_struct_layout)) + >((struct_tag, *move_struct_layout)) } }) .collect::>(); diff --git a/crates/iota-indexer/src/models/objects.rs b/crates/iota-indexer/src/models/objects.rs index 50aeee95151..482fc5b9ec0 100644 --- a/crates/iota-indexer/src/models/objects.rs +++ b/crates/iota-indexer/src/models/objects.rs @@ -316,7 +316,7 @@ impl StoredObject { )), }?; - Ok(ObjectRead::Exists(oref, object, Some(move_struct_layout))) + Ok(ObjectRead::Exists(oref, object, Some(*move_struct_layout))) } pub async fn try_into_expectant_dynamic_field_info( diff --git a/crates/iota-json/src/lib.rs b/crates/iota-json/src/lib.rs index 77b9759e2ce..bd83ccaf748 100644 --- a/crates/iota-json/src/lib.rs +++ b/crates/iota-json/src/lib.rs @@ -227,7 +227,7 @@ impl IotaJsonValue { with one field of address or u8 vector type" ), }, - MoveTypeLayout::Struct(MoveStructLayout { type_, .. }) if type_ == &ID::type_() => { + MoveTypeLayout::Struct(struct_layout) if struct_layout.type_ == ID::type_() => { Ok(R::MoveValue::Struct(R::MoveStruct(vec![ Self::to_move_value(val, &inner_vec[0].layout.clone())?, ]))) @@ -282,27 +282,27 @@ impl IotaJsonValue { R::MoveValue::U256(convert_string_to_u256(s.as_str())?) } // For ascii and utf8 strings - ( - JsonValue::String(s), - MoveTypeLayout::Struct(MoveStructLayout { type_, fields: _ }), - ) if is_move_string_type(type_) => { + (JsonValue::String(s), MoveTypeLayout::Struct(struct_layout)) + if is_move_string_type(&struct_layout.type_) => + { R::MoveValue::Vector(s.as_bytes().iter().copied().map(R::MoveValue::U8).collect()) } // For ID - (JsonValue::String(s), MoveTypeLayout::Struct(MoveStructLayout { type_, fields })) - if type_ == &ID::type_() => + (JsonValue::String(s), MoveTypeLayout::Struct(struct_layout)) + if struct_layout.type_ == ID::type_() => { - if fields.len() != 1 { + if struct_layout.fields.len() != 1 { bail!( - "Cannot convert string arg {s} to {type_} which is expected to be a struct with one field" + "Cannot convert string arg {s} to {} which is expected to be a struct with one field", + struct_layout.type_ ); }; let addr = IotaAddress::from_str(s)?; R::MoveValue::Address(addr.into()) } - (JsonValue::Object(o), MoveTypeLayout::Struct(MoveStructLayout { fields, .. })) => { + (JsonValue::Object(o), MoveTypeLayout::Struct(struct_layout)) => { let mut field_values = vec![]; - for layout in fields { + for layout in struct_layout.fields.iter() { let field = o .get(layout.name.as_str()) .ok_or_else(|| anyhow!("Missing field {} for struct {ty}", layout.name))?; @@ -311,10 +311,8 @@ impl IotaJsonValue { R::MoveValue::Struct(R::MoveStruct(field_values)) } // Unnest fields - (value, MoveTypeLayout::Struct(MoveStructLayout { fields, .. })) - if fields.len() == 1 => - { - Self::to_move_value(value, &fields[0].layout)? + (value, MoveTypeLayout::Struct(struct_layout)) if struct_layout.fields.len() == 1 => { + Self::to_move_value(value, &struct_layout.fields[0].layout)? } (JsonValue::String(s), MoveTypeLayout::Vector(t)) => { match &**t { @@ -337,8 +335,8 @@ impl IotaJsonValue { }; R::MoveValue::Vector(vec.iter().copied().map(R::MoveValue::U8).collect()) } - MoveTypeLayout::Struct(MoveStructLayout { fields: inner, .. }) => { - Self::handle_inner_struct_layout(inner, val, ty, s)? + MoveTypeLayout::Struct(struct_layout) => { + Self::handle_inner_struct_layout(&struct_layout.fields, val, ty, s)? } _ => bail!("Cannot convert string arg {s} to {ty}"), } @@ -606,37 +604,37 @@ pub fn primitive_type( if resolved_struct == RESOLVED_ASCII_STR { ( true, - Some(MoveTypeLayout::Struct(MoveStructLayout { + Some(MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: resolved_to_struct(RESOLVED_ASCII_STR), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("bytes").into(), MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - )], - })), + )]), + }))), ) } else if resolved_struct == RESOLVED_UTF8_STR { // both structs structs representing strings have one field - a vector of type // u8 ( true, - Some(MoveTypeLayout::Struct(MoveStructLayout { + Some(MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: resolved_to_struct(RESOLVED_UTF8_STR), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("bytes").into(), MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - )], - })), + )]), + }))), ) } else if resolved_struct == RESOLVED_IOTA_ID { ( true, - Some(MoveTypeLayout::Struct(MoveStructLayout { + Some(MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: resolved_to_struct(RESOLVED_IOTA_ID), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("bytes").into(), MoveTypeLayout::Address, - )], - })), + )]), + }))), ) } else { (false, None) diff --git a/crates/iota-json/src/tests.rs b/crates/iota-json/src/tests.rs index b97880f0efa..d9ec52977ae 100644 --- a/crates/iota-json/src/tests.rs +++ b/crates/iota-json/src/tests.rs @@ -626,18 +626,18 @@ fn test_from_str() { fn test_iota_call_arg_string_type() { let arg1 = bcs::to_bytes("Some String").unwrap(); - let string_layout = Some(MoveTypeLayout::Struct(MoveStructLayout { + let string_layout = Some(MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: StructTag { address: MOVE_STDLIB_ADDRESS, module: STD_ASCII_MODULE_NAME.into(), name: STD_ASCII_STRUCT_NAME.into(), type_params: vec![], }, - fields: vec![MoveFieldLayout { + fields: Box::new(vec![MoveFieldLayout { name: ident_str!("bytes").into(), layout: MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - }], - })); + }]), + }))); let v = IotaJsonValue::from_bcs_bytes(string_layout.as_ref(), &arg1).unwrap(); assert_eq!(json! {"Some String"}, v.to_json_value()); @@ -647,31 +647,31 @@ fn test_iota_call_arg_string_type() { fn test_iota_call_arg_option_type() { let arg1 = bcs::to_bytes(&Some("Some String")).unwrap(); - let string_layout = MoveTypeLayout::Struct(MoveStructLayout { + let string_layout = MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: StructTag { address: MOVE_STDLIB_ADDRESS, module: STD_ASCII_MODULE_NAME.into(), name: STD_ASCII_STRUCT_NAME.into(), type_params: vec![], }, - fields: vec![MoveFieldLayout { + fields: Box::new(vec![MoveFieldLayout { name: ident_str!("bytes").into(), layout: MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - }], - }); + }]), + })); - let option_layout = MoveTypeLayout::Struct(MoveStructLayout { + let option_layout = MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: StructTag { address: MOVE_STDLIB_ADDRESS, module: STD_OPTION_MODULE_NAME.into(), name: STD_OPTION_STRUCT_NAME.into(), type_params: vec![], }, - fields: vec![MoveFieldLayout { + fields: Box::new(vec![MoveFieldLayout { name: ident_str!("vec").into(), layout: MoveTypeLayout::Vector(Box::new(string_layout.clone())), - }], - }); + }]), + })); let v = IotaJsonValue::from_bcs_bytes(Some(option_layout).as_ref(), &arg1).unwrap(); @@ -688,7 +688,7 @@ fn test_iota_call_arg_option_type() { #[test] fn test_convert_struct() { - let layout = MoveTypeLayout::Struct(GasCoin::layout()); + let layout = MoveTypeLayout::Struct(Box::new(GasCoin::layout())); let value = json!({"id":"0xf1416fe18c7baa1673187375777a7606708481311cb3548509ec91a5871c6b9a", "balance": "1000000"}); let iota_json = IotaJsonValue::new(value).unwrap(); @@ -710,18 +710,18 @@ fn test_convert_struct() { fn test_convert_string_vec() { let test_vec = vec!["0xbbb", "test_str"]; let bcs = bcs::to_bytes(&test_vec).unwrap(); - let string_layout = MoveTypeLayout::Struct(MoveStructLayout { + let string_layout = MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: StructTag { address: MOVE_STDLIB_ADDRESS, module: STD_ASCII_MODULE_NAME.into(), name: STD_ASCII_STRUCT_NAME.into(), type_params: vec![], }, - fields: vec![MoveFieldLayout { + fields: Box::new(vec![MoveFieldLayout { name: ident_str!("bytes").into(), layout: MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - }], - }); + }]), + })); let layout = MoveTypeLayout::Vector(Box::new(string_layout)); @@ -745,31 +745,31 @@ fn test_string_vec_df_name_child_id_eq() { ] }); - let string_layout = MoveTypeLayout::Struct(MoveStructLayout { + let string_layout = MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: StructTag { address: MOVE_STDLIB_ADDRESS, module: STD_ASCII_MODULE_NAME.into(), name: STD_ASCII_STRUCT_NAME.into(), type_params: vec![], }, - fields: vec![MoveFieldLayout { + fields: Box::new(vec![MoveFieldLayout { name: ident_str!("bytes").into(), layout: MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)), - }], - }); + }]), + })); - let layout = MoveTypeLayout::Struct(MoveStructLayout { + let layout = MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_: StructTag { address: MOVE_STDLIB_ADDRESS, module: STD_ASCII_MODULE_NAME.into(), name: STD_ASCII_STRUCT_NAME.into(), type_params: vec![], }, - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( Identifier::from_str("labels").unwrap(), MoveTypeLayout::Vector(Box::new(string_layout)), - )], - }); + )]), + })); let iota_json = IotaJsonValue::new(name).unwrap(); let bcs2 = iota_json.to_bcs_bytes(&layout).unwrap(); diff --git a/crates/iota-move-build/src/lib.rs b/crates/iota-move-build/src/lib.rs index 309885fcbf1..c73dae6f128 100644 --- a/crates/iota-move-build/src/lib.rs +++ b/crates/iota-move-build/src/lib.rs @@ -26,7 +26,7 @@ use move_binary_format::{ CompiledModule, normalized::{self, Type}, }; -use move_bytecode_utils::{layout::SerdeLayoutBuilder, module_cache::GetModule}; +use move_bytecode_utils::{Modules, layout::SerdeLayoutBuilder, module_cache::GetModule}; use move_compiler::{ compiled_unit::AnnotatedCompiledModule, diagnostics::{Diagnostics, report_diagnostics_to_buffer, report_warnings}, @@ -45,7 +45,7 @@ use move_package::{ }, package_hooks::{PackageHooks, PackageIdentifier}, resolution::resolution_graph::{Package, ResolvedGraph}, - source_package::parsed_manifest::{CustomDepInfo, SourceManifest}, + source_package::parsed_manifest::{OnChainInfo, SourceManifest}, }; use move_symbol_pool::Symbol; use serde_reflection::Registry; @@ -320,11 +320,10 @@ impl CompiledPackage { &self, with_unpublished_deps: bool, ) -> Vec { - let all_modules = self.package.all_modules_map(); - let graph = all_modules.compute_dependency_graph(); + let all_modules = Modules::new(self.get_modules_and_deps()); // SAFETY: package built successfully - let modules = graph.compute_topological_order().unwrap(); + let modules = all_modules.compute_topological_order().unwrap(); if with_unpublished_deps { // For each transitive dependent module, if they are not to be published, they @@ -604,14 +603,10 @@ impl PackageHooks for IotaPackageHooks { ] } - fn custom_dependency_key(&self) -> Option { - None - } - - fn resolve_custom_dependency( + fn resolve_on_chain_dependency( &self, _dep_name: move_symbol_pool::Symbol, - _info: &CustomDepInfo, + _info: &OnChainInfo, ) -> anyhow::Result<()> { Ok(()) } @@ -620,7 +615,9 @@ impl PackageHooks for IotaPackageHooks { &self, manifest: &SourceManifest, ) -> anyhow::Result { - if !cfg!(debug_assertions) && manifest.package.edition == Some(Edition::DEVELOPMENT) { + if (!cfg!(debug_assertions) || cfg!(test)) + && manifest.package.edition == Some(Edition::DEVELOPMENT) + { return Err(Edition::DEVELOPMENT.unknown_edition_error()); } Ok(manifest.package.name) diff --git a/crates/iota-node/src/main.rs b/crates/iota-node/src/main.rs index 09b001d78bb..673d1666f42 100644 --- a/crates/iota-node/src/main.rs +++ b/crates/iota-node/src/main.rs @@ -44,8 +44,8 @@ fn main() { // figure out how to eliminate crashes in prod because of this. // ProtocolConfig::poison_get_for_min_version(); - move_vm_profiler::gas_profiler_feature_enabled! { - panic!("Cannot run the iota-node binary with gas-profiler feature enabled"); + move_vm_profiler::tracing_feature_enabled! { + panic!("Cannot run the iota-node binary with tracing feature enabled"); } let args = Args::parse(); diff --git a/crates/iota-open-rpc/src/examples.rs b/crates/iota-open-rpc/src/examples.rs index a98c62a0623..51a391a5749 100644 --- a/crates/iota-open-rpc/src/examples.rs +++ b/crates/iota-open-rpc/src/examples.rs @@ -1111,7 +1111,7 @@ impl RpcExampleProvider { }, MoveStructLayout { type_: struct_tag, - fields: Vec::new(), + fields: Box::new(Vec::new()), }, ) .unwrap(), diff --git a/crates/iota-package-resolver/src/lib.rs b/crates/iota-package-resolver/src/lib.rs index 05ed900b686..099c5e7d4cb 100644 --- a/crates/iota-package-resolver/src/lib.rs +++ b/crates/iota-package-resolver/src/lib.rs @@ -1503,10 +1503,10 @@ impl<'l> ResolutionContext<'l> { } ( - MoveTypeLayout::Struct(MoveStructLayout { + MoveTypeLayout::Struct(Box::new(MoveStructLayout { type_, - fields: resolved_fields, - }), + fields: Box::new(resolved_fields), + })), field_depth + 1, ) } @@ -1531,10 +1531,10 @@ impl<'l> ResolutionContext<'l> { } ( - MoveTypeLayout::Enum(MoveEnumLayout { + MoveTypeLayout::Enum(Box::new(MoveEnumLayout { type_, variants: resolved_variants, - }), + })), field_depth + 1, ) } diff --git a/crates/iota-replay/src/data_fetcher.rs b/crates/iota-replay/src/data_fetcher.rs index 70749a03dbe..19851d6a9fd 100644 --- a/crates/iota-replay/src/data_fetcher.rs +++ b/crates/iota-replay/src/data_fetcher.rs @@ -23,7 +23,7 @@ use iota_types::{ }, }; use lru::LruCache; -use move_core_types::parser::parse_struct_tag; +use move_core_types::language_storage::StructTag; use parking_lot::RwLock; use rand::Rng; @@ -555,7 +555,7 @@ impl DataFetcher for RemoteFetcher { reverse: bool, ) -> Result, ReplayEngineError> { let struct_tag_str = EPOCH_CHANGE_STRUCT_TAG.to_string(); - let struct_tag = parse_struct_tag(&struct_tag_str)?; + let struct_tag = StructTag::from_str(&struct_tag_str)?; let mut epoch_change_events: Vec = vec![]; let mut has_next_page = true; diff --git a/crates/iota-source-validation/src/toolchain.rs b/crates/iota-source-validation/src/toolchain.rs index 56c6cda08b8..88515eb744b 100644 --- a/crates/iota-source-validation/src/toolchain.rs +++ b/crates/iota-source-validation/src/toolchain.rs @@ -41,7 +41,7 @@ use tracing::{debug, info}; pub(crate) const CURRENT_COMPILER_VERSION: &str = env!("CARGO_PKG_VERSION"); const LEGACY_COMPILER_VERSION: &str = CURRENT_COMPILER_VERSION; // TODO: update this when Move 2024 is released -const PRE_TOOLCHAIN_MOVE_LOCK_VERSION: u64 = 0; // Used to detect lockfiles pre-toolchain versioning support +const PRE_TOOLCHAIN_MOVE_LOCK_VERSION: u16 = 0; // Used to detect lockfiles pre-toolchain versioning support const CANONICAL_UNIX_BINARY_NAME: &str = "iota"; const CANONICAL_WIN_BINARY_NAME: &str = "iota.exe"; diff --git a/crates/iota-transactional-test-runner/src/args.rs b/crates/iota-transactional-test-runner/src/args.rs index 2379237cc51..da43f0190c9 100644 --- a/crates/iota-transactional-test-runner/src/args.rs +++ b/crates/iota-transactional-test-runner/src/args.rs @@ -11,12 +11,12 @@ use iota_types::{ programmable_transaction_builder::ProgrammableTransactionBuilder, transaction::{Argument, CallArg, ObjectArg}, }; -use move_command_line_common::{ - parser::{Parser as MoveCLParser, parse_u64, parse_u256}, - values::{ParsableValue, ParsedValue, ValueToken}, -}; use move_compiler::editions::Flavor; use move_core_types::{ + parsing::{ + parser::{Parser as MoveCLParser, parse_u64, parse_u256}, + values::{ParsableValue, ParsedValue, ValueToken}, + }, runtime_value::{MoveStruct, MoveValue}, u256::U256, }; diff --git a/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs b/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs index e1fbf7a8596..2681fc0b367 100644 --- a/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs +++ b/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs @@ -9,11 +9,14 @@ use iota_types::{ base_types::ObjectID, transaction::{Argument, Command, ProgrammableMoveCall}, }; -use move_command_line_common::{ - parser::{Parser, Token}, - types::{ParsedType, TypeToken}, +use move_core_types::{ + account_address::AccountAddress, + identifier::Identifier, + parsing::{ + parser::{Parser, Token}, + types::{ParsedType, TypeToken}, + }, }; -use move_core_types::{account_address::AccountAddress, identifier::Identifier}; use super::token::CommandToken; use crate::programmable_transaction_test_parser::token::{ diff --git a/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/token.rs b/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/token.rs index cc02eee8a40..8fc2a69b476 100644 --- a/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/token.rs +++ b/crates/iota-transactional-test-runner/src/programmable_transaction_test_parser/token.rs @@ -5,8 +5,7 @@ use std::fmt::{self, Display}; use anyhow::bail; -use move_command_line_common::parser::Token; -use move_core_types::identifier; +use move_core_types::{identifier, parsing::parser::Token}; #[derive(Eq, PartialEq, Debug, Clone, Copy)] pub enum CommandToken { diff --git a/crates/iota-transactional-test-runner/src/test_adapter.rs b/crates/iota-transactional-test-runner/src/test_adapter.rs index 268fe616239..10d264c0967 100644 --- a/crates/iota-transactional-test-runner/src/test_adapter.rs +++ b/crates/iota-transactional-test-runner/src/test_adapter.rs @@ -66,9 +66,7 @@ use iota_types::{ }; use move_binary_format::CompiledModule; use move_bytecode_utils::module_cache::GetModule; -use move_command_line_common::{ - address::ParsedAddress, files::verify_and_create_named_address_mapping, -}; +use move_command_line_common::files::verify_and_create_named_address_mapping; use move_compiler::{ Flags, FullyCompiledProgram, editions::{Edition, Flavor}, @@ -79,6 +77,7 @@ use move_core_types::{ ident_str, identifier::IdentStr, language_storage::{ModuleId, TypeTag}, + parsing::address::ParsedAddress, }; use move_symbol_pool::Symbol; use move_transactional_test_runner::{ diff --git a/crates/iota-types/Cargo.toml b/crates/iota-types/Cargo.toml index 9d229d4ed41..034325deb0a 100644 --- a/crates/iota-types/Cargo.toml +++ b/crates/iota-types/Cargo.toml @@ -104,10 +104,9 @@ harness = false [features] default = [] test-utils = [] -gas-profiler = [ - "move-vm-profiler/gas-profiler", - "move-vm-test-utils/gas-profiler", - "move-vm-types/gas-profiler", +tracing = [ + "move-vm-profiler/tracing", + "move-vm-test-utils/tracing", ] fuzzing = ["move-core-types/fuzzing", "dep:proptest-derive", "dep:proptest"] diff --git a/crates/iota-types/src/balance.rs b/crates/iota-types/src/balance.rs index fa7e354cc7a..54b8749809b 100644 --- a/crates/iota-types/src/balance.rs +++ b/crates/iota-types/src/balance.rs @@ -86,10 +86,10 @@ impl Balance { pub fn layout(type_param: TypeTag) -> MoveStructLayout { MoveStructLayout { type_: Self::type_(type_param), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("value").to_owned(), MoveTypeLayout::U64, - )], + )]), } } } diff --git a/crates/iota-types/src/coin.rs b/crates/iota-types/src/coin.rs index 6336c75168c..177f8479318 100644 --- a/crates/iota-types/src/coin.rs +++ b/crates/iota-types/src/coin.rs @@ -99,16 +99,16 @@ impl Coin { pub fn layout(type_param: TypeTag) -> MoveStructLayout { MoveStructLayout { type_: Self::type_(type_param.clone()), - fields: vec![ + fields: Box::new(vec![ MoveFieldLayout::new( ident_str!("id").to_owned(), - MoveTypeLayout::Struct(UID::layout()), + MoveTypeLayout::Struct(Box::new(UID::layout())), ), MoveFieldLayout::new( ident_str!("balance").to_owned(), - MoveTypeLayout::Struct(Balance::layout(type_param)), + MoveTypeLayout::Struct(Box::new(Balance::layout(type_param))), ), - ], + ]), } } diff --git a/crates/iota-types/src/id.rs b/crates/iota-types/src/id.rs index 0610c6aaa4b..e65b35a2b26 100644 --- a/crates/iota-types/src/id.rs +++ b/crates/iota-types/src/id.rs @@ -61,10 +61,10 @@ impl UID { pub fn layout() -> MoveStructLayout { MoveStructLayout { type_: Self::type_(), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("id").to_owned(), - MoveTypeLayout::Struct(ID::layout()), - )], + MoveTypeLayout::Struct(Box::new(ID::layout())), + )]), } } } @@ -86,10 +86,10 @@ impl ID { pub fn layout() -> MoveStructLayout { MoveStructLayout { type_: Self::type_(), - fields: vec![MoveFieldLayout::new( + fields: Box::new(vec![MoveFieldLayout::new( ident_str!("bytes").to_owned(), MoveTypeLayout::Address, - )], + )]), } } } diff --git a/crates/iota-types/src/layout_resolver.rs b/crates/iota-types/src/layout_resolver.rs index d6cbed972f7..417099199f0 100644 --- a/crates/iota-types/src/layout_resolver.rs +++ b/crates/iota-types/src/layout_resolver.rs @@ -40,7 +40,7 @@ pub fn get_layout_from_struct_tag( pub fn into_struct_layout(layout: A::MoveDatatypeLayout) -> Result { match layout { - A::MoveDatatypeLayout::Struct(s) => Ok(s), + A::MoveDatatypeLayout::Struct(s) => Ok(*s), A::MoveDatatypeLayout::Enum(e) => Err(IotaError::ObjectSerialization { error: format!("Expected struct layout but got an enum {e:?}"), }), diff --git a/crates/iota-types/src/lib.rs b/crates/iota-types/src/lib.rs index 962434c3c2b..47a153ab65a 100644 --- a/crates/iota-types/src/lib.rs +++ b/crates/iota-types/src/lib.rs @@ -162,7 +162,7 @@ pub fn iota_framework_address_concat_string(suffix: &str) -> String { /// with no remaining suffix. This function is intended for use within the /// authority codebases. pub fn parse_iota_address(s: &str) -> anyhow::Result { - use move_command_line_common::address::ParsedAddress; + use move_core_types::parsing::address::ParsedAddress; Ok(ParsedAddress::parse(s)? .into_account_address(&resolve_address)? .into()) @@ -173,7 +173,7 @@ pub fn parse_iota_address(s: &str) -> anyhow::Result { /// if `s` matches this format exactly, with no remaining input. This function /// is intended for use within the authority codebases. pub fn parse_iota_module_id(s: &str) -> anyhow::Result { - use move_command_line_common::types::ParsedModuleId; + use move_core_types::parsing::types::ParsedModuleId; ParsedModuleId::parse(s)?.into_module_id(&resolve_address) } @@ -183,7 +183,7 @@ pub fn parse_iota_module_id(s: &str) -> anyhow::Result { /// format exactly, with no remaining input. This function is intended for use /// within the authority codebases. pub fn parse_iota_fq_name(s: &str) -> anyhow::Result<(ModuleId, String)> { - use move_command_line_common::types::ParsedFqName; + use move_core_types::parsing::types::ParsedFqName; ParsedFqName::parse(s)?.into_fq_name(&resolve_address) } @@ -193,7 +193,7 @@ pub fn parse_iota_fq_name(s: &str) -> anyhow::Result<(ModuleId, String)> { /// matches this format exactly, with no remaining input. This function is /// intended for use within the authority codebase. pub fn parse_iota_struct_tag(s: &str) -> anyhow::Result { - use move_command_line_common::types::ParsedStructType; + use move_core_types::parsing::types::ParsedStructType; ParsedStructType::parse(s)?.into_struct_tag(&resolve_address) } @@ -202,7 +202,7 @@ pub fn parse_iota_struct_tag(s: &str) -> anyhow::Result { /// only if `s` matches this format exactly, with no remaining input. This /// function is intended for use within the authority codebase. pub fn parse_iota_type_tag(s: &str) -> anyhow::Result { - use move_command_line_common::types::ParsedType; + use move_core_types::parsing::types::ParsedType; ParsedType::parse(s)?.into_type_tag(&resolve_address) } @@ -399,7 +399,7 @@ mod tests { #[test] fn test_parse_iota_struct_tag_long_account_addr() { let result = parse_iota_struct_tag( - "0x00000000000000000000000000000000000000000000000000000000000000002::iota::IOTA", + "0x0000000000000000000000000000000000000000000000000000000000000002::iota::IOTA", ) .expect("should not error"); diff --git a/crates/iota-types/src/object.rs b/crates/iota-types/src/object.rs index 63ef7c06824..ef3f6fdbe6d 100644 --- a/crates/iota-types/src/object.rs +++ b/crates/iota-types/src/object.rs @@ -295,7 +295,7 @@ impl MoveObject { } })?; match layout { - MoveTypeLayout::Struct(l) => Ok(l), + MoveTypeLayout::Struct(l) => Ok(*l), _ => unreachable!( "We called build_with_types on Struct type, should get a struct layout" ), diff --git a/crates/iota-types/src/object/balance_traversal.rs b/crates/iota-types/src/object/balance_traversal.rs index 3e9c9ef87c6..14b101d9a3f 100644 --- a/crates/iota-types/src/object/balance_traversal.rs +++ b/crates/iota-types/src/object/balance_traversal.rs @@ -5,7 +5,7 @@ use std::collections::BTreeMap; use move_core_types::{ - annotated_visitor::{self, StructDriver, Traversal}, + annotated_visitor::{self, StructDriver, Traversal, ValueDriver}, language_storage::{StructTag, TypeTag}, }; @@ -31,12 +31,12 @@ impl BalanceTraversal { } } -impl Traversal for BalanceTraversal { +impl<'b, 'l> Traversal<'b, 'l> for BalanceTraversal { type Error = annotated_visitor::Error; fn traverse_struct( &mut self, - driver: &mut StructDriver<'_, '_, '_>, + driver: &mut StructDriver<'_, 'b, 'l>, ) -> Result<(), Self::Error> { let Some(coin_type) = is_balance(&driver.struct_layout().type_) else { // Not a balance, search recursively for balances among fields. @@ -51,9 +51,13 @@ impl Traversal for BalanceTraversal { } } -impl Traversal for Accumulator { +impl<'b, 'l> Traversal<'b, 'l> for Accumulator { type Error = annotated_visitor::Error; - fn traverse_u64(&mut self, value: u64) -> Result<(), Self::Error> { + fn traverse_u64( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result<(), Self::Error> { self.total += value; Ok(()) } @@ -236,7 +240,7 @@ mod tests { /// Create a Coin layout for testing purposes. fn coin_t(tag: &str) -> A::MoveTypeLayout { layout_(&format!("0x2::coin::Coin<{tag}>"), vec![ - ("id", A::MoveTypeLayout::Struct(UID::layout())), + ("id", A::MoveTypeLayout::Struct(Box::new(UID::layout()))), ("balance", bal_t(tag)), ]) } @@ -265,7 +269,10 @@ mod tests { .map(|(name, layout)| A::MoveFieldLayout::new(Identifier::new(name).unwrap(), layout)) .collect(); - A::MoveTypeLayout::Struct(A::MoveStructLayout { type_, fields }) + A::MoveTypeLayout::Struct(Box::new(A::MoveStructLayout { + type_, + fields: Box::new(fields), + })) } /// BCS encode Move value. diff --git a/crates/iota-types/src/object/bounded_visitor.rs b/crates/iota-types/src/object/bounded_visitor.rs index d8ccf434bf4..6efe1f3c4d1 100644 --- a/crates/iota-types/src/object/bounded_visitor.rs +++ b/crates/iota-types/src/object/bounded_visitor.rs @@ -6,7 +6,7 @@ use anyhow::bail; use move_core_types::{ account_address::AccountAddress, annotated_value as A, - annotated_visitor::{self, StructDriver, VecDriver, Visitor}, + annotated_visitor::{self, StructDriver, ValueDriver, VecDriver, Visitor}, language_storage::TypeTag, u256::U256, }; @@ -152,49 +152,85 @@ impl BoundedVisitor { } } -impl Visitor for BoundedVisitor { +impl<'b, 'l> Visitor<'b, 'l> for BoundedVisitor { type Value = A::MoveValue; type Error = Error; - fn visit_u8(&mut self, value: u8) -> Result { + fn visit_u8( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u8, + ) -> Result { Ok(A::MoveValue::U8(value)) } - fn visit_u16(&mut self, value: u16) -> Result { + fn visit_u16( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u16, + ) -> Result { Ok(A::MoveValue::U16(value)) } - fn visit_u32(&mut self, value: u32) -> Result { + fn visit_u32( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u32, + ) -> Result { Ok(A::MoveValue::U32(value)) } - fn visit_u64(&mut self, value: u64) -> Result { + fn visit_u64( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u64, + ) -> Result { Ok(A::MoveValue::U64(value)) } - fn visit_u128(&mut self, value: u128) -> Result { + fn visit_u128( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: u128, + ) -> Result { Ok(A::MoveValue::U128(value)) } - fn visit_u256(&mut self, value: U256) -> Result { + fn visit_u256( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: U256, + ) -> Result { Ok(A::MoveValue::U256(value)) } - fn visit_bool(&mut self, value: bool) -> Result { + fn visit_bool( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: bool, + ) -> Result { Ok(A::MoveValue::Bool(value)) } - fn visit_address(&mut self, value: AccountAddress) -> Result { + fn visit_address( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { Ok(A::MoveValue::Address(value)) } - fn visit_signer(&mut self, value: AccountAddress) -> Result { + fn visit_signer( + &mut self, + _driver: &ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result { Ok(A::MoveValue::Signer(value)) } fn visit_vector( &mut self, - driver: &mut VecDriver<'_, '_, '_>, + driver: &mut VecDriver<'_, 'b, 'l>, ) -> Result { let mut elems = vec![]; while let Some(elem) = driver.next_element(self)? { @@ -206,12 +242,12 @@ impl Visitor for BoundedVisitor { fn visit_struct( &mut self, - driver: &mut StructDriver<'_, '_, '_>, + driver: &mut StructDriver<'_, 'b, 'l>, ) -> Result { let tag = driver.struct_layout().type_.clone().into(); self.debit_type_size(&tag)?; - for field in &driver.struct_layout().fields { + for field in driver.struct_layout().fields.iter() { self.debit(field.name.len())?; } @@ -232,7 +268,7 @@ impl Visitor for BoundedVisitor { fn visit_variant( &mut self, - driver: &mut annotated_visitor::VariantDriver<'_, '_, '_>, + driver: &mut annotated_visitor::VariantDriver<'_, 'b, 'l>, ) -> Result { let type_ = driver.enum_layout().type_.clone().into(); @@ -459,7 +495,10 @@ mod tests { .map(|(name, layout)| A::MoveFieldLayout::new(Identifier::new(name).unwrap(), layout)) .collect(); - A::MoveTypeLayout::Struct(A::MoveStructLayout { type_, fields }) + A::MoveTypeLayout::Struct(Box::new(A::MoveStructLayout { + type_, + fields: Box::new(fields), + })) } /// BCS encode Move value. diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_name_change.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_name_change.snap index e8e29045927..07a0129ca74 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_name_change.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_name_change.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_value_changed.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_value_changed.snap index 896ade4f0b8..5fdfbb413f9 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_value_changed.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__constant_value_changed.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_entry_changed.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_entry_changed.snap index 09665dce74d..a6260a01e49 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_entry_changed.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_entry_changed.snap @@ -3,25 +3,7 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: true -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true @@ -30,7 +12,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: true @@ -39,7 +21,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: true @@ -48,7 +30,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_function_change.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_function_change.snap index 235d6867ef2..afa105f53ef 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_function_change.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__friend_function_change.snap @@ -3,25 +3,16 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -0000000000000000000000000000000000000000000000000000000000000000::friend_module: base->upgrade: true upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false 0000000000000000000000000000000000000000000000000000000000000000::friend_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true @@ -30,7 +21,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true @@ -39,16 +30,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check.snap index f9331168e2f..2bfb67dfdae 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_alpha_rename.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_alpha_rename.snap index f9331168e2f..2bfb67dfdae 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_alpha_rename.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_alpha_rename.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_local_shuffle.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_local_shuffle.snap index 3c4f874d418..8bf3ed4793d 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_local_shuffle.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_equality_check_local_shuffle.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_inclusion_check.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_inclusion_check.snap index dabd6c1a1d0..a24644c7f1b 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_inclusion_check.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_inclusion_check.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_invalid_equality_inclusion_check.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_invalid_equality_inclusion_check.snap index 3c4f874d418..8bf3ed4793d 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_invalid_equality_inclusion_check.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__large_package_invalid_equality_inclusion_check.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::ascii: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::ascii: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_and_friend_changes.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_and_friend_changes.snap index 2be98d1827b..7e01066277d 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_and_friend_changes.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_and_friend_changes.snap @@ -3,25 +3,7 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true @@ -30,7 +12,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: true @@ -39,16 +21,16 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false - upgrade->base: false + upgrade->base: true 0000000000000000000000000000000000000000000000000000000000000000::friend_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_fun_entry_removed.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_fun_entry_removed.snap index 09665dce74d..a6260a01e49 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_fun_entry_removed.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__private_entry_fun_entry_removed.snap @@ -3,25 +3,7 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: true -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -0000000000000000000000000000000000000000000000000000000000000000::friend_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true @@ -30,7 +12,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: true @@ -39,7 +21,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: true @@ -48,7 +30,7 @@ Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_la upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_alpha_rename.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_alpha_rename.snap index e8e29045927..07a0129ca74 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_alpha_rename.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_alpha_rename.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_permute.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_permute.snap index 896ade4f0b8..5fdfbb413f9 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_permute.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_param_permute.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_rename.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_rename.snap index 0f1af90aa73..687a2aae72a 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_rename.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__public_fun_rename.snap @@ -3,40 +3,28 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true ======== Equal 0000000000000000000000000000000000000000000000000000000000000000::base_module: diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_name_change.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_name_change.snap index 0f1af90aa73..838ec903d25 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_name_change.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_name_change.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder.snap index 0f1af90aa73..838ec903d25 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder_no_name_change.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder_no_name_change.snap index 0f1af90aa73..838ec903d25 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder_no_name_change.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_field_reorder_no_name_change.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_layout_change.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_layout_change.snap index 0f1af90aa73..838ec903d25 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_layout_change.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_layout_change.snap @@ -3,37 +3,25 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: true upgrade->base: true diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_name_change.snap b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_name_change.snap index 0f1af90aa73..687a2aae72a 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_name_change.snap +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/snapshots/tests__struct_name_change.snap @@ -3,40 +3,28 @@ source: crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs expression: results --- ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: true, check_private_entry_linking: true, disallowed_new_abilities: [Key, ] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false ==== ==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: false, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } +Compatibility { check_datatype_layout: false, check_private_entry_linking: false, disallowed_new_abilities: [] } 0000000000000000000000000000000000000000000000000000000000000000::base_module: base->upgrade: false upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: true, check_datatype_layout: true, check_friend_linking: true, check_private_entry_linking: true, disallowed_new_abilities: [Copy, Drop, Store, Key, ], disallow_change_datatype_type_params: true, disallow_new_variants: true } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: false - upgrade->base: false -==== -==== -Compatibility { check_datatype_and_pub_function_linking: false, check_datatype_layout: false, check_friend_linking: false, check_private_entry_linking: false, disallowed_new_abilities: [], disallow_change_datatype_type_params: false, disallow_new_variants: false } -0000000000000000000000000000000000000000000000000000000000000000::base_module: - base->upgrade: true - upgrade->base: true ======== Equal 0000000000000000000000000000000000000000000000000000000000000000::base_module: diff --git a/crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs b/crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs index 8fe573d592b..7e9dbe9a355 100644 --- a/crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs +++ b/crates/iota-upgrade-compatibility-transactional-tests/tests/tests.rs @@ -8,7 +8,6 @@ use iota_move_build::{BuildConfig, IotaPackageHooks}; use move_binary_format::{ CompiledModule, compatibility::{Compatibility, InclusionCheck}, - file_format::AbilitySet, normalized, }; @@ -54,47 +53,12 @@ fn check_all_compatibilities( assert_eq!(base.len(), upgraded.len()); let compatibility_types = [ + // Full compat skip check private entry linking + Compatibility::upgrade_check(), + // Full compat but allow any new abilities Compatibility::full_check(), - // Full compat but allow private entry functions to change - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: true, - check_private_entry_linking: false, - disallowed_new_abilities: AbilitySet::ALL, - disallow_change_datatype_type_params: true, - disallow_new_variants: true, - }, - // Full compat but allow private entry functions and friends to change - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: false, - check_private_entry_linking: false, - disallowed_new_abilities: AbilitySet::ALL, - disallow_change_datatype_type_params: true, - disallow_new_variants: true, - }, - // Full compat but allow friends to change - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: false, - check_private_entry_linking: true, - disallowed_new_abilities: AbilitySet::ALL, - disallow_change_datatype_type_params: true, - disallow_new_variants: true, - }, - // Full compat but allow new enum variants to be added - Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: true, - check_private_entry_linking: true, - disallowed_new_abilities: AbilitySet::ALL, - disallow_change_datatype_type_params: true, - disallow_new_variants: true, - }, + // Full compat only disallow new key ability + Compatibility::framework_upgrade_check(), Compatibility::no_check(), ]; diff --git a/crates/iota/Cargo.toml b/crates/iota/Cargo.toml index 8f6435f5f12..bf13542d328 100644 --- a/crates/iota/Cargo.toml +++ b/crates/iota/Cargo.toml @@ -126,5 +126,5 @@ name = "ptb_files_tests" harness = false [features] -gas-profiler = ["iota-types/gas-profiler", "iota-execution/gas-profiler"] +tracing = ["iota-types/tracing", "iota-execution/tracing"] indexer = ["dep:diesel", "dep:iota-indexer", "dep:iota-graphql-rpc"] diff --git a/crates/iota/src/client_commands.rs b/crates/iota/src/client_commands.rs index dfb34bb8808..051ab49f9a9 100644 --- a/crates/iota/src/client_commands.rs +++ b/crates/iota/src/client_commands.rs @@ -775,10 +775,10 @@ impl IotaClientCommands { tx_digest, profile_output, } => { - move_vm_profiler::gas_profiler_feature_disabled! { + move_vm_profiler::tracing_feature_disabled! { bail!( - "gas-profiler feature is not enabled, rebuild or reinstall with \ - --features gas-profiler" + "tracing feature is not enabled, rebuild or reinstall with \ + --features tracing" ); }; diff --git a/crates/iota/src/client_ptb/ast.rs b/crates/iota/src/client_ptb/ast.rs index e07b2dec8d7..8a1bc1bb30b 100644 --- a/crates/iota/src/client_ptb/ast.rs +++ b/crates/iota/src/client_ptb/ast.rs @@ -8,11 +8,13 @@ use iota_types::{ Identifier, TypeTag, base_types::{ObjectID, RESOLVED_ASCII_STR, RESOLVED_STD_OPTION, RESOLVED_UTF8_STR}, }; -use move_command_line_common::{ - address::{NumericalAddress, ParsedAddress}, - types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType}, +use move_core_types::{ + parsing::{ + address::{NumericalAddress, ParsedAddress}, + types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType}, + }, + runtime_value::MoveValue, }; -use move_core_types::runtime_value::MoveValue; use super::error::{PTBResult, Span, Spanned}; use crate::{err, error, sp}; diff --git a/crates/iota/src/client_ptb/builder.rs b/crates/iota/src/client_ptb/builder.rs index c64514e2f48..c1c5930eee6 100644 --- a/crates/iota/src/client_ptb/builder.rs +++ b/crates/iota/src/client_ptb/builder.rs @@ -24,12 +24,14 @@ use miette::Severity; use move_binary_format::{ CompiledModule, binary_config::BinaryConfig, file_format::SignatureToken, }; -use move_command_line_common::{ - address::{NumericalAddress, ParsedAddress}, - parser::NumberFormat, -}; use move_core_types::{ - account_address::AccountAddress, annotated_value::MoveTypeLayout, ident_str, + account_address::AccountAddress, + annotated_value::MoveTypeLayout, + ident_str, + parsing::{ + address::{NumericalAddress, ParsedAddress}, + parser::NumberFormat, + }, }; use move_package::BuildConfig; diff --git a/crates/iota/src/client_ptb/parser.rs b/crates/iota/src/client_ptb/parser.rs index 65c5a7ad11b..e77ad857923 100644 --- a/crates/iota/src/client_ptb/parser.rs +++ b/crates/iota/src/client_ptb/parser.rs @@ -5,7 +5,7 @@ use std::iter::Peekable; use iota_types::{Identifier, base_types::ObjectID}; -use move_command_line_common::{ +use move_core_types::parsing::{ address::{NumericalAddress, ParsedAddress}, parser::{parse_u8, parse_u16, parse_u32, parse_u64, parse_u128, parse_u256}, types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType}, diff --git a/crates/iota/src/unit_tests/profiler_tests.rs b/crates/iota/src/unit_tests/profiler_tests.rs index ac053d7b032..2baaef80a74 100644 --- a/crates/iota/src/unit_tests/profiler_tests.rs +++ b/crates/iota/src/unit_tests/profiler_tests.rs @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 /// This test exists to make sure that the feature gating for all the code under -/// `gas-profiler` remains fully connected such that if and only if we enable -/// the feature here, the `gas-profiler` feature gets enabled anywhere. +/// `tracing` remains fully connected such that if and only if we enable the +/// feature here, the `tracing` feature gets enabled anywhere. /// /// If this test fails, check for the following. /// -/// Any crate that has code decorated with #[cfg(feature = "gas-profiler")] -/// needs to have a feature declared in its Cargo.toml named `gas-profiler`. If -/// moving / refactoring code with this decorator from a crate to a different -/// crate, it is likely needed to copy over some of the feature declaration -/// defined in the original crate. Also ensure we do not include the feature in -/// any dependency of the dependencies section so that the feature won't get -/// partially enabled as default. +/// Any crate that has code decorated with #[cfg(feature = "tracing")] needs to +/// have a feature declared in its Cargo.toml named `tracing`. If moving / +/// refactoring code with this decorator from a crate to a different crate, it +/// is likely needed to copy over some of the feature declaration defined in the +/// original crate. Also ensure we do not include the feature in any dependency +/// of the dependencies section so that the feature won't get partially enabled +/// as default. /// /// Each crate defines its own version of the feature with the same name. We can /// think of these features as a tree structure where the root is defined here @@ -25,18 +25,18 @@ /// current crate depends on. /// /// Note this crate will always have the feature enabled in testing due to the -/// addition of `iota = { path = ".", features = ["gas-profiler"] }` to our +/// addition of `iota = { path = ".", features = ["tracing"] }` to our /// dev-dependencies. -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] #[test] fn test_macro_shows_feature_enabled() { - move_vm_profiler::gas_profiler_feature_disabled! { + move_vm_profiler::tracing_feature_disabled! { panic!("gas profile feature graph became disconnected"); } } -#[cfg(feature = "gas-profiler")] +#[cfg(feature = "tracing")] #[tokio::test(flavor = "multi_thread")] async fn test_profiler() { use std::fs; diff --git a/crates/iota/tests/cli_tests.rs b/crates/iota/tests/cli_tests.rs index aaded6cecdb..fcdb7637a0e 100644 --- a/crates/iota/tests/cli_tests.rs +++ b/crates/iota/tests/cli_tests.rs @@ -4469,8 +4469,8 @@ async fn test_move_new() -> Result<(), anyhow::Error> { .flat_map(|r| r.map(|file| file.file_name().to_str().unwrap().to_owned())) .collect::>(); - assert_eq!(3, files.len()); - for name in ["sources", "tests", "Move.toml"] { + assert_eq!(4, files.len()); + for name in ["sources", "tests", "Move.toml", ".gitignore"] { assert!(files.contains(&name.to_string())); } assert!(std::path::Path::new(&format!("{package_name}/sources/{package_name}.move")).exists()); @@ -4512,6 +4512,7 @@ async fn test_move_new() -> Result<(), anyhow::Error> { verbose_mode: false, seed: None, rand_num_iters: None, + trace_execution: None, }, }), } diff --git a/docs/content/developer/dev-cheat-sheet.mdx b/docs/content/developer/dev-cheat-sheet.mdx index aa067459d45..d0a20214c45 100644 --- a/docs/content/developer/dev-cheat-sheet.mdx +++ b/docs/content/developer/dev-cheat-sheet.mdx @@ -19,7 +19,7 @@ Quick reference on best practices for IOTA Network developers. |`iota keytool list`|to list all the address.| |`iota move new first_package`|to create new move package.| |`pnpm create @iota/dapp --template react-client-dapp`| to setup React app with dApp kit| -|`cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features gas-profiler iota`|To get the latest version of CLI| +|`cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features tracing iota`|To get the latest version of CLI| |`iota client active-address`|to get the current address.| |`iota client -–help`|to list out all commands of iota client.| |`iota client new-address Scheme`|to generate address , **Scheme** - (ed25519,secp256k1,secp256r1)| diff --git a/docs/content/references/cli.mdx b/docs/content/references/cli.mdx index aa229d53742..c5e26087d0c 100644 --- a/docs/content/references/cli.mdx +++ b/docs/content/references/cli.mdx @@ -14,12 +14,12 @@ IOTA provides a command line interface (CLI) tool to interact with the IOTA netw To get the latest version of the CLI, you can run the following command from a terminal or console. Be sure to replace `` with `develop`, `devnet`, `testnet`, or `mainnet` to get the desired version. For more information on the branches available, see [IOTA Environment Setup](/developer/getting-started/iota-environment.mdx). ```shell -cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features gas-profiler iota +cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features tracing iota ``` :::info -The `--features gas-profiler` flag is necessary only if you want to run gas profiles for transactions. +The `--features tracing` flag is necessary only if you want to run gas profiles for transactions. ::: diff --git a/docs/content/references/cli/client.mdx b/docs/content/references/cli/client.mdx index 87060609c08..953960f16ac 100644 --- a/docs/content/references/cli/client.mdx +++ b/docs/content/references/cli/client.mdx @@ -472,10 +472,10 @@ and produce a gas profile. Similar to the `replay` command, this command fetches Full node specified in the client environment that are needed to execute the transaction. During the local execution of the transaction, this command records all the Move function invocations and the gas cost breakdown for each invocation. -To enable the profiler, you must either install or build the IOTA Client binary locally with the `--features gas-profiler` flag. +To enable the profiler, you must either install or build the IOTA Client binary locally with the `--features tracing` flag. ```shell -cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features gas-profiler iota +cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features tracing iota ``` The command outputs a profile to the current working directory in the format `gas_profile_{tx_digest}_{unix_timestamp}.json`. diff --git a/iota-execution/Cargo.toml b/iota-execution/Cargo.toml index 4899d7bdbf0..2cbad944365 100644 --- a/iota-execution/Cargo.toml +++ b/iota-execution/Cargo.toml @@ -30,10 +30,10 @@ petgraph = "0.6" [features] default = [] -gas-profiler = [ - "iota-adapter-latest/gas-profiler", - "move-vm-config/gas-profiler", - "move-vm-runtime-latest/gas-profiler", - # "iota-adapter-$CUT/gas-profiler", - # "move-vm-runtime-$CUT/gas-profiler", +tracing = [ + "iota-adapter-latest/tracing", + "move-vm-config/tracing", + "move-vm-runtime-latest/tracing", + # "iota-adapter-$CUT/tracing", + # "move-vm-runtime-$CUT/tracing", ] diff --git a/iota-execution/latest/iota-adapter/Cargo.toml b/iota-execution/latest/iota-adapter/Cargo.toml index 452e5c1dd45..93461caa5c7 100644 --- a/iota-execution/latest/iota-adapter/Cargo.toml +++ b/iota-execution/latest/iota-adapter/Cargo.toml @@ -37,10 +37,9 @@ move-vm-runtime = { path = "../../../external-crates/move/crates/move-vm-runtime move-vm-types.workspace = true [features] -gas-profiler = [ - "iota-types/gas-profiler", - "move-vm-config/gas-profiler", - "move-vm-profiler/gas-profiler", - "move-vm-runtime/gas-profiler", - "move-vm-types/gas-profiler", +tracing = [ + "iota-types/tracing", + "move-vm-config/tracing", + "move-vm-profiler/tracing", + "move-vm-runtime/tracing", ] diff --git a/iota-execution/latest/iota-adapter/src/adapter.rs b/iota-execution/latest/iota-adapter/src/adapter.rs index 295facc2e8f..e85d25989ea 100644 --- a/iota-execution/latest/iota-adapter/src/adapter.rs +++ b/iota-execution/latest/iota-adapter/src/adapter.rs @@ -24,7 +24,7 @@ mod checked { use move_bytecode_verifier::verify_module_with_config_metered; use move_bytecode_verifier_meter::{Meter, Scope}; use move_core_types::account_address::AccountAddress; - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] use move_vm_config::runtime::VMProfilerConfig; use move_vm_config::{ runtime::{VMConfig, VMRuntimeLimitsConfig}, @@ -47,9 +47,9 @@ mod checked { protocol_config: &ProtocolConfig, _enable_profiler: Option, ) -> Result { - #[cfg(not(feature = "gas-profiler"))] + #[cfg(not(feature = "tracing"))] let vm_profiler_config = None; - #[cfg(feature = "gas-profiler")] + #[cfg(feature = "tracing")] let vm_profiler_config = _enable_profiler.clone().map(|path| VMProfilerConfig { full_path: path, track_bytecode_instructions: false, @@ -73,6 +73,7 @@ mod checked { binary_config: to_binary_config(protocol_config), rethrow_serialization_type_layout_errors: protocol_config .rethrow_serialization_type_layout_errors(), + max_type_to_layout_nodes: None, // protocol_config.max_type_to_layout_nodes_as_option(), }) .map_err(|_| IotaError::ExecutionInvariantViolation) } diff --git a/iota-execution/latest/iota-adapter/src/programmable_transactions/context.rs b/iota-execution/latest/iota-adapter/src/programmable_transactions/context.rs index cfe7ff20ee5..d1a0d63869b 100644 --- a/iota-execution/latest/iota-adapter/src/programmable_transactions/context.rs +++ b/iota-execution/latest/iota-adapter/src/programmable_transactions/context.rs @@ -200,7 +200,7 @@ mod checked { // Set the profiler if in CLI #[skip_checked_arithmetic] - move_vm_profiler::gas_profiler_feature_enabled! { + move_vm_profiler::tracing_feature_enabled! { use move_vm_profiler::GasProfiler; use move_vm_types::gas::GasMeter; diff --git a/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs b/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs index 60dff0ae180..f471314560c 100644 --- a/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs +++ b/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs @@ -709,16 +709,7 @@ mod checked { UpgradePolicy::Additive => InclusionCheck::Subset.check(cur_module, new_module), UpgradePolicy::DepOnly => InclusionCheck::Equal.check(cur_module, new_module), UpgradePolicy::Compatible => { - let compatibility = Compatibility { - check_datatype_and_pub_function_linking: true, - check_datatype_layout: true, - check_friend_linking: false, - check_private_entry_linking: false, - disallowed_new_abilities: AbilitySet::ALL, - disallow_change_datatype_type_params: true, - // We disallow adding new variants to enums for now - disallow_new_variants: true, - }; + let compatibility = Compatibility::upgrade_check(); compatibility.check(cur_module, new_module) } diff --git a/iota-execution/latest/iota-move-natives/src/object_runtime/mod.rs b/iota-execution/latest/iota-move-natives/src/object_runtime/mod.rs index 099f3c8537d..21fa434dfe9 100644 --- a/iota-execution/latest/iota-move-natives/src/object_runtime/mod.rs +++ b/iota-execution/latest/iota-move-natives/src/object_runtime/mod.rs @@ -696,10 +696,13 @@ pub fn get_all_uids( struct UIDTraversalV1<'i>(&'i mut BTreeSet); struct UIDCollectorV1<'i>(&'i mut BTreeSet); - impl AV::Traversal for UIDTraversalV1<'_> { + impl<'i, 'b, 'l> AV::Traversal<'b, 'l> for UIDTraversalV1<'i> { type Error = AV::Error; - fn traverse_struct(&mut self, driver: &mut AV::StructDriver) -> Result<(), Self::Error> { + fn traverse_struct( + &mut self, + driver: &mut AV::StructDriver<'_, 'b, 'l>, + ) -> Result<(), Self::Error> { if driver.struct_layout().type_ == UID::type_() { while driver.next_field(&mut UIDCollectorV1(self.0))?.is_some() {} } else { @@ -709,9 +712,13 @@ pub fn get_all_uids( } } - impl AV::Traversal for UIDCollectorV1<'_> { + impl<'i, 'b, 'l> AV::Traversal<'b, 'l> for UIDCollectorV1<'i> { type Error = AV::Error; - fn traverse_address(&mut self, value: AccountAddress) -> Result<(), Self::Error> { + fn traverse_address( + &mut self, + _driver: &AV::ValueDriver<'_, 'b, 'l>, + value: AccountAddress, + ) -> Result<(), Self::Error> { self.0.insert(value.into()); Ok(()) }

<8iM-}q91e5BrX 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 SSN*Hh;jWH>cKPimVgC;zBo*QS literal 0 HcmV?d00001 diff --git a/external-crates/move/tooling/prettier-extension/jsconfig.json b/external-crates/move/tooling/prettier-extension/jsconfig.json new file mode 100644 index 00000000000..dbdd228c54d --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/jsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "Node16", + "target": "ES2022", + "checkJs": false, /* Typecheck .js files. */ + "lib": [ + "ES2022" + ] + }, + "exclude": [ + "node_modules" + ] +} diff --git a/external-crates/move/tooling/prettier-extension/package-lock.json b/external-crates/move/tooling/prettier-extension/package-lock.json new file mode 100644 index 00000000000..a87fffe3c0f --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/package-lock.json @@ -0,0 +1,2937 @@ +{ + "name": "prettier-move", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "prettier-move", + "version": "0.1.0", + "license": "Apache-2.0", + "dependencies": { + "@iota/prettier-plugin-move": "^0.1.1", + "cosmiconfig": "^9.0.0", + "prettier": "^3.3.2" + }, + "devDependencies": { + "@vscode/vsce": "^3.2.1" + }, + "engines": { + "vscode": "^1.80.0" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz", + "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz", + "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.18.0.tgz", + "integrity": "sha512-QSoGUp4Eq/gohEFNJaUOwTN7BCc2nHTjjbm75JT0aD7W65PWM1H/tItz0GsABn22uaKyGxiMhWQLt2r+FGU89Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.8.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", + "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz", + "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.5.0.tgz", + "integrity": "sha512-EknvVmtBuSIic47xkOqyNabAme0RYTw52BTMz8eBgU1ysTyMrD1uOoM+JdS0J/4Yfp98IBT3osqq3BfwSaNaGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^3.26.1", + "@azure/msal-node": "^2.15.0", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz", + "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.27.0.tgz", + "integrity": "sha512-+b4ZKSD8+vslCtVRVetkegEhOFMLP3rxDWJY212ct+2r6jVg6OSQKc1Qz3kCoXo0FgwaXkb+76TMZfpHp8QtgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "14.16.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz", + "integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.2.tgz", + "integrity": "sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "14.16.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@iota/prettier-plugin-move": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@iota/prettier-plugin-move/-/prettier-plugin-move-0.1.1.tgz", + "integrity": "sha512-sxs6ER3hyHTGoCmvgv0XFA0oUHZK5kh91OGageKEu2NEjuhn8ZccNFKrdrDAC0idPQOfygS7wgc0vIhr/S/BNA==", + "license": "Apache-2.0", + "dependencies": { + "prettier": "^3.3.2", + "web-tree-sitter": "^0.20.8" + } + }, + "node_modules/@vscode/vsce": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.1.tgz", + "integrity": "sha512-AY9vBjwExakK1c0cI/3NN2Ey0EgiKLBye/fxl/ue+o4q6RZ7N+xzd1jAD6eI6eBeMVANi617+V2rxIAkDPco2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/identity": "^4.1.0", + "@vscode/vsce-sign": "^2.0.0", + "azure-devops-node-api": "^12.5.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.9", + "cockatiel": "^3.1.2", + "commander": "^6.2.1", + "form-data": "^4.0.0", + "glob": "^11.0.0", + "hosted-git-info": "^4.0.2", + "jsonc-parser": "^3.2.0", + "leven": "^3.1.0", + "markdown-it": "^14.1.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^7.5.2", + "tmp": "^0.2.3", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.5.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "vsce" + }, + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "keytar": "^7.7.0" + } + }, + "node_modules/@vscode/vsce-sign": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.5.tgz", + "integrity": "sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optionalDependencies": { + "@vscode/vsce-sign-alpine-arm64": "2.0.2", + "@vscode/vsce-sign-alpine-x64": "2.0.2", + "@vscode/vsce-sign-darwin-arm64": "2.0.2", + "@vscode/vsce-sign-darwin-x64": "2.0.2", + "@vscode/vsce-sign-linux-arm": "2.0.2", + "@vscode/vsce-sign-linux-arm64": "2.0.2", + "@vscode/vsce-sign-linux-x64": "2.0.2", + "@vscode/vsce-sign-win32-arm64": "2.0.2", + "@vscode/vsce-sign-win32-x64": "2.0.2" + } + }, + "node_modules/@vscode/vsce-sign-alpine-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz", + "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-alpine-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz", + "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz", + "integrity": "sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz", + "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz", + "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz", + "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz", + "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-win32-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz", + "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/vsce-sign-win32-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz", + "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/vsce/node_modules/azure-devops-node-api": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz", + "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "node_modules/@vscode/vsce/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vscode/vsce/node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/vsce/node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/@vscode/vsce/node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/@vscode/vsce/node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vscode/vsce/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@vscode/vsce/node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vscode/vsce/node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/cockatiel": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz", + "integrity": "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-abi": { + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.1.0" + } + }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC" + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web-tree-sitter": { + "version": "0.20.8", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.8.tgz", + "integrity": "sha512-weOVgZ3aAARgdnb220GqYuh7+rZU0Ka9k9yfKtGAzEYMa6GgiCzW9JjQRJyCJakvibQW+dfjJdihjInKuuCAUQ==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3" + } + } + } +} diff --git a/external-crates/move/tooling/prettier-extension/package.json b/external-crates/move/tooling/prettier-extension/package.json new file mode 100644 index 00000000000..69e8b8005a6 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/package.json @@ -0,0 +1,86 @@ +{ + "name": "prettier-move", + "publisher": "IOTA Foundation", + "displayName": "Move Formatter Developer Preview", + "description": "Adds Move code formatting to VSCode using Prettier@v3", + "version": "0.1.0", + "private": true, + "preview": true, + "icon": "img/move.png", + "license": "Apache-2.0", + "browser": "./src/extension.js", + "main": "./src/extension.js", + "repository": { + "type": "git", + "url": "https://github.com/iotaledger/iota.git", + "directory": "external-crates/move/tooling/prettier-extension" + }, + "engines": { + "vscode": "^1.80.0" + }, + "categories": [ + "Formatters" + ], + "activationEvents": [ + "onLanguage:move" + ], + "contributes": { + "configuration": { + "title": "prettierMove", + "properties": { + "prettierMove.errorDebugMode": { + "type": "boolean", + "default": false, + "description": "Print failing nodes for debugging" + }, + "prettierMove.printWidth": { + "type": "number", + "default": 100, + "description": "Set `printWidth` in prettier" + }, + "prettierMove.tabWidth": { + "type": "number", + "default": 4, + "description": "Set `tabWidth` in prettier" + }, + "prettierMove.useModuleLabel": { + "type": "boolean", + "default": true, + "description": "Use module label instead of module body" + }, + "prettierMove.wrapComments": { + "type": "boolean", + "default": false, + "description": "Wrap comments if they exceed print width" + }, + "prettierMove.autoGroupImports": { + "type": "string", + "default": "module", + "enum": [ + "module", + "package" + ], + "description": "Group imports in the file by `module` or `package`" + } + } + }, + "configurationDefaults": { + "[move]": { + "editor.defaultFormatter": "iota.prettier-move" + } + } + }, + "scripts": { + "package": "vsce package", + "lint": "pnpm run eslint:check && pnpm run prettier:check", + "lint:fix": "pnpm run eslint:fix && pnpm run prettier:fix" + }, + "dependencies": { + "@iota/prettier-plugin-move": "^0.1.1", + "cosmiconfig": "^9.0.0", + "prettier": "^3.3.2" + }, + "devDependencies": { + "@vscode/vsce": "^3.2.1" + } +} diff --git a/external-crates/move/tooling/prettier-extension/src/extension.js b/external-crates/move/tooling/prettier-extension/src/extension.js new file mode 100644 index 00000000000..e1b3e2c5118 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/src/extension.js @@ -0,0 +1,132 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +const path = require('path'); +const vscode = require('vscode'); +const prettier = require('prettier'); +const { cosmiconfigSync: cosmiconfig } = require('cosmiconfig'); +const { Worker } = require('node:worker_threads'); + +/** + * Extension name must match the name in `package.json`, as it is the way to + * read the configuration settings. + */ +const EXTENSION_NAME = 'prettierMove'; + +/** + * Max time to wait for the worker to respond. + */ +const WAIT_TIME = 5000; + +/** + * Stores the worker instance. + */ +let worker; + +/** + * Output channel to display messages. + */ +const channel = vscode.window.createOutputChannel('Prettier Move'); + +/** + * Start the worker and register the document range formatting provider. + * Upon activation, the extension reads the configuration settings in the following order: + * + * - .prettierrc + * - Extension settings + * - Prettier extension settings + */ +function activate(context) { + worker = new Worker(path.join(__dirname, 'formatter-worker.js')); + const langs = [ + { scheme: 'file', language: 'move' }, + { scheme: 'untitled', language: 'move' }, + ]; + + context.subscriptions.push( + vscode.languages.registerDocumentRangeFormattingEditProvider(langs, { + provideDocumentRangeFormattingEdits: async (document, range, _opts, token) => { + const options = await findMatchingConfig(document.uri); + + // send the text and options to the worker + worker.postMessage(JSON.stringify({ text: document.getText(), options })); + + // wait for the worker to send the formatted text back. If it + // takes longer than 5 seconds, reject the promise. + const edited = await new Promise((resolve, reject) => { + setTimeout(() => reject(), WAIT_TIME); + worker.once('message', ({ text, message }) => { + message && channel.appendLine(message); + resolve(text); + }); + }); + + return [vscode.TextEdit.replace(range, edited)]; + }, + }), + ); +} + +/** + * For the given filepath, seach for one of the following configuration files: + * - .prettierrc (prettier.json etc) + * + * Alternatively use (in order, if set): + * - Extension settings + * - Prettier extension settings + */ +async function findMatchingConfig(documentUri) { + const root = vscode.workspace.getWorkspaceFolder(documentUri).uri.path; + let lookup = documentUri.path; + let search = {}; + + // go back in the directory until the root is found; or until we find the + // .prettierrc (.json | .yml) file + while (lookup !== root && lookup !== '/') { + lookup = path.join(lookup, '..'); + + const prettierConfig = cosmiconfig('prettier', { + searchPlaces: [ + '.prettierrc', + '.prettierrc.json', + '.prettierrc.yaml', + '.prettierrc.yml', + '.prettierrc.js', + 'prettier.config.js', + ], + }).search(lookup); + + if (prettierConfig) { + channel.appendLine(`Found a prettier config at ${prettierConfig.filepath}`); + search = prettierConfig.config; + channel.append(JSON.stringify(search, null, 2)); + break; + } + } + + const formatterConfig = vscode.workspace.getConfiguration(EXTENSION_NAME); + + return { + tabWidth: formatterConfig.get('tabWidth'), + printWidth: formatterConfig.get('printWidth'), + wrapComments: formatterConfig.get('wrapComments'), + useModuleLabel: formatterConfig.get('useModuleLabel'), + autoGroupImports: formatterConfig.get('autoGroupImports'), + enableErrorDebug: formatterConfig.get('errorDebugMode'), + ...search, // .prettierrc overrides the extension settings + }; +} + +/** + * Deactivate the extension by terminating the worker. + */ +function deactivate() { + worker && worker.terminate(); + channel.dispose(); +} + +module.exports = { + activate, + deactivate, +}; diff --git a/external-crates/move/tooling/prettier-extension/src/formatter-worker.js b/external-crates/move/tooling/prettier-extension/src/formatter-worker.js new file mode 100644 index 00000000000..0d26d5d0bb4 --- /dev/null +++ b/external-crates/move/tooling/prettier-extension/src/formatter-worker.js @@ -0,0 +1,30 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const plugin = require('@iota/prettier-plugin-move'); +const { format } = require('prettier'); +const { parentPort } = require('node:worker_threads'); + +/** + * Upon receiving a message from the parent thread, format the text and send it + * back. If an error occurs, send the original text back with the error message. + */ +parentPort.on('message', async (message) => { + const { text, options } = JSON.parse(message); + + return format(text, { + parser: 'move-parse', + plugins: [plugin], + tabWidth: options.tabWidth, + printWidth: options.printWidth, + wrapComments: options.wrapComments, + useModuleLabel: options.useModuleLabel, + autoGroupImports: options.autoGroupImports, + enableErrorDebug: options.enableErrorDebug, + }) + .then((text) => parentPort.postMessage({ text })) + .catch((err) => parentPort.postMessage({ text, message: err.message })); +}); diff --git a/external-crates/move/tooling/prettier-move/.gitignore b/external-crates/move/tooling/prettier-move/.gitignore new file mode 100644 index 00000000000..5df8049bff2 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/.gitignore @@ -0,0 +1,2 @@ +out +node_modules diff --git a/external-crates/move/tooling/prettier-move/.npmignore b/external-crates/move/tooling/prettier-move/.npmignore new file mode 100644 index 00000000000..a888e5fe1ec --- /dev/null +++ b/external-crates/move/tooling/prettier-move/.npmignore @@ -0,0 +1,3 @@ +node_modules +tests +scripts diff --git a/external-crates/move/tooling/prettier-move/CHANGELOG.md b/external-crates/move/tooling/prettier-move/CHANGELOG.md new file mode 100644 index 00000000000..9d8e9360717 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/CHANGELOG.md @@ -0,0 +1,29 @@ +# @iota/prettier-plugin-move + +## 0.2.1 + +### Patch Changes + +- 360e9a2: Fixes missing parser for move-parser error + +## 0.2.0 + +### Minor Changes + +- 53387ff: - parser rename "move-parser" -> "move" + - adds `prettier-move` bin when installed globally + - better comments handling in empty blocks + - sorts abilities alphabetically, but `key` always first + - no longer inserts block in `if_expression` if expression breaks + +## 0.1.1 + +### Patch Changes + +- e1a85c2: fixes publishing issue, compiles prepublish + +## 0.1.0 + +### Minor Changes + +- 9521492: Initial version of the prettier-plugin-move diff --git a/external-crates/move/tooling/prettier-move/CONTRIBUTING.md b/external-crates/move/tooling/prettier-move/CONTRIBUTING.md new file mode 100644 index 00000000000..a297cc32e4e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +If you decide to contribute to this project, please choose the scope of your contribution (e.g., +implement formatting for structs) and file an issue in the Iota +[repository](https://github.com/iotaledger/iota) describing the work you plan to do, and wait for a +response from a core team member so that we can avoid duplication of efforts. + +Please make sure that the code you add is well documented and that you add relevant tests - please +use existing code as guidance. + +## Build and Test + +To run build and test, use these commands: + +```shell +pnpm build +pnpm test +``` + +## Updating Snapshots + +To update snapshots in tests, use `UB=1` (update baseline) env variable: + +```shell +UB=1 pnpm test +``` + +## Changeset + +Make sure to run `pnpm changeset` with appropriate version for the changes made. Commit the change, +so that it is picked up by CI. diff --git a/external-crates/move/tooling/prettier-move/README.md b/external-crates/move/tooling/prettier-move/README.md new file mode 100644 index 00000000000..d52aa41c990 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/README.md @@ -0,0 +1,96 @@ +# Prettier Move Plugin + +This is a Move language plugin for the +[Prettier](https://prettier.io/) code formatter. It uses a Move +[parser](https://github.com/tzakian/tree-sitter-move) built on top of the +[tree-sitter](https://tree-sitter.github.io/) parser generator and maintained by Tim Zakian. + +The plugin is platform-independent by utilizing a [WASM](https://webassembly.org/)-ified version of +the Move parser included in this repository at +[(./tree-sitter-move.wasm)](./tree-sitter-move.wasm). You can re-generate the WASM-ified version of +the parser by running the [scripts/treesitter-wasm-gen.sh](scripts/treesitter-wasm-gen.sh) script +(prerequisites for this are listed in the script itself). You should be careful when doing so, as +certain changes to the parser may break the plugin (e.g., if parse tree node types are modified). + +## Prerequisites + +Requires [nodejs 18+](https://nodejs.org/en) installed. + +## Usage (Global, CLI) + +For CLI usage, you can install the plugin globally by running the following command: + +```bash +npm i -g prettier @iota/prettier-plugin-move +``` + +Then there will be a registered executable `prettier-move` which works exactly like a regular `prettier` one, except that it automatically inserts the path to the plugin as an argument. + +```bash +prettier-move -c sources/example.move # to check +prettier-move -w sources/example.move # to write +``` + +This command is identical to the following: + +```bash +prettier --plugin /path/to/local/npm/node_modules/@iota/prettier-plugin-move/out/index.js -c sources/example.move # to check +prettier --plugin /path/to/local/npm/node_modules/@iota/prettier-plugin-move/out/index.js -w sources/example.move # to write +``` + +## Installation (Per-Project) + +If you decide to use the plugin per-project, you can install it in the project's directory. This way, +the plugin will be available via `prettier` call in the project's directory. + +```bash +# install as a dev-dependency +npm i -D prettier @iota/prettier-plugin-move +``` + +Add the `.prettierrc` or a similar configuration file (see [all supported formats](https://prettier.io/docs/en/configuration.html)): + +```json +{ + "printWidth": 100, + "tabWidth": 4, + "useModuleLabel": true, + "autoGroupImports": "module", + "plugins": ["@iota/prettier-plugin-move"] +} +``` + +Then you can run prettier either via adding a script to `package.json`: + +```json +{ + "scripts": { + "prettier": "prettier --write ." + } +} +``` + +```bash +npm run prettier -w sources/example.move +``` + +Or, if you have prettier installed globally, you can run it directly: + +```bash +prettier --write sources/example.move +``` + +## VSCode integration + +There is a bundled [Move Formatter](https://marketplace.visualstudio.com/items?itemName=iota.prettier-move) extension for VSCode. It will detect prettier configuration for the workspace and use +the plugin automatically. + +Alternatively, if you follow the per-project installation, [regular Pretter extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) should work as well. + +## Known Integrations + +- Neovim: see [this commit](https://github.com/amnn/nvim/commit/26236dc08162b61f95f689e232a5df2418708339) for configuration + +## Contribute + +See [CONTRIBUTING](./CONTRIBUTING.md). diff --git a/external-crates/move/tooling/prettier-move/bin/prettier-move.js b/external-crates/move/tooling/prettier-move/bin/prettier-move.js new file mode 100755 index 00000000000..44c86a7373c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/bin/prettier-move.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +// use the +const path = require('path'); +const plugin_path = path.resolve(__dirname, '..', 'out', 'index.js'); +const child_process = require('child_process'); + +// command is prettier + plugin path + args passed to the script +const args = process.argv.slice(2); + +// check that prettier is installed +try { + child_process.execFileSync('prettier', ['--version']); +} catch (e) { + console.error('Prettier is not installed. Please install it by running `npm install -g prettier`.'); + process.exit(1); +} + +// run prettier, print the output and exit with correct code +const prettier = child_process.execFile( + 'prettier', + args.length ? ['--plugin', plugin_path, ...args] : ['--help'], +); + +// additionally, exchange stdin/stdout/stderr with the prettier process +process.stdin.pipe(prettier.stdin); +prettier.stdout.pipe(process.stdout); +prettier.stderr.pipe(process.stderr); +prettier.on('exit', (code) => process.exit(code)); diff --git a/external-crates/move/tooling/prettier-move/package-lock.json b/external-crates/move/tooling/prettier-move/package-lock.json new file mode 100644 index 00000000000..0b6c6957edc --- /dev/null +++ b/external-crates/move/tooling/prettier-move/package-lock.json @@ -0,0 +1,1770 @@ +{ + "name": "prettier-plugin-move", + "version": "0.0.55", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "prettier-plugin-move", + "version": "0.0.55", + "license": "Apache-2.0", + "dependencies": { + "prettier": "^3.3.3", + "web-tree-sitter": "^0.20.8" + }, + "devDependencies": { + "@types/diff": "^5.2.1", + "@types/node": "^20.10.6", + "diff": "^5.2.0", + "typescript": "^5.5.4", + "vitest": "^1.6.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.4.tgz", + "integrity": "sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.4.tgz", + "integrity": "sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.4.tgz", + "integrity": "sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.4.tgz", + "integrity": "sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.4.tgz", + "integrity": "sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.4.tgz", + "integrity": "sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.4.tgz", + "integrity": "sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.4.tgz", + "integrity": "sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.4.tgz", + "integrity": "sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.4.tgz", + "integrity": "sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.4.tgz", + "integrity": "sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.4.tgz", + "integrity": "sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.4.tgz", + "integrity": "sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.4.tgz", + "integrity": "sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.4.tgz", + "integrity": "sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.4.tgz", + "integrity": "sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.4.tgz", + "integrity": "sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.4.tgz", + "integrity": "sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/diff": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.3.tgz", + "integrity": "sha512-K0Oqlrq3kQMaO2RhfrNQX5trmt+XLyom88zS0u84nnIcLvFnRUMRRHmrGny5GSM+kNO9IZLARsdQHDzkhAgmrQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.17.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", + "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mlly": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", + "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.4.tgz", + "integrity": "sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.4", + "@rollup/rollup-android-arm64": "4.24.4", + "@rollup/rollup-darwin-arm64": "4.24.4", + "@rollup/rollup-darwin-x64": "4.24.4", + "@rollup/rollup-freebsd-arm64": "4.24.4", + "@rollup/rollup-freebsd-x64": "4.24.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.4", + "@rollup/rollup-linux-arm-musleabihf": "4.24.4", + "@rollup/rollup-linux-arm64-gnu": "4.24.4", + "@rollup/rollup-linux-arm64-musl": "4.24.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.4", + "@rollup/rollup-linux-riscv64-gnu": "4.24.4", + "@rollup/rollup-linux-s390x-gnu": "4.24.4", + "@rollup/rollup-linux-x64-gnu": "4.24.4", + "@rollup/rollup-linux-x64-musl": "4.24.4", + "@rollup/rollup-win32-arm64-msvc": "4.24.4", + "@rollup/rollup-win32-ia32-msvc": "4.24.4", + "@rollup/rollup-win32-x64-msvc": "4.24.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/web-tree-sitter": { + "version": "0.20.8", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.8.tgz", + "integrity": "sha512-weOVgZ3aAARgdnb220GqYuh7+rZU0Ka9k9yfKtGAzEYMa6GgiCzW9JjQRJyCJakvibQW+dfjJdihjInKuuCAUQ==", + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/external-crates/move/tooling/prettier-move/package.json b/external-crates/move/tooling/prettier-move/package.json new file mode 100644 index 00000000000..b4ebf8c72c2 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/package.json @@ -0,0 +1,34 @@ +{ + "name": "@iota/prettier-plugin-move", + "author": "IOTA Foundation ", + "description": "Move Plugin for Prettier", + "version": "0.2.1", + "license": "Apache-2.0", + "keywords": [ + "prettier", + "move", + "plugin" + ], + "bin": { + "prettier-move": "./bin/prettier-move.js" + }, + "main": "./out/index.js", + "scripts": { + "prepublishOnly": "pnpm build", + "build": "tsc -p .", + "watch": "tsc -p . -w", + "test": "npm run build && vitest run", + "prettier": "npm run build && prettier --plugin out/index.js" + }, + "dependencies": { + "prettier": "^3.3.2", + "web-tree-sitter": "^0.20.8" + }, + "devDependencies": { + "@types/diff": "^5.2.1", + "@types/node": "^20.14.10", + "diff": "^5.2.0", + "typescript": "^5.5.3", + "vitest": "^2.0.1" + } +} diff --git a/external-crates/move/tooling/prettier-move/pnpm-lock.yaml b/external-crates/move/tooling/prettier-move/pnpm-lock.yaml new file mode 100644 index 00000000000..392354ee886 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/pnpm-lock.yaml @@ -0,0 +1,1413 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + prettier: + specifier: ^3.3.3 + version: 3.3.3 + web-tree-sitter: + specifier: ^0.20.8 + version: 0.20.8 + devDependencies: + '@types/diff': + specifier: ^5.2.1 + version: 5.2.1 + '@types/node': + specifier: ^20.10.6 + version: 20.10.6 + diff: + specifier: ^5.2.0 + version: 5.2.0 + typescript: + specifier: ^5.5.4 + version: 5.5.4 + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@20.10.6) + +packages: + '@esbuild/aix-ppc64@0.21.5': + resolution: + { + integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, + } + engines: { node: '>=12' } + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: + { + integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, + } + engines: { node: '>=12' } + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: + { + integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, + } + engines: { node: '>=12' } + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: + { + integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: + { + integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, + } + engines: { node: '>=12' } + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: + { + integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: + { + integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, + } + engines: { node: '>=12' } + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: + { + integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: + { + integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, + } + engines: { node: '>=12' } + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: + { + integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, + } + engines: { node: '>=12' } + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: + { + integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, + } + engines: { node: '>=12' } + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: + { + integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, + } + engines: { node: '>=12' } + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: + { + integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, + } + engines: { node: '>=12' } + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: + { + integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, + } + engines: { node: '>=12' } + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: + { + integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, + } + engines: { node: '>=12' } + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: + { + integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, + } + engines: { node: '>=12' } + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: + { + integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: + { + integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: + { + integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: + { + integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: + { + integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, + } + engines: { node: '>=12' } + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: + { + integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, + } + engines: { node: '>=12' } + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: + { + integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, + } + engines: { node: '>=12' } + cpu: [x64] + os: [win32] + + '@jest/schemas@29.6.3': + resolution: + { + integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: + { + integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==, + } + + '@rollup/rollup-android-arm-eabi@4.18.0': + resolution: + { + integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==, + } + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.18.0': + resolution: + { + integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==, + } + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.18.0': + resolution: + { + integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==, + } + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.18.0': + resolution: + { + integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==, + } + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + resolution: + { + integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==, + } + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + resolution: + { + integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==, + } + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + resolution: + { + integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==, + } + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.18.0': + resolution: + { + integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==, + } + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + resolution: + { + integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==, + } + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + resolution: + { + integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==, + } + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + resolution: + { + integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==, + } + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.18.0': + resolution: + { + integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==, + } + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.18.0': + resolution: + { + integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==, + } + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + resolution: + { + integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==, + } + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + resolution: + { + integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==, + } + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.18.0': + resolution: + { + integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==, + } + cpu: [x64] + os: [win32] + + '@sinclair/typebox@0.27.8': + resolution: + { + integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, + } + + '@types/diff@5.2.1': + resolution: + { + integrity: sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g==, + } + + '@types/estree@1.0.5': + resolution: + { + integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==, + } + + '@types/node@20.10.6': + resolution: + { + integrity: sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==, + } + + '@vitest/expect@1.6.0': + resolution: + { + integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==, + } + + '@vitest/runner@1.6.0': + resolution: + { + integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==, + } + + '@vitest/snapshot@1.6.0': + resolution: + { + integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==, + } + + '@vitest/spy@1.6.0': + resolution: + { + integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==, + } + + '@vitest/utils@1.6.0': + resolution: + { + integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==, + } + + acorn-walk@8.3.3: + resolution: + { + integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, + } + engines: { node: '>=0.4.0' } + + acorn@8.12.0: + resolution: + { + integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==, + } + engines: { node: '>=0.4.0' } + hasBin: true + + ansi-styles@5.2.0: + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: '>=10' } + + assertion-error@1.1.0: + resolution: + { + integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==, + } + + cac@6.7.14: + resolution: + { + integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, + } + engines: { node: '>=8' } + + chai@4.4.1: + resolution: + { + integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==, + } + engines: { node: '>=4' } + + check-error@1.0.3: + resolution: + { + integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==, + } + + confbox@0.1.7: + resolution: + { + integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==, + } + + cross-spawn@7.0.3: + resolution: + { + integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, + } + engines: { node: '>= 8' } + + debug@4.3.5: + resolution: + { + integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==, + } + engines: { node: '>=6.0' } + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@4.1.4: + resolution: + { + integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==, + } + engines: { node: '>=6' } + + diff-sequences@29.6.3: + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + diff@5.2.0: + resolution: + { + integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==, + } + engines: { node: '>=0.3.1' } + + esbuild@0.21.5: + resolution: + { + integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==, + } + engines: { node: '>=12' } + hasBin: true + + estree-walker@3.0.3: + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } + + execa@8.0.1: + resolution: + { + integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==, + } + engines: { node: '>=16.17' } + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + get-func-name@2.0.2: + resolution: + { + integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==, + } + + get-stream@8.0.1: + resolution: + { + integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==, + } + engines: { node: '>=16' } + + human-signals@5.0.0: + resolution: + { + integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==, + } + engines: { node: '>=16.17.0' } + + is-stream@3.0.0: + resolution: + { + integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + + isexe@2.0.0: + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } + + js-tokens@9.0.0: + resolution: + { + integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==, + } + + local-pkg@0.5.0: + resolution: + { + integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==, + } + engines: { node: '>=14' } + + loupe@2.3.7: + resolution: + { + integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==, + } + + magic-string@0.30.10: + resolution: + { + integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==, + } + + merge-stream@2.0.0: + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } + + mimic-fn@4.0.0: + resolution: + { + integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, + } + engines: { node: '>=12' } + + mlly@1.7.1: + resolution: + { + integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==, + } + + ms@2.1.2: + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } + + nanoid@3.3.7: + resolution: + { + integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + npm-run-path@5.3.0: + resolution: + { + integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + + onetime@6.0.0: + resolution: + { + integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, + } + engines: { node: '>=12' } + + p-limit@5.0.0: + resolution: + { + integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==, + } + engines: { node: '>=18' } + + path-key@3.1.1: + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: '>=8' } + + path-key@4.0.0: + resolution: + { + integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, + } + engines: { node: '>=12' } + + pathe@1.1.2: + resolution: + { + integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==, + } + + pathval@1.1.1: + resolution: + { + integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==, + } + + picocolors@1.0.1: + resolution: + { + integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, + } + + pkg-types@1.1.1: + resolution: + { + integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==, + } + + postcss@8.4.38: + resolution: + { + integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==, + } + engines: { node: ^10 || ^12 || >=14 } + + prettier@3.3.3: + resolution: + { + integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, + } + engines: { node: '>=14' } + hasBin: true + + pretty-format@29.7.0: + resolution: + { + integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + react-is@18.3.1: + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } + + rollup@4.18.0: + resolution: + { + integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==, + } + engines: { node: '>=18.0.0', npm: '>=8.0.0' } + hasBin: true + + shebang-command@2.0.0: + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: '>=8' } + + shebang-regex@3.0.0: + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: '>=8' } + + siginfo@2.0.0: + resolution: + { + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, + } + + signal-exit@4.1.0: + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: '>=14' } + + source-map-js@1.2.0: + resolution: + { + integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==, + } + engines: { node: '>=0.10.0' } + + stackback@0.0.2: + resolution: + { + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, + } + + std-env@3.7.0: + resolution: + { + integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==, + } + + strip-final-newline@3.0.0: + resolution: + { + integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, + } + engines: { node: '>=12' } + + strip-literal@2.1.0: + resolution: + { + integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==, + } + + tinybench@2.8.0: + resolution: + { + integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==, + } + + tinypool@0.8.4: + resolution: + { + integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==, + } + engines: { node: '>=14.0.0' } + + tinyspy@2.2.1: + resolution: + { + integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==, + } + engines: { node: '>=14.0.0' } + + type-detect@4.0.8: + resolution: + { + integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, + } + engines: { node: '>=4' } + + typescript@5.5.4: + resolution: + { + integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, + } + engines: { node: '>=14.17' } + hasBin: true + + ufo@1.5.3: + resolution: + { + integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==, + } + + undici-types@5.26.5: + resolution: + { + integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, + } + + vite-node@1.6.0: + resolution: + { + integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==, + } + engines: { node: ^18.0.0 || >=20.0.0 } + hasBin: true + + vite@5.3.1: + resolution: + { + integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==, + } + engines: { node: ^18.0.0 || >=20.0.0 } + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@1.6.0: + resolution: + { + integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==, + } + engines: { node: ^18.0.0 || >=20.0.0 } + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + web-tree-sitter@0.20.8: + resolution: + { + integrity: sha512-weOVgZ3aAARgdnb220GqYuh7+rZU0Ka9k9yfKtGAzEYMa6GgiCzW9JjQRJyCJakvibQW+dfjJdihjInKuuCAUQ==, + } + + which@2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: '>= 8' } + hasBin: true + + why-is-node-running@2.2.2: + resolution: + { + integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==, + } + engines: { node: '>=8' } + hasBin: true + + yocto-queue@1.0.0: + resolution: + { + integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==, + } + engines: { node: '>=12.20' } + +snapshots: + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@rollup/rollup-android-arm-eabi@4.18.0': + optional: true + + '@rollup/rollup-android-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-x64@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.18.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.18.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.18.0': + optional: true + + '@sinclair/typebox@0.27.8': {} + + '@types/diff@5.2.1': {} + + '@types/estree@1.0.5': {} + + '@types/node@20.10.6': + dependencies: + undici-types: 5.26.5 + + '@vitest/expect@1.6.0': + dependencies: + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.4.1 + + '@vitest/runner@1.6.0': + dependencies: + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.6.0': + dependencies: + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.6.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.6.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.0 + + acorn@8.12.0: {} + + ansi-styles@5.2.0: {} + + assertion-error@1.1.0: {} + + cac@6.7.14: {} + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + confbox@0.1.7: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + deep-eql@4.1.4: + dependencies: + type-detect: 4.0.8 + + diff-sequences@29.6.3: {} + + diff@5.2.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + fsevents@2.3.3: + optional: true + + get-func-name@2.0.2: {} + + get-stream@8.0.1: {} + + human-signals@5.0.0: {} + + is-stream@3.0.0: {} + + isexe@2.0.0: {} + + js-tokens@9.0.0: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.1 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + merge-stream@2.0.0: {} + + mimic-fn@4.0.0: {} + + mlly@1.7.1: + dependencies: + acorn: 8.12.0 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + + ms@2.1.2: {} + + nanoid@3.3.7: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.0.0 + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + picocolors@1.0.1: {} + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prettier@3.3.3: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + react-is@18.3.1: {} + + rollup@4.18.0: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.18.0 + '@rollup/rollup-android-arm64': 4.18.0 + '@rollup/rollup-darwin-arm64': 4.18.0 + '@rollup/rollup-darwin-x64': 4.18.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 + '@rollup/rollup-linux-arm-musleabihf': 4.18.0 + '@rollup/rollup-linux-arm64-gnu': 4.18.0 + '@rollup/rollup-linux-arm64-musl': 4.18.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 + '@rollup/rollup-linux-riscv64-gnu': 4.18.0 + '@rollup/rollup-linux-s390x-gnu': 4.18.0 + '@rollup/rollup-linux-x64-gnu': 4.18.0 + '@rollup/rollup-linux-x64-musl': 4.18.0 + '@rollup/rollup-win32-arm64-msvc': 4.18.0 + '@rollup/rollup-win32-ia32-msvc': 4.18.0 + '@rollup/rollup-win32-x64-msvc': 4.18.0 + fsevents: 2.3.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.0: {} + + stackback@0.0.2: {} + + std-env@3.7.0: {} + + strip-final-newline@3.0.0: {} + + strip-literal@2.1.0: + dependencies: + js-tokens: 9.0.0 + + tinybench@2.8.0: {} + + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + + type-detect@4.0.8: {} + + typescript@5.5.4: {} + + ufo@1.5.3: {} + + undici-types@5.26.5: {} + + vite-node@1.6.0(@types/node@20.10.6): + dependencies: + cac: 6.7.14 + debug: 4.3.5 + pathe: 1.1.2 + picocolors: 1.0.1 + vite: 5.3.1(@types/node@20.10.6) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite@5.3.1(@types/node@20.10.6): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.38 + rollup: 4.18.0 + optionalDependencies: + '@types/node': 20.10.6 + fsevents: 2.3.3 + + vitest@1.6.0(@types/node@20.10.6): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + acorn-walk: 8.3.3 + chai: 4.4.1 + debug: 4.3.5 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 + pathe: 1.1.2 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.8.0 + tinypool: 0.8.4 + vite: 5.3.1(@types/node@20.10.6) + vite-node: 1.6.0(@types/node@20.10.6) + why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.10.6 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + web-tree-sitter@0.20.8: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.2.2: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + yocto-queue@1.0.0: {} diff --git a/external-crates/move/tooling/prettier-move/prettier.config.js b/external-crates/move/tooling/prettier-move/prettier.config.js new file mode 100644 index 00000000000..4f559bfd411 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/prettier.config.js @@ -0,0 +1,13 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module.exports = { + printWidth: 100, + semi: true, + singleQuote: true, + tabWidth: 4, + trailingComma: 'all', + useTabs: true, + overrides: [], +}; diff --git a/external-crates/move/tooling/prettier-move/scripts/treesitter-wasm-gen.sh b/external-crates/move/tooling/prettier-move/scripts/treesitter-wasm-gen.sh new file mode 100755 index 00000000000..990df6cfb20 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/scripts/treesitter-wasm-gen.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright (c) Mysten Labs, Inc. +# Modifications Copyright (c) 2024 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +# This scripts regenerates WASM bytecode representing the tree-sitter Move parser by wasm-ifying the +# tree-sitter Move parser created by Tim Zakian and available at +# https://github.com/tzakian/tree-sitter-move +# +# Pre-requisites: +# - npm (install on Mac: `brew install node`) +# - tree-sitter (install on Mac: `brew install tree-sitter`) +# - emscripten (install on Mac: `brew install emscripten`) + +# fail if there's no npm, tree-sitter or emscripten +if ! command -v npm &> /dev/null; then + echo "npm not found. Please install `node`." + exit 1 +fi + + +if ! command -v tree-sitter &> /dev/null; then + echo "tree-sitter not found. Please install `tree-sitter`." + exit 1 +fi + +if ! command -v emcc &> /dev/null; then + echo "emscripten not found. Please install `emscripten`." + exit 1 +fi + +set -e + +clean_tmp_dir() { + test -d "$TMP_DIR" && rm -fr "$TMP_DIR" +} + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TOPLEVEL="${DIR}/../" + +TMP_DIR=$( mktemp -d -t vscode-create ) +trap "clean_tmp_dir $TMP_DIR" EXIT + +TARGET_DIR=$TMP_DIR/"move-parser" + +git clone https://github.com/tzakian/tree-sitter-move.git $TARGET_DIR +cd $TARGET_DIR +npm install +tree-sitter build --wasm +cp $TARGET_DIR/tree-sitter-move.wasm $TOPLEVEL/ diff --git a/external-crates/move/tooling/prettier-move/src/cst/annotation.ts b/external-crates/move/tooling/prettier-move/src/cst/annotation.ts new file mode 100644 index 00000000000..fc9d569e2c4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/annotation.ts @@ -0,0 +1,72 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, doc, Doc } from 'prettier'; +import { list } from '../utilities'; +const { group, join } = doc.builders; + +export enum Annotation { + Annotation = 'annotation', + AnnotationItem = 'annotation_item', + AnnotationList = 'annotation_list', + AnnotationExpr = 'annotation_expr', +} + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case Annotation.Annotation: + return printAnnotation; + case Annotation.AnnotationItem: + return printAnnotationItem; + case Annotation.AnnotationList: + return printAnnotationList; + case Annotation.AnnotationExpr: + return printAnnotationExpr; + } + + return null; +} + +/** + * Print `annotation` node. + */ +export function printAnnotation(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group(['#', list({ path, print, options, open: '[', close: ']' })]); +} + +/** + * Print `annotation_item` node. + */ +export function printAnnotationItem(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return path.map(print, 'nonFormattingChildren'); +} + +export function printAnnotationList( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return [ + path.call(print, 'nonFormattingChildren', 0), + list({ path, print, options, open: '(', close: ')', skipChildren: 1 }), + ]; +} + +/** + * Print `annotation_expr` node. + */ +export function printAnnotationExpr(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + // allow `::module::Expression` in annotations + return join( + ' = ', + path.map((path) => { + if (path.node.type === 'module_access' && path.node.previousSibling?.type == '::') { + return ['::', path.call(print)]; + } + return path.call(print); + }, 'nonFormattingChildren'), + ); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/common.ts b/external-crates/move/tooling/prettier-move/src/cst/common.ts new file mode 100644 index 00000000000..a5846c1204c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/common.ts @@ -0,0 +1,388 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, doc, Doc } from 'prettier'; +import { list, printIdentifier, shouldBreakFirstChild } from '../utilities'; +const { group, ifBreak, softline, indent, join, line } = doc.builders; + +/** + * Creates a callback function to print common nodes. + */ +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case Common.PrimitiveType: + return printPrimitiveType; + case Common.ModuleAccess: + return printModuleAccess; + + // identifiers + case Common.Identifier: + case Common.FieldIdentifier: + case Common.VariableIdentifier: + return printIdentifier; + + case Common.RefType: + return printRefType; + case Common.FunctionType: + return printFunctionType; + case Common.FunctionTypeParameters: + return printFunctionTypeParameters; + + case Common.Ability: + return printAbility; + + case Common.TupleType: + return printTupleType; + + // === Bindings === + + case Common.BindUnpack: + return printBindUnpack; + case Common.BindFields: + return printBindFields; + case Common.BindField: + return printBindField; + case Common.BindList: + return printBindList; + case Common.CommaBindList: + return printCommaBindList; + case Common.OrBindList: + return printOrBindList; + case Common.AtBind: + return printAtBind; + case Common.BindNamedFields: + return printBindNamedFields; + case Common.BindPositionalFields: + return printBindPositionalFields; + case Common.BindVar: + return printBindVar; + + case Common.Label: + return printLabel; + case Common.Alias: + return printAlias; + case Common.BlockIdentifier: + return printBlockIdentifier; + case Common.UnaryOperator: + return printUnaryOperator; + case Common.FieldInitializeList: + return printFieldInitializeList; + case Common.ExpressionField: + return printExpressionField; + case Common.ArgList: + return printArgList; + } + + return null; +} + +/** + * Nodes which are used across multiple files, yet can't be categorized. + */ +export enum Common { + PrimitiveType = 'primitive_type', + VariableIdentifier = 'variable_identifier', + ModuleAccess = 'module_access', + Identifier = 'identifier', + RefType = 'ref_type', + FunctionType = 'function_type', + FunctionTypeParameters = 'function_type_parameters', + FieldIdentifier = 'field_identifier', + BlockIdentifier = 'block_identifier', + + Ability = 'ability', + TupleType = 'tuple_type', + + // === Bindings === + + BindUnpack = 'bind_unpack', + BindFields = 'bind_fields', + BindField = 'bind_field', + BindList = 'bind_list', + BindNamedFields = 'bind_named_fields', + CommaBindList = 'comma_bind_list', + OrBindList = 'or_bind_list', + AtBind = 'at_bind', + BindPositionalFields = 'bind_positional_fields', + BindVar = 'bind_var', + LambdaBindings = 'lambda_bindings', + + Label = 'label', + Alias = 'alias', + UnaryOperator = 'unary_op', + FieldInitializeList = 'field_initialize_list', + ExpressionField = 'exp_field', + + // used in `call_expression` and `macro_call_expression` + ArgList = 'arg_list', +} + +/** + * Print `primitive_type` node. + */ +export function printPrimitiveType(path: AstPath, _opt: MoveOptions, _p: printFn): Doc { + return path.node.text; +} + +/** + * Print `module_access` node. + */ +export function printModuleAccess(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return path.map(print, 'children'); +} + +/** + * Print `ref_type` node. + */ +export function printRefType(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const ref = path.node.child(0)!.text == '&' ? ['&'] : ['&mut ']; + return group([ + ...ref, + path.call(print, 'nonFormattingChildren', 0), // type + ]); +} + +/** + * Print `arg_list` node. + */ +function printArgList(path: AstPath, options: MoveOptions, print: printFn): Doc { + const nodes = path.node.nonFormattingChildren; + const children = path.map(print, 'nonFormattingChildren'); + + if (nodes.length === 1 && nodes[0]!.isBreakableExpression) { + return ['(', children[0]!, ')']; + } + + return group(list({ path, print, options, open: '(', close: ')' }), { + shouldBreak: shouldBreakFirstChild(path), + }); +} + +/** + * Print `ability` node. + */ +export function printAbility(path: AstPath, _opt: MoveOptions, _p: printFn): Doc { + return path.node.text; +} + +/** + * Print `tuple_type` node. + */ +export function printTupleType(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group( + list({ + path, + print, + options, + open: '(', + close: ')', + shouldBreak: false, + }), + ); +} + +// === Bindings === + +/** + * Print `bind_unpack` node. + * For easier seach: `unpack_expression`. + * + * Inside: + * - `bind_var` + * - `bind_fields` + * - `bind_fields` + * + * `let Struct { field1, field2 } = ...;` + */ +function printBindUnpack(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return path.map(print, 'nonFormattingChildren'); +} + +/** + * Print `bind_fields` node. + * Choice node between `bind_named_fields` and `bind_positional_fields`. + */ +function printBindFields(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return path.call(print, 'nonFormattingChildren', 0); +} + +/** + * Print `bind_field` node. + */ +function printBindField(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + // special case for `..` operator + if (path.node.child(0)?.type == '..') { + return '..'; + } + + // if there's only one child, we can just print it + // if there're two, they will be joined + return join( + ': ', + path.map((path) => { + if (path.node.type == Common.BindVar) return print(path); + return path.node.previousSibling?.type == 'mut' ? ['mut ', print(path)] : print(path); + }, 'nonFormattingChildren'), + ); +} + +/** + * Print `bind_list` node. + * In the bind list we have two paths: + * + * - one is just `bind_var` with potential `mut` + * - another is a list, and we know it because the first member is `(`. + */ +function printBindList(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.nonFormattingChildren.length == 1) { + return join(' ', path.map(print, 'nonFormattingChildren')); + } + + return group(list({ path, print, options, open: '(', close: ')' })); +} + +/** + * Print `comma_bind_list` node. + */ +function printCommaBindList(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group(list({ path, print, options, open: '(', close: ')' })); +} + +/** + * Print `at_bind` node. + */ +function printAtBind(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return join(' @ ', path.map(print, 'nonFormattingChildren')); +} + +/** + * Print `or_bind_list` node. + */ +function printOrBindList(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group(join([' |', line], path.map(print, 'nonFormattingChildren'))); +} + +/** + * Print `bind_named_fields` node. + */ +function printBindNamedFields(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [ + ' ', + group(list({ path, print, options, open: '{', close: '}', addWhitespace: true }), { + shouldBreak: shouldBreakFirstChild(path), + }), + ]; +} + +/** + * Print `bind_positional_fields` node. + */ +function printBindPositionalFields(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group(list({ path, print, options, open: '(', close: ')' }), { + shouldBreak: shouldBreakFirstChild(path), + }); +} + +/** + * Print `bind_var` node. + * + * If it has `mut` before the value, we print it. `mut` is not a named child. + */ +function printBindVar(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + let isMut = path.node.previousSibling?.type == 'mut'; + return [isMut ? ['mut '] : '', path.call(print, 'nonFormattingChildren', 0)]; +} + +/** + * Print `alias` node. ...as `identifier` + */ +export function printAlias(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return ['as ', path.call(print, 'nonFormattingChildren', 0)]; +} + +/** + * Print `block_identifier` node. + */ +function printBlockIdentifier(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return path.call(print, 'nonFormattingChildren', 0); +} + +/** + * Print `label` node. + */ +function printLabel(path: AstPath, _opt: MoveOptions, _p: printFn): Doc { + if (path.node.nextSibling?.type == ':') { + return [path.node.text, ':']; + } + + return path.node.text; +} + +/** + * Print `unary_op` node. + */ +function printUnaryOperator(path: AstPath, _opt: MoveOptions, _p: printFn): Doc { + return path.node.text; +} + +/** + * Print `field_initialize_list` node. + */ +function printFieldInitializeList(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [ + ' ', + group(list({ path, print, options, open: '{', close: '}', addWhitespace: true }), { + shouldBreak: shouldBreakFirstChild(path), + }), + ]; +} + +/** + * Print `expression_field` node. + * Inside: + * - `field_identifier` + * - `expression` + */ +function printExpressionField(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const children = path.map(print, 'nonFormattingChildren'); + + if (children.length === 1) { + return children[0]!; + } + + return group([children[0]!, ': ', children[1]!]); +} + +/** + * Print `function_type` node. + * Inside: + * - `function_type_parameters` + * - `return_type` + */ +function printFunctionType(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const children = path.map(print, 'nonFormattingChildren'); + + if (children.length === 0) { + return '||'; + } + + if (children.length === 1) { + return children[0]!; + } + + return join(' -> ', children); +} + +/** + * Print `function_type_parameters` node. + */ +function printFunctionTypeParameters( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return group(list({ path, print, options, open: '|', close: '|' })); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/constant.ts b/external-crates/move/tooling/prettier-move/src/cst/constant.ts new file mode 100644 index 00000000000..c7a2d49971f --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/constant.ts @@ -0,0 +1,109 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { printIdentifier, printTrailingComment } from '../utilities'; +import * as VectorExpression from './expression/vector_expression'; +import { printBreakableBlock } from './expression/block'; +const { line, group, join, fill, ifBreak, softline, breakParent, indent, lineSuffix } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'constant'; + +/** + * Prints: + * - `constant` + * - `constant_identifier` + */ +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printConstant; + } else if (path.node.type === 'constant_identifier') { + return printIdentifier; + } + + return null; +} + +/** + * Print `constant` node. + * + * See `module-members/constant.move` for tests. + */ +function printConstant(path: AstPath, options: MoveOptions, print: printFn): Doc { + const expression = path.node.nonFormattingChildren[2]; + const trailing = lineSuffix(printTrailingComment(path)); + path.node.disableTrailingComment(); + + const printCb = (path: AstPath) => printConstExpression(path, options, print); + const groupId = Symbol('type_group'); + + if (path.node.nonFormattingChildren.length !== 3) { + throw new Error('`constant` expects 3 children'); + } + + const [identDoc, typeDoc, exprDoc] = path.map(printCb, 'nonFormattingChildren'); + const parts = [] as Doc[]; + + // const : = ; + parts.push('const ', identDoc!); + parts.push(': ', group(typeDoc!, { id: groupId }), ' ='); + + if (expression?.isList) { + parts.push( + group([ + ifBreak(indent(line), ' ', { groupId }), + ifBreak(indent(exprDoc!), exprDoc, { groupId }), + ]), + ); + } else { + parts.push(group([indent(line), indent(exprDoc!)])); + } + + return parts.concat([';', trailing]); +} + +// Sub-router for expressions in the const declaration. Special cases are: +// +// - for vectors with `num` and `bool` literals, we want to fill single line +// - for blocks we want breakability +function printConstExpression(path: AstPath, options: MoveOptions, print: printFn) { + if (path.node.type === VectorExpression.NODE_TYPE) { + return prettyNumVector(path, options, print); + } + + if (path.node.type === 'block') { + return printBreakableBlock(path, options, print); + } + + return print(path); +} + +// TODO: optionally move this to `VectorExpression` +function prettyNumVector(path: AstPath, options: MoveOptions, print: printFn) { + let elType = path.node.nonFormattingChildren[0]?.type; + if (elType && ['num_literal', 'bool_literal'].includes(elType)) { + let allSameType = !path.node.nonFormattingChildren.some((e) => e.type !== elType); + let hasComments = path.node.namedChildren.some((e) => e.trailingComment || e.leadingComment.length > 0); + + if (allSameType && !hasComments) { + const literals = path.map(print, 'nonFormattingChildren'); + + if (literals.length == 0) { + return 'vector[]'; + } + + const elements = join([',', line], literals); + return [ + 'vector[', + group([indent(softline), indent(fill(elements)), ifBreak(','), softline]), + ']', + ]; + } + } + + return print(path); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/enum_definition.ts b/external-crates/move/tooling/prettier-move/src/cst/enum_definition.ts new file mode 100644 index 00000000000..71ad8a60bb1 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/enum_definition.ts @@ -0,0 +1,76 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { AstPath, Doc, doc } from 'prettier'; +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { printIdentifier, printTrailingComment } from '../utilities'; +const { join, lineSuffix, indent, hardline, group, line, ifBreak } = doc.builders; + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case EnumDefinition.EnumDefinition: + return printEnumDefinition; + case EnumDefinition.EnumVariants: + return printEnumVariants; + case EnumDefinition.Variant: + return printVariant; + + // identifiers + case EnumDefinition.EnumIdentifier: + case EnumDefinition.VariantIdentifier: + return printIdentifier; + } + + return null; +} + +export enum EnumDefinition { + EnumDefinition = 'enum_definition', + EnumVariants = 'enum_variants', + Variant = 'variant', + + EnumIdentifier = 'enum_identifier', + VariantIdentifier = 'variant_identifier', +} + +/** + * Print `enum_definition` node. + */ +export function printEnumDefinition(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const isPublic = path.node.child(0)?.type == 'public'; + + return [isPublic ? 'public ' : '', 'enum ', path.map(print, 'nonFormattingChildren')]; +} + +/** + * Print `enum_variants` node. + * List of `variant` nodes. + */ +export function printEnumVariants(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.nonFormattingChildren.length === 0) { + return ' {}'; + } + + return group([ + ' {', + indent(hardline), + indent(join([',', line], path.map(print, 'nonFormattingChildren'))), + ifBreak(','), + hardline, + '}', + ]); +} + +/** + * Print `variant` node. + * Inside: + * - `variant_identifier` + * - `datatype_fields` (optional) + */ +export function printVariant(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const trailing = lineSuffix(printTrailingComment(path, false)); + path.node.disableTrailingComment(); + return [path.map(print, 'nonFormattingChildren'), trailing]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/abort_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/abort_expression.ts new file mode 100644 index 00000000000..d6305452ca9 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/abort_expression.ts @@ -0,0 +1,34 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { group, indent, line } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'abort_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printAbortExpression; + } + + return null; +} + +/** + * Print `abort_expression` node. + */ +function printAbortExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const expression = path.node.nonFormattingChildren[0]; + const printed = path.call(print, 'nonFormattingChildren', 0); + + return group([ + 'abort', + expression?.isList || expression?.isControlFlow + ? [' ', printed] + : [indent(line), indent(printed)], + ]); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/annotation_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/annotation_expression.ts new file mode 100644 index 00000000000..af53721f6ba --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/annotation_expression.ts @@ -0,0 +1,39 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { group, indent, softline } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'annotation_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printAnnotationExpression; + } + + return null; +} + +/** + * Print `annotation_expression` node. + */ +function printAnnotationExpression(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const children = path.map(print, 'nonFormattingChildren'); + if (children.length !== 2) { + throw new Error('`annotation_expression` node should have 2 children'); + } + + return group([ + '(', + indent(softline), + indent(children[0]!), // expression + ': ', + children[1]!, // type + softline, + ')', + ]); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/assign_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/assign_expression.ts new file mode 100644 index 00000000000..09d382b18a5 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/assign_expression.ts @@ -0,0 +1,33 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { group, indent, line } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'assign_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printAssignExpression; + } + + return null; +} + +/** + * Print `assign_expression` node. + */ +function printAssignExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [ + path.call(print, 'nonFormattingChildren', 0), // lhs + ' =', + group([ + indent(line), + indent(path.call(print, 'nonFormattingChildren', 1)), // rhs + ]), + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/binary_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/binary_expression.ts new file mode 100644 index 00000000000..ed3f9309eb4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/binary_expression.ts @@ -0,0 +1,76 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { group, line } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'binary_expression'; + +// TODO: re-enable binary expression once we figure out how to achieve it. +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return () => path.node.text; + // TODO: re-enable binary expression once we figure out how to achieve it. + // return printBinaryExpression; + } else if (path.node.type === 'binary_operator') { + // return printBinaryOperator; + // TODO: re-enable binary expression once we figure out how to achieve it. + return () => path.node.text; + } + + return null; +} + +/** + * Print `binary_expression` node. + * (Currently disabled) + */ +function printBinaryExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.nonFormattingChildren.length != 3) { + throw new Error('`binary_expression` node should have 3 children'); + } + + const [one, two, three] = path.map(print, 'nonFormattingChildren'); + const rhs = path.node.nonFormattingChildren[2]; + + if (rhs?.type === 'block' || rhs?.type === 'expression_list') { + return [one!, ' ', two!, ' ', three!]; + } + + return [one!, ' ', two!, group([line, three!], { shouldBreak: false })]; +} + +/** + * Print `binary_operator` node. + */ +export function printBinaryOperator(path: AstPath, _opt: MoveOptions, _p: printFn): Doc { + return path.node.text; +} + +/** + + or: '||', + and: '&&', + eq: '==', + neq: '!=', + lt: '<', + gt: '>', + le: '<=', + ge: '>=', + bit_or: '|', + xor: '^', + bit_and: '&', + shl: '<<', + shr: '>>', + add: '+', + sub: '-', + mul: '*', + div: '/', + mod: '%' + + +*/ diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/block.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/block.ts new file mode 100644 index 00000000000..9c1bce9a09a --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/block.ts @@ -0,0 +1,70 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { block, shouldBreakFirstChild } from '../../utilities'; +const { group, indent, join, hardlineWithoutBreakParent } = doc.builders; + +/** The type of the node implemented in this file */ +const NODE_TYPE = 'block'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printBlock; + } + + return null; +} + +/** + * Special case of `block` node, that does not break the parent. A must-have for + * lambda expressions. + */ +export function printNonBreakingBlock( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const length = path.node.nonFormattingChildren.length; + + if (length == 0) { + return '{}'; + } + + return group([ + '{', + indent(hardlineWithoutBreakParent), + indent(join(hardlineWithoutBreakParent, path.map(print, 'namedAndEmptyLineChildren'))), + hardlineWithoutBreakParent, + '}', + ]); +} + +export function printBreakableBlock( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const length = path.node.nonFormattingChildren.length; + + if (length == 0) { + return '{}'; + } + + return block({ + options, + print, + path, + shouldBreak: shouldBreakFirstChild(path), + }); +} + +/** + * Print `block` node. + */ +export function printBlock(path: AstPath, options: MoveOptions, print: printFn): Doc { + return printNonBreakingBlock(path, options, print); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/block_item.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/block_item.ts new file mode 100644 index 00000000000..449c457929b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/block_item.ts @@ -0,0 +1,30 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { printTrailingComment } from '../../utilities'; +const { group, lineSuffix } = doc.builders; + +/** The type of the node implemented in this file */ +const NODE_TYPE = 'block_item'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printBlockItem; + } + + return null; +} + +/** + * Print `block_item` node. + */ +function printBlockItem(path: AstPath, options: MoveOptions, print: printFn): Doc { + const trailing = lineSuffix(printTrailingComment(path)); + path.node.disableTrailingComment(); + + return [group([path.call(print, 'nonFormattingChildren', 0), ';', trailing])]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/borrow_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/borrow_expression.ts new file mode 100644 index 00000000000..d9cc6b99e73 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/borrow_expression.ts @@ -0,0 +1,30 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'borrow_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printBorrowExpression; + } + + return null; +} + +/** + * Print `borrow_expression` node. + */ +function printBorrowExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const ref = path.node.child(0)!.text == '&mut' ? ['&mut', ' '] : ['&']; + return [ + ...ref, + path.call(print, 'nonFormattingChildren', 0), // borrow type + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/break_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/break_expression.ts new file mode 100644 index 00000000000..72e25d7bf36 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/break_expression.ts @@ -0,0 +1,34 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { join } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'break_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printBreakExpression; + } + + return null; +} + +/** + * Print `break_expression` node. + */ +export function printBreakExpression( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + if (path.node.nonFormattingChildren.length > 0) { + return join(' ', ['break', ...path.map(print, 'nonFormattingChildren')]); + } + + return 'break'; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/call_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/call_expression.ts new file mode 100644 index 00000000000..ef94e161a47 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/call_expression.ts @@ -0,0 +1,29 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'call_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printCallExpression; + } + + return null; +} + +/** + * Print `call_expression` node. + * Inside: + * - `module_access` + * - `type_arguments` + * - `arg_list` + */ +function printCallExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return path.map(print, 'nonFormattingChildren'); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/cast_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/cast_expression.ts new file mode 100644 index 00000000000..7aed85a041e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/cast_expression.ts @@ -0,0 +1,36 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { join } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'cast_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printCastExpression; + } + + return null; +} + +/** + * Print `cast_expression` node. + * Inside: + * - `expression` + * - `type` + */ +function printCastExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const parens = path.node.child(0)?.text == '('; + const children = path.map(print, 'nonFormattingChildren'); + + if (parens) { + return ['(', join(' as ', children), ')']; + } + + return join(' as ', children); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/continue_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/continue_expression.ts new file mode 100644 index 00000000000..eff1daaf307 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/continue_expression.ts @@ -0,0 +1,30 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'continue_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printContinueExpression; + } + + return null; +} + +/** + * Print `continue_expression` node. + */ +function printContinueExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.nonFormattingChildren.length === 1) { + return ['continue ', path.call(print, 'nonFormattingChildren', 0)]; + } + + return 'continue'; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/dereference_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/dereference_expression.ts new file mode 100644 index 00000000000..bd7625b5615 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/dereference_expression.ts @@ -0,0 +1,34 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'dereference_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printDereferenceExpression; + } + + return null; +} + +/** + * Print `dereference_expression` node. + * + * Inside: + * - `*` + * - `_expression` + */ +function printDereferenceExpression( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return ['*', path.call(print, 'nonFormattingChildren', 0)]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/dot_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/dot_expression.ts new file mode 100644 index 00000000000..cdad0f6256b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/dot_expression.ts @@ -0,0 +1,87 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { printLeadingComment, printTrailingComment } from '../../utilities'; +const { group, indent, ifBreak, breakParent, lineSuffix, softline } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'dot_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printDotExpression; + } + + return null; +} + +/** + * Print `dot_expression` node. + * + * Note, that it's intentional, that the return value is not a `group`. For more info, + * @see [This Issue](https://github.com/prettier/prettier/issues/15710#issuecomment-1836701758) + */ +function printDotExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.nonFormattingChildren.length < 2) { + throw new Error('`dot_expression` node should have at least 2 children'); + } + + // chain is a `dot_expression` that is a child of another `dot_expression` + // or which has a `dot_expression` as a child + const isChain = + path.node.nonFormattingChildren[0]!.type === NODE_TYPE || + path.node.parent?.type === NODE_TYPE; + + // if dot expression has a trailing comment and it breaks, we need to + // print it manually after the rhs + const trailing = lineSuffix(printTrailingComment(path)); + path.node.disableTrailingComment(); + + const lhs = path.call( + (path) => printNode(path, options, print, false), + 'nonFormattingChildren', + 0, + ); + const rhs = path.call( + (path) => printNode(path, options, print, true), + 'nonFormattingChildren', + 1, + ); + + // if it's a single expression, we don't need to group it + // and optionally no need to break it; no need to special + // print it in this case + if (!isChain) { + const right = path.node.nonFormattingChildren[1]!; + if (right.leadingComment.length > 0) { + return [lhs, indent(softline), indent(rhs), trailing]; + } + + return [lhs, rhs]; + } + + const parts = [lhs, ifBreak(indent(softline), ''), ifBreak(indent(rhs), rhs), trailing]; + + // group if parent is not `dot_expression` + if (isChain && path.node.parent?.type !== NODE_TYPE) { + return group(parts); + } + + return parts; +} + +// In `dot_expression` we need to keep the `.` in the same line as the `rhs`, +// so we need to prevent automatic printing of comments in the `print` call, and +// perform it manually. +function printNode(path: AstPath, options: MoveOptions, print: printFn, insertDot = false) { + const leading = printLeadingComment(path, options); + const shouldBreak = + path.node.leadingComment.length > 0 || path.node.trailingComment?.type === 'line_comment'; + + path.node.disableLeadingComment(); + return [leading, shouldBreak ? breakParent : '', insertDot ? '.' : '', print(path)]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/expression_list.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/expression_list.ts new file mode 100644 index 00000000000..42e9f07f663 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/expression_list.ts @@ -0,0 +1,33 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { list } from '../../utilities'; +const { group } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'expression_list'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printExpressionList; + } + + return null; +} + +/** + * Print `expression_list` node. + */ +function printExpressionList( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return group(list({ path, print, options, open: '(', close: ')' }), { + shouldBreak: false, + }); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/identified_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/identified_expression.ts new file mode 100644 index 00000000000..37e93c52701 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/identified_expression.ts @@ -0,0 +1,31 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'identified_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printIdentifiedExpression; + } + + return null; +} + +/** + * Print `identified_expression` node. + * Also known as `label` in the grammar or `labeled_expression`. + */ +function printIdentifiedExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [ + path.call(print, 'nonFormattingChildren', 0), // identifier + ' ', + path.call(print, 'nonFormattingChildren', 1), // expression + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/if_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/if_expression.ts new file mode 100644 index 00000000000..45328eb9f15 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/if_expression.ts @@ -0,0 +1,99 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { group, softline, ifBreak, indentIfBreak, line, indent } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'if_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printIfExpression; + } + + return null; +} + +/** + * Print `if_expression` node. + * + * ``` + * // single line + * if (cond || cond) {} + * + * // multi line + block + * if ( + * long_cond || + * long_cond + * ) { + * long_expr; + * long_expr; + * } + * + * // multi line + single line + * if (cond) + * return long_expr; + * + * // multi line + single line + long expr + * if ( + * long_cond || + * long_cond + * ) + * return long_expr && + * long_expr; + * ``` + */ +function printIfExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const groupId = Symbol('if_expression'); + const length = path.node.nonFormattingChildren.length; + const condition = path.node.nonFormattingChildren[0]; + const trueBranch = path.node.nonFormattingChildren[1]; + const result = [ + // condition group + group([ + 'if (', + condition?.isList + ? [indent(softline), path.call(print, 'nonFormattingChildren', 0), softline] + : [ + indent(softline), + indent(path.call(print, 'nonFormattingChildren', 0)), + softline, + ], + ')', + ]), + // body group + group( + [ + trueBranch?.isList // || trueBranch?.isControlFlow + ? [' ', path.call(print, 'nonFormattingChildren', 1)] + : [indent(line), (path.call(print, 'nonFormattingChildren', 1))], + + ], + { id: groupId }, + ), + ]; + + // else block + if (length === 3) { + // whether developer has put a newline character before `else` keyword + // if they did - we respect it and break the line intentionally + const shouldBreak = !!path.node.children.find((e) => e.type === 'else')?.startsOnNewLine; + const elseBranch = path.node.nonFormattingChildren[2]; + const printed = path.call(print, 'nonFormattingChildren', 2); + + result.push( + group( + elseBranch?.isList || trueBranch?.type === 'block' + ? [' else ', printed] + : [ifBreak(' ', line, { groupId }), 'else ', printed], + { shouldBreak }, + ), + ); + } + + return result; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/index.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/index.ts new file mode 100644 index 00000000000..9be67e2462c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/index.ts @@ -0,0 +1,86 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/** + * Route through `_expression` nodes. + * + * @module src/cst/expression + */ + +import { Node } from '../..'; +import { treeFn } from '../../printer'; +import { AstPath } from 'prettier'; + +// Folder imports: +import abort_expression from './abort_expression'; +import annotation_expression from './annotation_expression'; +import assign_expression from './assign_expression'; +import binary_expression from './binary_expression'; +import block_item from './block_item'; +import block from './block'; +import borrow_expression from './borrow_expression'; +import break_expression from './break_expression'; +import call_expression from './call_expression'; +import cast_expression from './cast_expression'; +import continue_expression from './continue_expression'; +import dereference_expression from './dereference_expression'; +import dot_expression from './dot_expression'; +import expression_list from './expression_list'; +import if_expression from './if_expression'; +import identified_expression from './identified_expression'; +import index_expression from './index_expression'; +import lambda_expression from './lambda_expression'; +import let_statement from './let_statement'; +import loop_expression from './loop_expression'; +import macro_call_expression from './macro_call_expression'; +import match_expression from './match_expression'; +import move_or_copy_expression from './move_or_copy_expression'; +import name_expression from './name_expression'; +import pack_expression from './pack_expression'; +import return_expression from './return_expression'; +import unary_expression from './unary_expression'; +import unit_expression from './unit_expression'; +import vector_expression from './vector_expression'; +import while_expression from './while_expression'; + +export default function (path: AstPath): treeFn | null { + // route to separated functions + const result = + abort_expression(path) || + annotation_expression(path) || + assign_expression(path) || + binary_expression(path) || + block_item(path) || + block(path) || + borrow_expression(path) || + break_expression(path) || + call_expression(path) || + cast_expression(path) || + continue_expression(path) || + dereference_expression(path) || + dot_expression(path) || + expression_list(path) || + if_expression(path) || + identified_expression(path) || + index_expression(path) || + lambda_expression(path) || + let_statement(path) || + loop_expression(path) || + macro_call_expression(path) || + match_expression(path) || + move_or_copy_expression(path) || + name_expression(path) || + pack_expression(path) || + return_expression(path) || + unary_expression(path) || + unit_expression(path) || + vector_expression(path) || + while_expression(path); + + if (result !== null) { + return result; + } + + return null; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/index_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/index_expression.ts new file mode 100644 index 00000000000..bb82633671a --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/index_expression.ts @@ -0,0 +1,38 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { list } from '../../utilities'; +const { group } = doc.builders; + +/** The type of the node implemented in this file */ +const NODE_TYPE = 'index_expression'; + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case NODE_TYPE: + return printIndexExpression; + } + + return null; +} + +/** + * Print `index_expression` node. + */ +export function printIndexExpression( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return group( + [ + path.call(print, 'nonFormattingChildren', 0), // lhs + list({path, options, open: '[', close: ']', print, skipChildren: 1 }), + ], + { shouldBreak: false }, + ); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/lambda_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/lambda_expression.ts new file mode 100644 index 00000000000..c7e34d81ede --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/lambda_expression.ts @@ -0,0 +1,95 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { printBreakableBlock, printNonBreakingBlock } from './block'; +import { list } from '../../utilities'; +const { group, join, conditionalGroup } = doc.builders; + +/** The type of the node implemented in this file */ +const NODE_TYPE = 'lambda_expression'; + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case NODE_TYPE: + return printLambdaExpression; + case 'lambda_bindings': + return printLambdaBindings; + case 'lambda_binding': + return printLambdaBinding; + } + + return null; +} + +/** + * Print `labda_expression` node. + * Inside: + * - `lambda_bindings` + * - `_bind` + */ +function printLambdaExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const children = path.node.nonFormattingChildren; + const printCb = (path: AstPath) => { + if (path.node.type === 'block') { + return conditionalGroup([ + printBreakableBlock(path, options, print), + printNonBreakingBlock(path, options, print) + ]); + } + + return print(path); + }; + + // just bindings + if (children.length === 1) { + return path.call(printCb, 'nonFormattingChildren', 0); + } + + // bindings, expression or bindings, return type + if (children.length === 2) { + return join(' ', path.map(printCb, 'nonFormattingChildren')); + } + + // bindings, return type, expression + if (children.length === 3) { + return [ + path.call(printCb, 'nonFormattingChildren', 0), // bindings + ' -> ', + path.call(printCb, 'nonFormattingChildren', 1), // return type + ' ', + path.call(printCb, 'nonFormattingChildren', 2), // expression + ]; + } + + throw new Error('`lambda_expression` node should have 1, 2 or 3 children'); +} + +/** + * Print `lambda_bindings` node, contains comma-separated list of `lambda_binding` nodes. + */ +function printLambdaBindings(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group(list({ path, print, options, open: '|', close: '|' })); +} + +/** + * Print `lambda_binding` node. + * It can be either type annotated or just a variable binding, we know it by the number + * of non-formatting children. + */ +function printLambdaBinding(path: AstPath, options: MoveOptions, print: printFn): Doc { + // simple bind, will be handled by its function + if (path.node.nonFormattingChildren.length === 1) { + return path.call(print, 'nonFormattingChildren', 0); + } + + // with type annotation + if (path.node.nonFormattingChildren.length === 2) { + return join(': ', path.map(print, 'nonFormattingChildren')); + } + + throw new Error('`lambda_binding` node should have 1 or 2 children'); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/let_statement.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/let_statement.ts new file mode 100644 index 00000000000..7fbd7e3cb0c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/let_statement.ts @@ -0,0 +1,63 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { group, indent, line } = doc.builders; + +/** The type of the node implemented in this file */ +const NODE_TYPE = 'let_statement'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printLetStatement; + } + + return null; +} + +/** + * Print `let_statement` node. + */ +function printLetStatement(path: AstPath, options: MoveOptions, print: printFn): Doc { + const nodes = path.node.nonFormattingChildren; + + if (nodes.length === 1) { + return group(['let', ' ', path.call(print, 'nonFormattingChildren', 0)]); + } + + const printed = path.map(print, 'nonFormattingChildren'); + const rhsNode = path.node.nonFormattingChildren.slice(-1)[0]!; + + if (nodes.length === 2 && nodes[1]!.isTypeParam) { + const [bind, type] = printed; + return group(['let ', bind!, ': ', type!]); + } + + if (nodes.length === 2) { + const [bind, expr] = printed; + const result = + rhsNode.isBreakableExpression || rhsNode.isFunctionCall + ? ['let ', bind!, ' = ', expr!] + : ['let ', bind!, ' =', indent(group([line, expr!], { shouldBreak: false }))]; + + return group(result, { shouldBreak: false }); + } + + const [bind, type, expr] = printed; + const result = + rhsNode.isBreakableExpression || rhsNode.isFunctionCall + ? ['let ', bind!, ': ', type!, ' = ', expr!] + : [ + 'let ', + bind!, + ': ', + type!, + ' =', + indent(group([line, expr!], { shouldBreak: false })), + ]; + + return result; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/loop_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/loop_expression.ts new file mode 100644 index 00000000000..cf5d8764000 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/loop_expression.ts @@ -0,0 +1,30 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'loop_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printLoopExpression; + } + + return null; +} + +/** + * Print `loop_expression` node. + * + * ``` + * loop `_expression` + * ``` + */ +function printLoopExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [`loop `, path.call(print, 'nonFormattingChildren', 0)]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/macro_call_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/macro_call_expression.ts new file mode 100644 index 00000000000..09f148a9986 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/macro_call_expression.ts @@ -0,0 +1,77 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { list } from '../../utilities'; +const { group, indentIfBreak, line, softline, ifBreak, join } = doc.builders; + +/** The type of the node implemented in this file */ +const NODE_TYPE = 'macro_call_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printMacroCallExpression; + } + + return null; +} + +/** + * Print `macro_call_expression` node. + * Inside: + * - `macro_module_access` + * - `type_arguments` + * - `arg_list` + */ +function printMacroCallExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return path.map((path) => { + if (path.node.type === 'macro_module_access') { + return printMacroModuleAccess(path, options, print); + } + + if (path.node.type === 'arg_list') { + return printMacroArgsList(path, options, print); + } + + return print(path); + }, 'nonFormattingChildren'); +} + +/** + * Print `macro_module_access` node. + * Inside: + * - `module_access` + * - `!` + */ +function printMacroModuleAccess(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [path.call(print, 'nonFormattingChildren', 0), '!']; +} + +/** + * Special function to print macro arguments list instead of `arg_list`. + */ +function printMacroArgsList(path: AstPath, options: MoveOptions, print: printFn) { + if (path.node.type !== 'arg_list') { + throw new Error('Expected `arg_list` node'); + } + + if (path.node.namedChildCount === 0) { + return '()'; + } + + const groupId = Symbol('macro_args_list'); + + return group(list({ + path, + options, + print, + open: '(', + close: ')', + addWhitespace: false, + shouldBreak: false, + indentGroup: groupId, + }), { id: groupId }); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/match_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/match_expression.ts new file mode 100644 index 00000000000..7a0a98c6ed0 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/match_expression.ts @@ -0,0 +1,114 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc } from 'prettier'; +import { list } from '../../utilities'; +import { builders } from 'prettier/doc'; +import { printBreakableBlock, printNonBreakingBlock } from './block'; +const { join, indent, group, softline, line, dedent, conditionalGroup } = builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'match_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printMatchExpression; + } else if (path.node.type === 'match_arm') { + return printMatchArm; + } else if (path.node.type === 'match_condition') { + return printMatchCondition; + } + + return null; +} + +/** + * Print `match_expression` node. + * Inside: + * - `match` + * - `(` + * - `_expression` + * - `)` + * - `_match_body` + */ +function printMatchExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const condNode = path.node.nonFormattingChildren[0]!; + const parts: Doc[] = ['match ']; + + if (condNode.isBreakableExpression) { + parts.push('(', path.call(print, 'nonFormattingChildren', 0), ')'); + } else { + parts.push( + group([ + '(', + indent(softline), + indent(path.call(print, 'nonFormattingChildren', 0)), + softline, + ')', + ]), + ); + } + + parts.push( + ' ', + list({ + path, + print, + options, + open: '{', + close: '}', + skipChildren: 1, + shouldBreak: true, + }), + ); + + return parts; +} + +/** + * Print `match_arm` node. + */ +function printMatchArm(path: AstPath, options: MoveOptions, print: printFn): Doc { + const children = path.map(print, 'nonFormattingChildren'); + const groupId = Symbol('match_arm'); + + if (children.length < 2) { + throw new Error('`match_arm` node should have at least 2 children'); + } + + if (children.length == 2) { + return group(join(' => ', children)); + } + + if (children.length == 3) { + return [children[0]!, ' ', children[1]!, group([' =>', indent(line), children[2]!])]; + } + + throw new Error('`match_arm` node should have at most 3 children'); +} + +/** + * Prints `match_condition` node in `match_arm`. + * Example: `Enum if (x == 1) => 1,`, `if (...)` here is a `match_condition` node. + */ +function printMatchCondition(path: AstPath, options: MoveOptions, print: printFn): Doc { + const children = path.node.nonFormattingChildren; + + if (children.length !== 1) { + throw new Error('`match_condition` expects 1 child'); + } + + return ['if (', path.call((path) => { + if (path.node.type === 'block') { + return conditionalGroup([ + printBreakableBlock(path, options, print), + printNonBreakingBlock(path, options, print), + ]); + } + + return print(path); + }, 'nonFormattingChildren', 0), ')']; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/move_or_copy_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/move_or_copy_expression.ts new file mode 100644 index 00000000000..9bf256cf859 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/move_or_copy_expression.ts @@ -0,0 +1,30 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'move_or_copy_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printMoveOrCopyExpression; + } + + return null; +} + +/** + * Print `move_or_copy_expression` node. + */ +function printMoveOrCopyExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const ref = path.node.child(0)!.text == 'move' ? ['move', ' '] : ['copy', ' ']; + return [ + ...ref, + path.call(print, 'nonFormattingChildren', 0), // expression + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/name_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/name_expression.ts new file mode 100644 index 00000000000..ed2773df578 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/name_expression.ts @@ -0,0 +1,29 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'name_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printNameExpression; + } + + return null; +} + +/** + * Print `name_expression` node. + * Inside: + * - `module_access` + * - `type_arguments` + */ +function printNameExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return path.map(print, 'nonFormattingChildren'); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/pack_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/pack_expression.ts new file mode 100644 index 00000000000..dba267c2395 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/pack_expression.ts @@ -0,0 +1,30 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'pack_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printPackExpression; + } + + return null; +} + +/** + * Print `pack_expression` node. + * Inside: + * - `module_access` + * - `type_arguments` (optional) + * - `field_initialize_list` + */ +function printPackExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return path.map(print, 'nonFormattingChildren'); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/return_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/return_expression.ts new file mode 100644 index 00000000000..01c3ce4a579 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/return_expression.ts @@ -0,0 +1,51 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { join, indent } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'return_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printReturnExpression; + } + + return null; +} + +/** + * Print `return_expression` node. + */ +function printReturnExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const nodes = path.node.nonFormattingChildren; + + if (nodes.length === 0) { + return 'return'; + } + + // either label or expression + if (nodes.length === 1) { + const expression = nodes[0]!; + const printed = path.call(print, 'nonFormattingChildren', 0); + return ['return ', expression.isBreakableExpression ? printed : indent(printed)]; + } + + // labeled expression + if (nodes.length === 2) { + const expression = nodes[1]!; + const printedLabel = path.call(print, 'nonFormattingChildren', 0); + const printedExpression = path.call(print, 'nonFormattingChildren', 1); + return join(' ', [ + 'return', + printedLabel, + expression.isBreakableExpression ? printedExpression : indent(printedExpression), + ]); + } + + throw new Error('Invalid return expression'); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/unary_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/unary_expression.ts new file mode 100644 index 00000000000..bd26cb51030 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/unary_expression.ts @@ -0,0 +1,29 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'unary_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printUnaryExpression; + } + + return null; +} + +/** + * Print `unary_expression` node. + */ +function printUnaryExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [ + path.call(print, 'nonFormattingChildren', 0), + path.call(print, 'nonFormattingChildren', 1), + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/unit_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/unit_expression.ts new file mode 100644 index 00000000000..05d40c2ac40 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/unit_expression.ts @@ -0,0 +1,19 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const {} = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'unit_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return () => '()' + } + + return null; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/vector_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/vector_expression.ts new file mode 100644 index 00000000000..f4f12d08c88 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/vector_expression.ts @@ -0,0 +1,86 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { list } from '../../utilities'; +import { printBreakableBlock } from './block'; +const { group } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'vector_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printVectorExpression; + } + + return null; +} + +/** + * Print `vector_expression` node. + */ +function printVectorExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.namedChildCount === 0) { + return 'vector[]'; + } + + // Injected print callback for elements in the vector + const printCb = (path: AstPath) => printElement(path, options, print); + + // Vector without type specified + // Eg: `vector[....]` + if (path.node.child(0)?.text == 'vector[') { + return group( + ['vector', list({ path, print: printCb, options, open: '[', close: ']' }) as Doc[]], + { shouldBreak: false }, + ); + } + + if (!path.node.nonFormattingChildren[0]?.isTypeParam) { + throw new Error( + `Expected a type parameter in the \`vector_expression\`, got \`${path.node.nonFormattingChildren[0]?.type}\``, + ); + } + + if (path.node.nonFormattingChildren.slice(1).some((child) => child.isTypeParam)) { + throw new Error('Expected only one type parameter in the `vector_expression`'); + } + + // Vector with type + // Eg: `vector[...]` + return [ + 'vector<', + // do not break the type in vector literal + // indent(softline), + group(path.call(print, 'nonFormattingChildren', 0), { shouldBreak: false }), + '>', + group( + list({ + path, + print: printCb, + options, + open: '[', + close: ']', + skipChildren: 1, + shouldBreak: false, + }) as Doc[], + ), + ]; +} + +/** + * Special print elements in the `vector_expression`. + * + * - we want to use breakable blocks for `block` nodes; + */ +function printElement(path: AstPath, options: MoveOptions, print: printFn): Doc { + if (path.node.type === 'block') { + return printBreakableBlock(path, options, print); + } + + return print(path); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/expression/while_expression.ts b/external-crates/move/tooling/prettier-move/src/cst/expression/while_expression.ts new file mode 100644 index 00000000000..3d151c71972 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/expression/while_expression.ts @@ -0,0 +1,46 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '../..'; +import { MoveOptions, printFn, treeFn } from '../../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { indent, softline, group } = doc.builders; + +/** The type of the node implemented in this file */ +export const NODE_TYPE = 'while_expression'; + +export default function (path: AstPath): treeFn | null { + if (path.node.type === NODE_TYPE) { + return printWhileExpression; + } + + return null; +} + +/** + * Print `while_expression` node. + * + * ``` + * // single line + * while (bool_expr) expr + * + * // break condition + * while ( + * very_long_expr && + * very_long_expr + * ) { + * expr; + * } + * ``` + */ +function printWhileExpression(path: AstPath, options: MoveOptions, print: printFn): Doc { + const condition = path.node.nonFormattingChildren[0]!.isList + ? [indent(softline), path.call(print, 'nonFormattingChildren', 0), softline] + : [indent(softline), indent(path.call(print, 'nonFormattingChildren', 0)), softline]; + + return [ + ['while (', group(condition), ') '], + path.call(print, 'nonFormattingChildren', 1), // body + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/formatting.ts b/external-crates/move/tooling/prettier-move/src/cst/formatting.ts new file mode 100644 index 00000000000..b8f30fe6e2c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/formatting.ts @@ -0,0 +1,101 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { treeFn } from '../printer'; +import { AstPath, Doc } from 'prettier'; + +/** + * Creates a callback function to print commments and comment-related nodes. + * + * @param path + * @returns + */ +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case Formatting.LineComment: + return printLineComment; + case Formatting.BlockComment: + return printBlockComment; + case Formatting.EmptyLine: + return printEmptyLine; + case Formatting.Newline: + return printNewline; + default: + return null; + } +} + +export enum Formatting { + LineComment = 'line_comment', + BlockComment = 'block_comment', + /** + * Token that doesn't exist in the grammar but we insert it in + * the `Tree` representation of CST to represent an empty line. + */ + EmptyLine = 'empty_line', + /** + * Special node to insert a newline before the next node. + * We use it to make a call to hardline or not. + */ + Newline = 'newline', +} + +export function startsOnNewLine(path: AstPath): boolean { + return path.previous?.type == Formatting.EmptyLine; +} + +export function shouldNewLine(path: AstPath): boolean { + return path.node.nextNamedSibling?.type == Formatting.Newline; +} + +/** + * Test if a node is a formatting node. + * + * @param node + * @returns + */ +export function isFormatting(node: Node): boolean { + return [ + Formatting.LineComment, + Formatting.BlockComment, + Formatting.EmptyLine, + Formatting.Newline, + ].includes(node.type as Formatting); +} + +export function isComment(node: Node | null): boolean { + return [Formatting.LineComment, Formatting.BlockComment].includes(node?.type as Formatting); +} + +export function isEmptyLine(node: Node | null): boolean { + return Formatting.EmptyLine == node?.type; +} + +export function isNewline(node: Node | null): boolean { + return Formatting.Newline == node?.type; +} + +/** + * Print `line_comment` node. + * Comments are handled via the `addLeadingComments` function. + */ +export function printLineComment(path: AstPath): Doc { + return path.node.text; +} + +/** + * Print `block_comment` node. + */ +export function printBlockComment(path: AstPath): Doc { + return path.node.text; +} + +export function printEmptyLine(path: AstPath): Doc { + return ''; // should not be printed directly, used in `join(hardline)` to act as an extra newline +} + +export function printNewline(path: AstPath): Doc { + return ''; // should not be printed, ever +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/function_definition.ts b/external-crates/move/tooling/prettier-move/src/cst/function_definition.ts new file mode 100644 index 00000000000..00fe9b11321 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/function_definition.ts @@ -0,0 +1,291 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, Doc, doc } from 'prettier'; +import { printBreakableBlock } from './expression/block'; +import { list, printIdentifier } from '../utilities'; +const { join, group } = doc.builders; + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case FunctionDefinition.NativeFunctionDefinition: + return printNativeFunctionDefinition; + case FunctionDefinition.FunctionDefinition: + return printFunctionDefinition; + case FunctionDefinition.MacroFunctionDefinition: + return printMacroFunctionDefinition; + case FunctionDefinition.VisibilityModifier: + return printVisibilityModifier; + case FunctionDefinition.FunctionParameters: + return printFunctionParameters; + case FunctionDefinition.FunctionParameter: + return printFunctionParameter; + case FunctionDefinition.ReturnType: + return printReturnType; + case FunctionDefinition.TypeArguments: + return printTypeArguments; + case FunctionDefinition.TypeParameters: + return printTypeParameters; + case FunctionDefinition.TypeParameter: + return printTypeParameter; + + // identifiers + case FunctionDefinition.FunctionIdentifier: + case FunctionDefinition.TypeParameterIdentifier: + return printIdentifier; + } + + return null; +} + +/** + * Function Definition, contains the following: + * ``` + * fun () + * ``` + */ +export enum FunctionDefinition { + FunctionDefinition = 'function_definition', + FunctionIdentifier = 'function_identifier', + NativeFunctionDefinition = 'native_function_definition', + MacroFunctionDefinition = 'macro_function_definition', + VisibilityModifier = 'visibility_modifier', + FunctionParameters = 'function_parameters', + FunctionParameter = 'function_parameter', + ReturnType = 'ret_type', + TypeArguments = 'type_arguments', + TypeParameters = 'type_parameters', + TypeParameter = 'type_parameter', + TypeParameterIdentifier = 'type_parameter_identifier', +} + +export type Modifiers = { + native?: boolean; + public?: boolean; + entry?: boolean; + ['public(friend)']?: boolean; + ['public(package)']?: boolean; +}; + +/** + * Print `function_definition` node. + */ +export function printFunctionDefinition( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const nodes = path.node.nonFormattingChildren; + const retIndex = nodes.findIndex((e) => e.type == FunctionDefinition.ReturnType); + const modifiers = getModifiers(path); + const printCb = (path: AstPath) => + path.node.type === 'block' ? printBreakableBlock(path, options, print) : print(path); + + const signature = [ + printModifiers(modifiers), + 'fun ', + path.map((path) => { + // We already added modifiers in the previous step + if (path.node.type == 'modifier') return ''; + if (path.node.type == 'block') return ''; + if (path.node.type == 'ret_type') return ''; + if (path.node.isFormatting) return ''; + + return print(path); + }, 'nonFormattingChildren'), + ]; + + return [ + group([signature, path.call(print, 'nonFormattingChildren', retIndex)]), + ' ', + path.call(printCb, 'nonFormattingChildren', nodes.length - 1), + ]; +} + +export function printNativeFunctionDefinition( + path: AstPath, + _opt: MoveOptions, + print: printFn, +): Doc { + const modifiers = getModifiers(path); + + return [ + printModifiers(modifiers), + 'fun ', + group( + path.map((path) => { + if (path.node.type == 'modifier') return ''; + return print(path); + }, 'nonFormattingChildren'), + ), + ';', + ]; +} + +/** + * Print `macro_function_definition` node. + */ +export function printMacroFunctionDefinition( + path: AstPath, + _opt: MoveOptions, + print: printFn, +): Doc { + const modifiers = getModifiers(path); + + return [ + printModifiers(modifiers), + 'macro fun ', + group( + path.map((path) => { + if (path.node.type == 'modifier') return ''; + if (path.node.type == 'block') return ''; + return print(path); + }, 'nonFormattingChildren'), + ), + ' ', + path.call(print, 'nonFormattingChildren', path.node.nonFormattingChildren.length - 1), + ]; +} + +/** + * Print `visibility_modifier` node. + * Always followed by a space. + */ +export function printVisibilityModifier( + path: AstPath, // | Node | null, + _opt: MoveOptions, + _print: printFn, +): Doc { + return [path.node.text, ' ']; +} + +/** + * Print `function_parameters` node. + */ +export function printFunctionParameters( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return list({ + path, + print, + options, + open: '(', + close: ')', + shouldBreak: false, + }); +} + +/** + * Print `function_parameter` node. + */ +export function printFunctionParameter( + path: AstPath, + _opt: MoveOptions, + print: printFn, +): Doc { + const isMut = path.node.child(0)?.type == 'mut'; + const isDollar = path.node.children.find((c) => c.type == '$'); + + return group([ + isMut ? 'mut ' : '', + isDollar ? '$' : '', + path.call(print, 'nonFormattingChildren', 0), // variable_identifier + ': ', + path.call(print, 'nonFormattingChildren', 1), // type + ]); +} + +/** + * Print `ret_type` node. + */ +export function printReturnType(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + return [': ', path.call(print, 'nonFormattingChildren', 0)]; +} + +/** + * Print `type_arguments` node. + */ +export function printTypeArguments( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return group( + list({ + path, + print, + options, + open: '<', + close: '>', + shouldBreak: false, + }), + ); +} + +/** + * Print `type_parameters` node. + */ +export function printTypeParameters( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return group( + list({ + path, + print, + options, + open: '<', + close: '>', + shouldBreak: false, + }), + ); +} + +/** + * Print `type_parameter` node. + */ +export function printTypeParameter(path: AstPath, _opt: MoveOptions, print: printFn): Doc { + const isDollar = path.node.child(0)?.type == '$'; + const isPhantom = path.node.child(0)?.type == 'phantom'; + const parameter = path.call(print, 'nonFormattingChildren', 0); + const abilities = path.map(print, 'nonFormattingChildren').slice(1); + + return [ + isDollar ? '$' : '', + isPhantom ? 'phantom ' : '', + parameter, + abilities.length > 0 ? ': ' : '', + join(' + ', abilities), + ]; +} + +/** + * Helper function to get modifiers. + */ +function getModifiers(path: AstPath): Modifiers { + const nodes = path.node.nonFormattingChildren; + + return nodes + .filter((e) => e.type == 'modifier') + .map((e) => e.text.replace(' ', '')) // removes the space in `public (package)` + .reduce((acc, e) => ({ ...acc, [e]: true }), {}); +} + +/** + * Helper function to print modifiers. + */ +function printModifiers(modifiers: Modifiers): Doc { + return [ + modifiers.public ? 'public ' : '', + modifiers['public(package)'] ? 'public(package) ' : '', + modifiers['public(friend)'] ? 'public(friend) ' : '', + modifiers.entry ? 'entry ' : '', + modifiers.native ? 'native ' : '', + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/literal.ts b/external-crates/move/tooling/prettier-move/src/cst/literal.ts new file mode 100644 index 00000000000..d7632feb8a7 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/literal.ts @@ -0,0 +1,70 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { AstPath, Doc } from 'prettier'; +import { Node } from '..'; +import { treeFn } from '../printer'; + +/** + * Node: `_literal_value` in the grammar.json. + */ +export enum Literal { + AddressLiteral = 'address_literal', + BoolLiteral = 'bool_literal', + NumLiteral = 'num_literal', + HexStringLiteral = 'hex_string_literal', + ByteStringLiteral = 'byte_string_literal', +} + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case Literal.AddressLiteral: + return printAddressLiteral; + case Literal.BoolLiteral: + return printBoolLiteral; + case Literal.NumLiteral: + return printNumLiteral; + case Literal.HexStringLiteral: + return printHexStringLiteral; + case Literal.ByteStringLiteral: + return printByteStringLiteral; + } + + return null; +} + +/** + * Print `byte_string_literal` node. + */ +export function printByteStringLiteral(path: AstPath): Doc { + return path.node.text; +} + +/** + * Print `bool_literal` node. + */ +export function printBoolLiteral(path: AstPath): Doc { + return path.node.text; +} + +/** + * Print `num_literal` node. + */ +export function printNumLiteral(path: AstPath): Doc { + return path.node.text; +} + +/** + * Print `address_literal` node. + */ +export function printAddressLiteral(path: AstPath): Doc { + return path.node.text; +} + +/** + * Print `hex_literal` node. + */ +export function printHexStringLiteral(path: AstPath): Doc { + return path.node.text; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/module.ts b/external-crates/move/tooling/prettier-move/src/cst/module.ts new file mode 100644 index 00000000000..a746d76c71b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/module.ts @@ -0,0 +1,165 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, Doc, ParserOptions, doc } from 'prettier'; +import { FunctionDefinition } from './function_definition'; +import { StructDefinition } from './struct_definition'; +import * as Constant from './constant'; +import { UseDeclaration } from './use_declaration'; +import { printImports, collectImports } from '../imports-grouping'; +import { EnumDefinition } from './enum_definition'; +import { printIdentifier } from '../utilities'; +const { join, hardline, indent } = doc.builders; + +/** + * Creates a callback function to print modules and module-related nodes. + */ +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case Module.ModuleDefinition: + return printModuleDefinition; + case Module.ModuleIdentity: + return printModuleIdentity; + case Module.ModuleIdentifier: + return printIdentifier; + case Module.ModuleBody: + return printModuleBody; + default: + return null; + } +} + +/** + * Module - top-level definition in a Move source file. + */ +export enum Module { + ModuleDefinition = 'module_definition', + BlockComment = 'block_comment', + ModuleIdentity = 'module_identity', + ModuleIdentifier = 'module_identifier', + ModuleBody = 'module_body', +} + +/** + * Print `module_definition` node. + */ +export function printModuleDefinition( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + let useLabel = false; + + // when option is present we must check that there's only one module per file + if (options.useModuleLabel) { + const modules = path.parent!.nonFormattingChildren.filter( + (node) => node.type === path.node.type, + ); + + useLabel = modules.length == 1; + } + + const result = ['module ', path.call(print, 'nonFormattingChildren', 0)]; + + // if we're using the label, we must add a semicolon and print the body in a + // new line + if (useLabel) { + return result.concat([ + ';', + hardline, + hardline, + path.call(print, 'nonFormattingChildren', 1), + ]); + } + + // when not module mabel, module body is a block with curly braces and + // indentation + return result.concat([ + ' {', + indent(hardline), + indent(path.call(print, 'nonFormattingChildren', 1)), + hardline, + '}', + ]); +} + +/** + * Print `module_identity` node. + */ +function printModuleIdentity(path: AstPath, options: ParserOptions, print: printFn): Doc { + return join('::', path.map(print, 'nonFormattingChildren')); +} + +/** + * Members that must be separated by an empty line if they are next to each other. + * For example, a function definition followed by a struct definition. + */ +const separatedMembers = [ + FunctionDefinition.FunctionDefinition, + StructDefinition.StructDefinition, + Constant.NODE_TYPE, + UseDeclaration.UseDeclaration, + UseDeclaration.FriendDeclaration, + EnumDefinition.EnumDefinition, +] as string[]; + +/** + * Print `module_body` node. + * + * We need to preserve spacing between members (functions, structs, constants, etc.). + * We need to only allow a single empty line (if there are more than one, we should remove them). + * Additionally, if `groupImports` is set to `package` or `module`, we should group imports and + * print them at the top of the module. + */ +function printModuleBody( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const nodes = path.node.namedAndEmptyLineChildren; + const importsDoc = [] as Doc[]; + const imports = collectImports(path.node); + if (Object.keys(imports).length > 0) { + importsDoc.push( + ...(printImports(imports, options.autoGroupImports as 'package' | 'module') as Doc[]), + ); + } + + const bodyDoc = [] as Doc[]; + + path.each((path, i) => { + const next = nodes[i + 1]; + + // empty lines should be removed if they are next to grouped imports + if (path.node.isEmptyLine && path.node.previousNamedSibling?.isGroupedImport) return; + if (path.node.isGroupedImport) return; + if (path.node.isEmptyLine && !path.node.previousNamedSibling) return; + + if ( + separatedMembers.includes(path.node.type) && + separatedMembers.includes(next?.type || '') && + path.node.type !== next?.type + ) { + return bodyDoc.push([path.call(print), hardline]); + } + + // force add empty line after function definitions + if ( + path.node.type === FunctionDefinition.FunctionDefinition && + next?.type === FunctionDefinition.FunctionDefinition + ) { + return bodyDoc.push([path.call(print), hardline]); + } + + return bodyDoc.push(path.call(print)); + }, 'namedAndEmptyLineChildren'); + + if (bodyDoc.length > 0 && importsDoc.length > 0) { + bodyDoc.unshift(''); // add empty line before first member + } + + return join(hardline, importsDoc.concat(bodyDoc)); +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/source_file.ts b/external-crates/move/tooling/prettier-move/src/cst/source_file.ts new file mode 100644 index 00000000000..5a1896e215a --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/source_file.ts @@ -0,0 +1,39 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, Doc, doc } from 'prettier'; +const { hardline, join } = doc.builders; + +/** + * Print a source node. + */ +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case SourceFile.SourceFile: + return printSourceFile; + } + return null; +} + +export enum SourceFile { + SourceFile = 'source_file', +} + +/** + * Print `source_file` node. + * + * Print all non-formatting children separated by a hardline. + * Also print empty lines with leading comments, this allows us to maintain structure like this: + * ``` + * // Copyright + * `empty_line` + * // module comment + * module book::book { ... } + * ``` + */ +function printSourceFile(path: AstPath, options: MoveOptions, print: printFn): Doc { + return [join(hardline, path.map(print, 'namedAndEmptyLineChildren')), hardline]; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/struct_definition.ts b/external-crates/move/tooling/prettier-move/src/cst/struct_definition.ts new file mode 100644 index 00000000000..c27926e00a0 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/struct_definition.ts @@ -0,0 +1,268 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { MoveOptions, printFn, treeFn } from '../printer'; +import { AstPath, Doc, ParserOptions, doc } from 'prettier'; +import { + emptyBlockOrList, + list, + printIdentifier, + printLeadingComment, + printTrailingComment, + shouldBreakFirstChild, +} from '../utilities'; +const { group, join } = doc.builders; + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case StructDefinition.StructDefinition: + return printStructDefinition; + case StructDefinition.NativeStructDefinition: + return printNativeStructDefinition; + case StructDefinition.AbilityDeclarations: + return printAbilityDeclarations; + case StructDefinition.PostfixAbilityDeclarations: + return printPostfixAbilityDeclarations; + case StructDefinition.DatatypeFields: + return printDatatypeFields; + case StructDefinition.NamedFields: + return printNamedFields; + case StructDefinition.PositionalFields: + return printPositionalFields; + case StructDefinition.FieldAnnotation: + return printFieldAnnotation; + case StructDefinition.ApplyType: + return printApplyType; + case StructDefinition.StructIdentifier: + return printIdentifier; + } + + return null; +} + +export enum StructDefinition { + /** + * Module-level definition + * ``` + * public struct identifier ... + * ``` + */ + StructDefinition = 'struct_definition', + /** + * Module-level definition (features `native` keyword and has no fields) + * ``` + * native struct identifier ... ; + * ``` + */ + NativeStructDefinition = 'native_struct_definition', + AbilityDeclarations = 'ability_decls', + /** + * Postfix ability declarations must be printed after the fields + * and be followed by a semicolon. + * ``` + * struct ident {} has store; + * struct Point(u8) has store, drop; + * ``` + */ + PostfixAbilityDeclarations = 'postfix_ability_decls', + DatatypeFields = 'datatype_fields', + NamedFields = 'named_fields', + PositionalFields = 'positional_fields', + FieldAnnotation = 'field_annotation', + ApplyType = 'apply_type', + StructIdentifier = 'struct_identifier', +} + +/** + * Print `struct_definition` node. + */ +export function printNativeStructDefinition( + path: AstPath, + options: ParserOptions, + print: printFn, +): Doc { + const isPublic = path.node.child(0)!.type === 'public' ? ['public', ' '] : []; + return group([ + ...isPublic, // insert `public` keyword if present + 'native', + ' ', + 'struct', + ' ', + path.map(print, 'nonFormattingChildren'), + ';', + ]); +} + +/** + * Print `struct_definition` node. + * Insert a newline before the comment if the previous node is not a line comment. + */ +export function printStructDefinition( + path: AstPath, + options: ParserOptions, + print: printFn, +): Doc { + const isPublic = path.node.child(0)!.type === 'public' ? ['public', ' '] : []; + return group([ + ...isPublic, // insert `public` keyword if present + 'struct', + ' ', + path.map(print, 'nonFormattingChildren'), + ]); +} + +type Ability = { name: 'key' | 'store' | 'drop'; text: Doc }; + +/** + * Print `ability_decls` node. + */ +export function printAbilityDeclarations( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const abilities = formatAndSortAbilities(path, options, print); + return [ + ' has ', + join( + ', ', + abilities.map((ability) => ability.text), + ), + path.next?.namedChildren[0]?.type === StructDefinition.PositionalFields ? ' ' : '', + ]; +} + +/** + * Print `postfix_ability_decls` node. + */ +export function printPostfixAbilityDeclarations( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const abilities = formatAndSortAbilities(path, options, print); + return group([ + ' has ', + join( + ', ', + abilities.map((ability) => ability.text), + ), + ';', + ]); +} + +/** + * Print `datatype_fields` node. + * Prints the underlying fields of a datatype. + */ +export function printDatatypeFields( + path: AstPath, + options: ParserOptions, + print: printFn, +): Doc { + return path.map(print, 'nonFormattingChildren'); +} + +/** + * Print `named_fields` node. + * Prints the underlying fields of a struct. + */ +export function printNamedFields(path: AstPath, options: MoveOptions, print: printFn): Doc { + const children = path.map(print, 'nonFormattingChildren'); + + if (children.length === 0) { + return [' ', emptyBlockOrList(path, '{', '}', doc.builders.line)]; + } + + return [ + ' ', + group(list({ path, print, options, open: '{', close: '}', addWhitespace: true }), { + shouldBreak: shouldBreakFirstChild(path), + }), + ]; +} + +/** + * Print `positional_fields` node. + * Prints the underlying fields of a struct. + */ +export function printPositionalFields( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const children = path.map(print, 'nonFormattingChildren'); + + if (children.length === 0) { + return emptyBlockOrList(path, '(', ')', doc.builders.line); + } + + return group(list({ path, print, options, open: '(', close: ')' }), { + shouldBreak: false, + }); +} + +/** + * Print `field_annotation` node. + */ +export function printFieldAnnotation( + path: AstPath, + options: ParserOptions, + print: printFn, +): Doc { + return group([ + path.call(print, 'nonFormattingChildren', 0), // field_identifier + ':', + ' ', + path.call(print, 'nonFormattingChildren', 1), // type + ]); +} + +/** + * Print `apply_type` node. + */ +export function printApplyType(path: AstPath, options: ParserOptions, print: printFn): Doc { + return path.map(print, 'nonFormattingChildren'); +} + +/** + * Utility function which formats and sorts abilities in the following order:: + * + * - key + * - copy + * - drop + * - store + * + * Key always goes first, the rest are sorted alphabetically. + */ +function formatAndSortAbilities( + path: AstPath, + options: MoveOptions, + print: printFn, +): Ability[] { + const abilities: Ability[] = path.map( + (path) => ({ + name: path.node.text as Ability['name'], + text: [ + printLeadingComment(path, options), + path.node.text, + printTrailingComment(path, true), + ] as Doc, + }), + 'nonFormattingChildren', + ); + + // alphabetical but `key` always goes first + const priority = { + key: 0, + copy: 1, + drop: 2, + store: 3, + }; + + abilities.sort((a, b) => priority[a.name] - priority[b.name]); + + return abilities; +} diff --git a/external-crates/move/tooling/prettier-move/src/cst/use_declaration.ts b/external-crates/move/tooling/prettier-move/src/cst/use_declaration.ts new file mode 100644 index 00000000000..448d53365d4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/cst/use_declaration.ts @@ -0,0 +1,231 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '..'; +import { AstPath, Doc, doc } from 'prettier'; +import { MoveOptions, printFn, treeFn } from '../printer'; +const { group, indent, line, softline, ifBreak, join } = doc.builders; + +export default function (path: AstPath): treeFn | null { + switch (path.node.type) { + case UseDeclaration.UseDeclaration: + return printUseDeclaration; + case UseDeclaration.UseModule: + return printUseModule; + case UseDeclaration.UseMember: + return printUseMember; + case UseDeclaration.UseModuleMember: + return printUseModuleMember; + case UseDeclaration.UseModuleMembers: + return printUseModuleMembers; + case UseDeclaration.UseFun: + return printUseFun; + case UseDeclaration.ModuleIdentity: + return printModuleIdentity; + case UseDeclaration.FriendDeclaration: + return printFriendDeclaration; + case UseDeclaration.FriendAccess: + return printFriendAccess; + default: + return null; + } +} + +/** + * Use Declaration + * + * Contains one of the following: + * + * `use_declaration` ( + * - use `use_module` ; + * - use `use_module_member` ; + * - use `use_module_members`; + * - use `use_fun`; + * ) + * + * `use_member` ( + * - `identifier` ; + * ) + */ +export enum UseDeclaration { + /** + * Module-level definition + * ``` + * ` use ...; + * ``` + */ + UseDeclaration = 'use_declaration', + FriendDeclaration = 'friend_declaration', + FriendAccess = 'friend_access', + UseFun = 'use_fun', + + // all of the nodes below are implemented in `import-grouping.ts` + // hence should never be printed directly. + + UseModule = 'use_module', + UseMember = 'use_member', + UseModuleMember = 'use_module_member', + UseModuleMembers = 'use_module_members', + ModuleIdentity = 'module_identity', +} + +/** + * Print @see `UseDeclaration.UseDeclaration` node. + */ +export function printUseDeclaration( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + const firstChild = path.node.child(0); + const isPublic = firstChild && firstChild.type === 'public' ? ['public', ' '] : []; + return [ + ...isPublic, // insert `public` keyword if present + 'use ', + path.call(print, 'nonFormattingChildren', 0), + ';', + ]; +} + +/** + * Print `use_fun` node `module_access` as `module_access`.`function_identifier` + */ +export function printUseFun(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group([ + 'fun ', + path.call(print, 'nonFormattingChildren', 0), // module_access + ' as', + indent(line), + path.call(print, 'nonFormattingChildren', 1), // module_access + '.', + path.call(print, 'nonFormattingChildren', 2), // function_identifier + ]); +} + +/** + * Print `friend_declaration` node. + */ +export function printFriendDeclaration( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return group([ + 'friend', + indent(line), + path.call(print, 'nonFormattingChildren', 0), // module_access + ';', + ]); +} + +/** + * Print `friend_access` node. + */ +export function printFriendAccess( + path: AstPath, + options: MoveOptions, + print: printFn, +): Doc { + return path.map(print, 'nonFormattingChildren'); +} + +/** + * Print `use_module` node. `module_name` + * Currently only used for `use` with annotations. + */ +export function printUseModule(path: AstPath, options: MoveOptions, print: printFn): Doc { + return path.map((e) => { + if (e.node.type == 'as') return ' as '; + return print(e); + }, 'children'); +} + +/** + * Print `use_member` node. `member_name` + * Currently only used for `use` with annotations. + */ +export function printUseMember(path: AstPath, options: MoveOptions, print: printFn): Doc { + const isGroup = path.node.children.findIndex((e) => e.type == '{'); + + // not found `::{...}` + if (isGroup == -1) { + return group( + path.map((e) => { + if (e.node.type == 'as') return ' as '; + if (e.node.type == ',') return [',', line]; + return print(e); + }, 'children'), + ); + } + + const children = path.map(print, 'nonFormattingChildren'); + + return group([ + children[0]!, + '::{', + indent(softline), + indent(join([',', line], children.slice(1))), + ifBreak(','), // trailing comma + softline, + '}', + ]); +} + +/** + * Print `use_module_member` node. `module_name::member_name` + * Single statement of direct import; + * `use address::module_name::member_name;` + * + * Wraps the member into a group `{}` if it's too long (if line breaks). + * Currently only used for `use` with annotations. + */ +export function printUseModuleMember(path: AstPath, options: MoveOptions, print: printFn): Doc { + return group([ + path.call(print, 'nonFormattingChildren', 0), // module_access + '::', + ifBreak(['{', indent(line)]), // wrap with `{` if the member is too long + indent(path.call(print, 'nonFormattingChildren', 1)), // module_access + ifBreak([line, '}']), // trailing comma + ]); +} + +/** + * Print `use_module_members` node. `module_identity::{member_name, member_name}` + * Currently only used for `use` with annotations. + */ +export function printUseModuleMembers(path: AstPath, options: MoveOptions, print: printFn): Doc { + const children = path.map(print, 'nonFormattingChildren'); + return group([ + children[0]!, + '::{', + indent(softline), + indent(join([',', line], children.slice(1))), + ifBreak(','), // trailing comma + softline, + '}', + ]); +} + +/** + * Print the `module_identity` node. `module_identifier::module_name`. + * Is present in the `use_module_member` and `use_module_members` nodes. + * Currently only used for `use` with annotations. + */ +export function printModuleIdentity(path: AstPath, options: MoveOptions, print: printFn): Doc { + return join('::', path.map(print, 'nonFormattingChildren')); +} + +/** + * Checks whether the given path is a `use` import. + */ +export function isUseImport(node: Node): boolean { + const firstChild = node.nonFormattingChildren[0]!; + + return ( + node.type === UseDeclaration.UseDeclaration && + (firstChild.type === UseDeclaration.UseModule || + firstChild.type === UseDeclaration.UseModuleMember || + firstChild.type === UseDeclaration.UseModuleMembers) + ); +} diff --git a/external-crates/move/tooling/prettier-move/src/imports-grouping.ts b/external-crates/move/tooling/prettier-move/src/imports-grouping.ts new file mode 100644 index 00000000000..8aa6e060c35 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/imports-grouping.ts @@ -0,0 +1,295 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/** + * This module contains the logic for grouping imports in a file. + * + * @module imports-grouping + */ + +import { Doc, doc } from 'prettier'; +import { Node } from './'; +import { UseDeclaration } from './cst/use_declaration'; +const { join, softline, indent, line, group } = doc.builders; + +// === Import Grouping === + +/** + * A simple type to represent grouped imports. + */ +export type GroupedImports = { + [package_: string]: { + [module_: string]: Member[]; + }; +}; + +type Member = { + name: string | 'Self'; + alias: string | undefined; +}; + +/** + * Special function to print imports if import grouping is turned on. + * Important note: we don't use the `print` function for imports, as they're already + * parsed. We just need to print them in the correct order and format. + * + * We sort and avoid duplicates in the imports. To do so, we keep track of the + * printed keys (including alias!), and only print the import if it hasn't been + * printed before. + */ +export function printImports(imports: GroupedImports, option: 'module' | 'package'): Doc { + const pkgs = Object.keys(imports).sort(); + const result = [] as Doc[]; + + for (const pkg of pkgs) { + const modules = imports[pkg]; + + // typescript wants this + if (modules == undefined) { + continue; + } + + const keys = Object.keys(modules).sort(); + + // if grouped by module + if (option === 'module') { + for (const mod of keys) { + if (modules[mod] == undefined) continue; + result.push(['use ', pkg, '::', printModule(mod, modules[mod]), ';']); + } + } else { + // if grouped by package + const modulesDoc = [] as Doc[]; + + for (const mod of keys) { + if (modules[mod] == undefined) continue; + modulesDoc.push(printModule(mod, modules[mod])); + } + + modulesDoc.length === 1 + ? result.push(['use ', pkg, '::', modulesDoc[0]!, ';']) + : result.push([ + 'use ', + pkg, + '::', + group([ + '{', + indent(softline), + indent(join([',', line], modulesDoc)), + softline, + '}', + ]), + ';', + ]); + } + } + + return result; +} + +function printModule(mod: string, members: Member[]): Doc { + const printedKeys: string[] = []; + + // perform deduplication of imports + members = members.filter((m) => { + const key = [mod, m.name, m.alias || '-'].join(''); + if (printedKeys.includes(key)) return false; + printedKeys.push(key); + return true; + }); + + if (members.length === 1) { + const member = members[0]!; + if (member.name === 'Self') { + const alias = member.alias ? ` as ${member.alias}` : ''; + return `${mod}${alias}`; + } + + return [mod, '::', printMember(member)]; + } + + const selfIdx = members.findIndex((m) => m.name === 'Self'); + if (selfIdx !== -1) { + const self = members.splice(selfIdx, 1); + members = [...self, ...members]; + } + + return members.length === 0 + ? [mod] + : [ + mod, + '::', + group([ + '{', + indent(softline), + indent(join([',', line], members.map(printMember))), + softline, + '}', + ]), + ]; +} + +/** + * Print a single member of a module with an optional alias. + */ +function printMember({ name, alias }: Member): Doc { + const a = alias ? ` as ${alias}` : ''; + return `${name}${a}`; +} + +/** + * Special function which walks the current node and collects all `use` imports. + * Returns a tree of all imports in this file to be used for grouping. + * + * There are 3 main types of imports: + * - `use_module` - `module_access` ; + * - `use_module_member` - `::`; + * - `use_module_members` - `package::, , ...` + * + * @param node + * @returns + */ +export function collectImports(node: Node): GroupedImports { + const grouped: GroupedImports = {}; + const imports = node.nonFormattingChildren + .filter((n) => n.isGroupedImport) + .map((n) => n.nonFormattingChildren[0]!); + + for (let import_ of imports) { + switch (import_.type) { + // `module_access` ; + case UseDeclaration.UseModule: { + const moduleIdentity = import_.nonFormattingChildren[0]!; + const alias = import_.nonFormattingChildren[1]; + const [pkg, mod] = parseModuleIdentity(moduleIdentity); + + // we use `Self` in the tree to represent the current module + const rec = { name: 'Self', alias: alias?.text }; + + // if there hasn't been a registered package yet, add it + if (!grouped[pkg]) grouped[pkg] = {}; + if (!grouped[pkg][mod]) grouped[pkg][mod] = []; + + grouped[pkg][mod].push(rec); + + break; + } + // `::` + case UseDeclaration.UseModuleMember: { + const moduleIdentity = import_.nonFormattingChildren[0]!; + const [pkg, mod] = parseModuleIdentity(moduleIdentity); + const useMember = import_.nonFormattingChildren[1]!; + const [name, alias] = parseUseMember(useMember); + + if (!grouped[pkg]) grouped[pkg] = {}; + if (!grouped[pkg][mod]) grouped[pkg][mod] = []; + + grouped[pkg][mod].push({ name, alias }); + + break; + } + // The only tricky node in this scheme. `use_module_members` can be + // both for grouped by package and for grouped by module, so we have + // to detect which version it is and then dance off of that. + case UseDeclaration.UseModuleMembers: { + const children = import_.nonFormattingChildren; + const isGroupedByPackage = children[0]!.type === 'module_identifier'; + + if (!isGroupedByPackage && children[0]!.type !== UseDeclaration.ModuleIdentity) { + throw new Error('Expected `module_identity` or `module_identifier`'); + } + + // simple scenario: the first node is `module_identity` + if (!isGroupedByPackage) { + const moduleIdentity = children[0]!; + const [pkg, mod] = parseModuleIdentity(moduleIdentity); + const members = children.slice(1).map((n) => parseUseMember(n)); + + if (!grouped[pkg]) grouped[pkg] = {}; + if (!grouped[pkg][mod]) grouped[pkg][mod] = []; + + grouped[pkg][mod].push(...members.map(([name, alias]) => ({ name, alias }))); + + break; + } + + // complex scenario: the first node is `module_identifier` + // `use_member` can be recursive in this scenario with 1 level of nesting + const pkg = children[0]!.text; + if (!grouped[pkg]) grouped[pkg] = {}; + + children.slice(1).forEach((node) => { + if (!node) return; + + if (node.type !== UseDeclaration.UseMember) + throw new Error('Expected `use_member` node got `' + node.type + '`'); + + const [first, ...rest] = node.nonFormattingChildren; + if (!first || first.type !== 'identifier') + throw new Error('Expected `identifier` node in `use_module_members`'); + + const mod = first.text; + if (!grouped[pkg]![mod]) grouped[pkg]![mod] = []; + + // if there's only one member and it's the module. + if (!rest.length) { + grouped[pkg]![mod].push({ name: 'Self', alias: undefined }); + return; + } + + // ident + ident is an alias + if (rest.length == 1 && rest[0]?.type === 'identifier') { + if (rest[0].previousSibling?.type !== "as") { + grouped[pkg]![mod].push({ name: rest[0].text, alias: undefined }); + } else { + grouped[pkg]![mod].push({ name: 'Self', alias: rest[0].text }); + } + + return; + } + + // special case, no use member, but already expanded pair of identifiers. + if (rest.length == 2 && rest[0]?.type === 'identifier' && rest[1]?.type === 'identifier') { + if (rest[1].previousSibling?.type !== "as") { + throw new Error('Expected `as` keyword after module name'); + } + + grouped[pkg]![mod].push({ name: rest[0].text, alias: rest[1].text }); + return; + } + + // the rest are `use_member` nodes + const members = rest.map(parseUseMember); + grouped[pkg]![mod].push(...members.map(([name, alias]) => ({ name, alias }))); + }); + } + } + } + + return grouped; +} + +/** + * Parse a `module_identity` node returning a tuple of package and module. + */ +function parseModuleIdentity(node: Node): [string, string] { + if (node.type !== UseDeclaration.ModuleIdentity) { + throw new Error('Expected `module_identity` node'); + } + + const [pkg, mod] = node.nonFormattingChildren.map((n) => n.text); + return [pkg!, mod!]; +} + +/** + * Parse a simple `use_member` node returning a tuple of member and alias. + */ +function parseUseMember(node: Node): [string, string | undefined] { + if (node.type !== UseDeclaration.UseMember) { + throw new Error('Expected `use_member` node, got `' + node.type + '`'); + } + + const [member, alias] = node.nonFormattingChildren.map((n) => n.text); + return [member!, alias]; +} diff --git a/external-crates/move/tooling/prettier-move/src/index.ts b/external-crates/move/tooling/prettier-move/src/index.ts new file mode 100644 index 00000000000..6ec29c5b492 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/index.ts @@ -0,0 +1,120 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/** + * Contains the Prettier Plugin definition for the Move language. + * For more information on Prettier plugins, see https://prettier.io/docs/en/plugins.html + * + * The printing logic is implemented in the `printer` module, which is routing the + * specific node types defined in the `cst/*` modules. + * + * Additionally, `utilities` module contains helper functions for the printer. + * + * @module prettier-move + */ + +import * as path from 'path'; +import Parser = require('web-tree-sitter'); +import { print } from './printer'; +import { Tree } from './tree'; +import { + Parser as PrettierParser, + Printer, + Plugin, + SupportOption, + SupportLanguage, +} from 'prettier'; + +/** + * Alias for easier refactoring if the SyntaxNode is changed. + */ +export type Node = Tree; + +export const languages: SupportLanguage[] = [ + { + name: 'move', + extensions: ['.move'], + parsers: ['move'], + }, +]; + +export const parsers: { [key: string]: PrettierParser } = { + move: { + parse: (text: string): Promise => { + return (async (): Promise => { + await Parser.init(); + const parser = new Parser(); + const Lang = await Parser.Language.load( + path.join(__dirname, '..', 'tree-sitter-move.wasm'), + ); + parser.setLanguage(Lang); + return new Tree(parser.parse(text).rootNode); + })(); + }, + + astFormat: 'move', + locStart: () => -1, + locEnd: () => -1, + }, +}; + +export const printers: { [key: string]: Printer } = { + 'move': { print }, +}; + +export const options: Record = { + autoGroupImports: { + type: 'choice', + category: 'Global', + default: 'package', + description: "Group all use imports by 'package', 'module' or 'none'.", + choices: [ + { + value: 'package', + description: + 'Group imports by package, eg `use iota::{balance::Balance, coin::Coin}', + }, + { + value: 'module', + description: + 'Group imports by module eg\n`use iota::balance::Balance;\nuse iota::coin::Coin`', + }, + ], + }, + wrapComments: { + type: 'boolean', + category: 'Global', + default: false, + description: 'Wrap comments to the next line if the line is too long.', + }, + useModuleLabel: { + type: 'boolean', + category: 'Global', + default: true, + description: + 'Enable module labels instead of module with braces. This option will be ignored if there is more than one module in the file.', + }, + enableErrorDebug: { + type: 'boolean', + category: 'Global', + default: false, + description: 'Print ERROR nodes instead of throwing an error.', + }, +}; + +export const defaultOptions = { + tabWidth: 4, + useTabs: false, + printWidth: 100, + useModuleLabel: false, + groupImports: 'module', +}; + +export default { + languages, + parsers, + printers, + options, + defaultOptions, +} as Plugin; diff --git a/external-crates/move/tooling/prettier-move/src/printer.ts b/external-crates/move/tooling/prettier-move/src/printer.ts new file mode 100644 index 00000000000..6e15c5fd6d8 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/printer.ts @@ -0,0 +1,94 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/** + * Implements the printing logic for the Move language. Takes a syntax tree and + * returns a formatted string. + * + * @see [Prettier Plugin API](https://prettier.io/docs/en/dev/plugins.html) + * @module printer + */ + +import { AstPath, Doc, ParserOptions } from 'prettier'; +import { Node } from '.'; +import Common from './cst/common'; +import Formatting from './cst/formatting'; +import Module from './cst/module'; +import UseDeclaration from './cst/use_declaration'; +import Constant from './cst/constant'; +import StructDefinition from './cst/struct_definition'; +import FunctionDefinition from './cst/function_definition'; +import SourceFile from './cst/source_file'; +import Expression from './cst/expression'; +import Literal from './cst/literal'; +import { printLeadingComment, printTrailingComment } from './utilities'; +import EnumDefinition from './cst/enum_definition'; +import Annotation from './cst/annotation'; + +export type MoveOptions = ParserOptions & { + wrapComments: boolean; + alwaysBreakConditionals: boolean; + alwaysBreakStructDefinition: boolean; + useModuleLabel: boolean; + enableErrorDebug: boolean; + autoGroupImports: 'package' | 'module'; +}; + +export type printFn = (path: AstPath) => Doc; +export type treeFn = (path: AstPath, options: MoveOptions, print: printFn) => Doc; + +/** + * Print the AST node at the given path. + */ +export function print(path: AstPath, options: MoveOptions, print: printFn) { + // check if the node has an error child, if so, we throw an error or return the error text + const checkErrorsCb = (path: AstPath) => { + if (path.node.children.some((n) => n.type === 'ERROR')) { + if (options.enableErrorDebug) { + return ((path, options, print) => ['/* ERROR: */', path.node.text]) as treeFn; + } else { + throw new Error('tree-sitter failure on \n```\n' + path.node.text + '\n```'); + } + } + + if (path.node.children.some((n) => n.type === 'MISSING')) { + if (options.enableErrorDebug) { + return ((path, options, print) => ['/* MISSING: */', path.node.text]) as treeFn; + } else { + throw new Error('tree-sitter failure on \n```\n' + path.node.text + '\n```'); + } + } + + return null; + }; + + // for unimplemented / not yet implemented nodes, we just return the node type + const defautCb: treeFn = (path, options, print) => { + return path.node.type; + }; + + const fn = + checkErrorsCb(path) || + SourceFile(path) || + Annotation(path) || + Formatting(path) || + Common(path) || + Module(path) || + UseDeclaration(path) || + Constant(path) || + EnumDefinition(path) || + StructDefinition(path) || + FunctionDefinition(path) || + Expression(path) || + Literal(path) || + defautCb; + + return [ + printLeadingComment(path, options), + // if the node has a `skipFormattingNode` property, we just return + // the text without formatting it + path.node.skipFormattingNode ? path.node.text : fn(path, options, print), + printTrailingComment(path), + ]; +} diff --git a/external-crates/move/tooling/prettier-move/src/tree.ts b/external-crates/move/tooling/prettier-move/src/tree.ts new file mode 100644 index 00000000000..0332048c543 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/tree.ts @@ -0,0 +1,439 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import Parser = require('web-tree-sitter'); +import { isFormatting } from './cst/formatting'; +import { isUseImport } from './cst/use_declaration'; + +export interface Comment { + type: 'line_comment' | 'block_comment'; + text: string; + newline: boolean; +} + +export class Tree { + public type: string; + public text: string; + public isNamed: boolean; + public children: Tree[]; + public leadingComment: Comment[]; + public trailingComment: Comment | null; + public enableLeadingComment: boolean = true; + public enableTrailingComment: boolean = true; + + /** + * A reference lock to the parent node. This is a function that returns the + * parent node. This way we remove the duplicate reference to the parent node + * and avoid circular references. + */ + private getParent: () => Tree | null; + + /** + * Marks if the comment has been used. This is useful to avoid using the same + * comment multiple times + filter out comments that are already used. + */ + private isUsedComment: boolean = false; + + /** + * Construct the `Tree` node from the `Parser.SyntaxNode`, additionally, run + * some passes to clean-up the tree and make the structure more manageable and + * easier to work with. + * + * Passes: + * - Sum-up pairs of newlines into a single empty line. + * - Filter out sequential empty lines. + * - Filter out leading and trailing empty lines. + * - Assign trailing comments to the node. + * - Assign leading comments to the node. + * - Filter out all assigned comments. + * + * @param node + * @param parent + */ + constructor(node: Parser.SyntaxNode, parent: Tree | null = null) { + this.type = node.type; + this.text = node.text; + this.isNamed = node.isNamed(); + this.leadingComment = []; + this.trailingComment = null; + this.getParent = () => parent; + + // === Clean-up passes === + + // turn every node into a `Tree` node. + this.children = node.children.map((child) => new Tree(child, this)); + + // sum-up pairs of newlines into a single empty line. + this.children = this.children.reduce((acc, node) => { + if (node.isNewline && node.nextSibling?.isNewline) node.type = 'empty_line'; + if (node.isNewline && acc[acc.length - 1]?.isEmptyLine) return acc; + return [...acc, node]; + }, [] as Tree[]); + + // filter out sequential empty lines. + this.children = this.children.filter((node) => { + return !node.isEmptyLine || !node.previousNamedSibling?.isEmptyLine; + }); + + // filter out leading and trailing empty lines. + this.children = this.children.filter((node) => { + if (!node.isEmptyLine) return true; // we only filter out empty lines + if (!node.previousNamedSibling) return false; // remove leading empty lines + if (!node.nextNamedSibling) return false; // remove trailing empty lines + return true; + }); + + // assign trailing comments to the node. modifies the tree in place. + this.children.forEach((child) => child.assignTrailingComments()); + + // assign leading comments to the node. modifies the tree in place. + this.children.forEach((child) => child.assignLeadingComments()); + + // filter out all leading comments. + this.children = this.children.filter((child) => !child.isUsedComment); + } + + /** + * Special case for lists, where we want to print the trailing comma. + */ + disableTrailingComment() { + this.enableTrailingComment = false; + } + + /** + * Special case for lists, where we want to print the leading character (eg `dot_expression`). + */ + disableLeadingComment() { + this.enableLeadingComment = false; + } + + /** + * Find the parent node of a specific type. Optionally, break on a specific type. + */ + findParentUntil(type: string, breakOn: string[]): Tree | null { + let parent = this.parent; + while (parent) { + if (parent.type === type) return parent; + if (breakOn.includes(parent.type)) return null; + parent = parent.parent; + } + + return null; + } + + /** + * Check if the previous sibling is an annotation node. Ignore formatting nodes. + */ + get hasAnnotation(): boolean { + let prev = this.previousNamedSibling; + while (prev) { + if (prev.type === 'annotation') return true; + if (!prev.isFormatting) return false; + prev = prev.previousNamedSibling; + } + return false; + } + + /** + * A flag to skip formatting for a specific node. A manual instruction from + * the user is `prettier-ignore`. When placed above (leading comment) a node, + * it will skip formatting for that node. + */ + get skipFormattingNode(): boolean { + return ( + !!this.leadingComment.find((comment) => comment.text.includes('prettier-ignore')) || + false + ); + } + + /** + * Get the number of named children. + */ + get namedChildCount(): number { + return this.namedChildren.length; + } + + get isFunctionCall(): boolean { + return this.type === 'call_expression' || this.type === 'macro_call_expression'; + } + + /** + * Tells whether a `Node` knows how to break itself. + * Nodes that match the following types are considered breakable: + * - `dot_expression` + * - `vector_expression` + * - `expression_list` + * - `if_expression` (?) + * - `pack_expression` + * - `match_expression` + * - `block` + */ + get isBreakableExpression(): boolean { + return [ + // TODO: consider revisiting `call_expression` and `macro_call_expression` + // 'call_expression', + // 'macro_call_expression', + 'dot_expression', + 'vector_expression', + 'expression_list', + 'if_expression', + 'pack_expression', + 'match_expression', + 'block', + ].includes(this.type); + } + + /** + * Whether a node is a list node, like `vector_expression`, `expression_list`, or `block`. + * Lists are typical breakable nodes, where each element is separated by a newline. + */ + get isList(): boolean { + return ['vector_expression', 'expression_list', 'block'].includes(this.type); + } + + /** + * Whether a node is a control flow node, like `if_expression`, `while_expression`, + * `loop_expression`, `abort_expression`, or `return_expression`. + */ + get isControlFlow(): boolean { + return [ + 'if_expression', + 'while_expression', + 'loop_expression', + 'abort_expression', + 'return_expression', + ].includes(this.type); + } + + /** + * Important part of the `imports-grouping` functionality. This flag is used to + * determine whether a node is an `use_module`, `use_module_members` or + * `use_module_member` node to skip their printing if they're printed as grouped. + */ + get isGroupedImport(): boolean { + return isUseImport(this) && !this.hasAnnotation; + } + + /** + * Whether a node is a `Formatting` node, like `line_comment`, `block_comment`, + * `empty_line`, or `next_line`. + */ + get isFormatting(): boolean { + return isFormatting(this); + } + + child(index: number): Tree | null { + return this.children[index] || null; + } + + get isEmptyLine(): boolean { + return this.type === 'empty_line'; + } + + get isNewline(): boolean { + return this.type === 'newline'; + } + + get isComment(): boolean { + return this.type === 'line_comment' || this.type === 'block_comment'; + } + + get isTypeParam(): boolean { + return [ + 'apply_type', + 'ref_type', + 'tuple_type', + 'function_type', + 'primitive_type' + ].includes(this.type); + } + + get previousSibling(): Tree | null { + const parent = this.getParent(); + if (!parent) { + return null; + } + + const index = parent.children.indexOf(this); + if (index === 0) { + return null; + } + + return parent.children[index - 1] || null; + } + + get previousNamedSibling(): Tree | null { + let node = this.previousSibling; + while (node && !node.isNamed) { + node = node.previousSibling; + } + return node; + } + + get startsOnNewLine(): boolean { + return this.previousSibling?.isNewline || false; + } + + get nonFormattingChildren(): Tree[] { + return this.namedChildren.filter((child) => !child.isFormatting); + } + + get namedChildren(): Tree[] { + return this.children.filter((child) => child.isNamed); + } + + get firstNamedChild(): Tree | null { + return this.namedChildren[0] || null; + } + + get namedAndEmptyLineChildren(): Tree[] { + return this.namedChildren.filter((child) => { + return ( + child.isNamed && + (child.isEmptyLine || + (child.isComment && !child.isUsedComment) || + !child.isFormatting) + ); + }); + } + + get nextSibling(): Tree | null { + const parent = this.getParent(); + if (!parent) { + return null; + } + + const index = parent.children.indexOf(this); + if (index === parent.children.length - 1) { + return null; + } + + return parent.children[index + 1] || null; + } + + get nextNamedSibling(): Tree | null { + let node = this.nextSibling; + while (node && !node.isNamed) { + node = node.nextSibling; + } + return node; + } + + get parent() { + return this.getParent(); + } + + /** + * Print the Node as a JSON object. Remove the fields that are not necessary + * for printing. May be extended shall one need to debug deeper. + */ + toJSON(): any { + return { + type: this.type, + isNamed: this.isNamed, + children: this.children.map((child) => child.toJSON()), + leadingComment: this.leadingComment, + trailingComment: this.trailingComment, + }; + } + + /** + * Checks the following node and assigns it as a trailing comment if it is a comment. + * The comment is then marked as used and will not be used again. + */ + private assignTrailingComments(): Tree { + if (!this.isNamed) return this; + if (this.isFormatting) return this; + + const nextNamed = this.nextNamedSibling; + + if (!nextNamed?.isComment) return this; + if (nextNamed.isUsedComment) return this; + + // if it's a block comment, we need to make sure there's nothing in + // between the current node and the comment, otherwise block comment is + // associated with the next node. + if (nextNamed.type == 'block_comment') { + // any non-named node between the current node and the comment + // breaks the association. + if (nextNamed.previousSibling != this && !!nextNamed.nextNamedSibling) return this; + const addSpace = !!nextNamed.nextNamedSibling ? ' ' : ''; + + this.trailingComment = { + type: nextNamed.type as 'line_comment' | 'block_comment', + text: nextNamed.text + addSpace, + newline: false, + }; + this.nextNamedSibling!.isUsedComment = true; + } + + if (nextNamed.type == 'line_comment') { + this.trailingComment = { + type: nextNamed.type as 'line_comment' | 'block_comment', + text: nextNamed.text, + newline: false, + }; + + this.nextNamedSibling!.isUsedComment = true; + } + + return this; + } + + /** + * Walks backwards through the siblings and searches for comments preceding + * the current node. If a comment is found, it is assigned to the `leadingComment` + * property of the node, and the comment is marked as used. + * + * Used comments are filtered out and not used again. + * + * Motivation for this is to avoid duplicate association of a comment both as + * a trailing comment and a leading comment. + */ + private assignLeadingComments(): Tree { + let comments = []; + let prev = this.previousNamedSibling; + let newline = false; + + if (!this.isNamed) return this; + if (this.isFormatting) return this; + + while (prev?.isNewline) { + newline = true; + prev = prev.previousNamedSibling; + } + + if (prev?.type == 'block_comment') { + if (prev.isUsedComment) return this; + + comments.unshift({ + type: prev.type as 'line_comment' | 'block_comment', + text: prev.text, + newline, + }); + + prev.isUsedComment = true; + this.leadingComment = comments; + return this; + } + + while (prev?.isComment || (prev?.isNewline && !prev?.isUsedComment)) { + if (prev.isUsedComment) break; + if (prev.isComment) { + comments.unshift({ + type: prev.type as 'line_comment' | 'block_comment', + text: prev.text, + newline: true, + }); + prev.isUsedComment = true; + } + + prev = prev.previousNamedSibling; // move to the previous comment + } + + this.leadingComment = comments; + + return this; + } +} diff --git a/external-crates/move/tooling/prettier-move/src/utilities.ts b/external-crates/move/tooling/prettier-move/src/utilities.ts new file mode 100644 index 00000000000..9ac802fecc8 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/src/utilities.ts @@ -0,0 +1,388 @@ +// Copyright (c) The Move Contributors +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Node } from '.'; +import { AstPath, Doc, ParserOptions, doc } from 'prettier'; +import { MoveOptions, printFn } from './printer'; + +const { + indent, + join, + fill, + softline, + dedent, + hardline, + line, + lineSuffix, + group, + indentIfBreak, + hardlineWithoutBreakParent, + breakParent, + ifBreak, +} = doc.builders; + +/** + * Prints an `identifier` node. + */ +export function printIdentifier(path: AstPath): Doc { + return path.node.text; +} + +/** + * Returns `true` if the first non-formatting child of the path starts on a new line. + * This function is useful for respecting developer formatting if they choose to break + * the list. + * + * ```move + * // input + * fun args(a: u8) {} // no break + * fun args( + * a: u8 // first child starts on a new line + * ) {} + * + * // output + * fun args(a: u8) {} // no break + * fun args( + * a: u8 // respect developer formatting + * ) {} + * ``` + * + * @param path + * @returns + */ +export function shouldBreakFirstChild(path: AstPath): boolean { + return path.node.nonFormattingChildren[0]?.startsOnNewLine || false; +} + +/** + * Prints all comments that are leading the node. This function is injected into + * the `printFn` to print comments before the node. See the `print` function in + * `printer.ts` for more information. + * + * @param path + * @returns + */ +export function printLeadingComment(path: AstPath, options: MoveOptions): Doc[] { + const comments = path.node.leadingComment; + if (!comments || !comments.length) return []; + if (!path.node.enableLeadingComment) return []; + + if (comments.length == 1 && comments[0]!.type == 'block_comment') { + return [comments[0]!.text, comments[0]!.newline ? hardlineWithoutBreakParent : ' ']; + } + + if (options.wrapComments == false) { + return [ + join( + hardlineWithoutBreakParent, + comments.map((c) => + c.type == 'line_comment' ? [c.text, /* used to be breakParent */ ''] : [c.text], + ), + ), + hardlineWithoutBreakParent, + ]; + } + + // we do not concatenate the comments into a single string, and treat each + // line separately. + return comments.map((comment) => { + if (comment.type == 'line_comment') { + const isDoc = comment.text.startsWith('///'); + const parts = comment.text.slice(isDoc ? 4 : 3).split(' '); + + return [ + isDoc ? '/// ' : '// ', + fill(join(ifBreak([softline, isDoc ? '/// ' : '// '], ' '), parts)), + hardlineWithoutBreakParent, + ]; + } + + return comment.text; + }); +} + +/** + * Prints the trailing comments of the node. Currently, we only allow a single line + * comment to be printed. This function is injected into the `printFn` to print + * comments after the node. See the `print` function in `printer.ts` for more information. + * + * @param path + * @returns + */ +export function printTrailingComment(path: AstPath, shouldBreak: boolean = false): Doc { + // we do not allow comments on empty lines + if (path.node.isEmptyLine) return ''; + if (!path.node.enableTrailingComment) return ''; + const comment = path.node.trailingComment; + if (!comment) return ''; + if (comment.type == 'line_comment' && shouldBreak) { + return [' ', comment.text, hardline]; + } + + return [' ', comment.text]; +} + +export function emptyBlockOrList( + path: AstPath, + open: string, + close: string, + line: Doc = hardline, +): Doc { + const length = path.node.nonFormattingChildren.length; + const comments = path.node.namedChildren.filter((e) => e.isComment); + + if (length != 0) { + throw new Error('The list is not empty'); + } + + if (comments.length == 0) { + return [open, close]; + } + + if (comments.length == 1 && comments[0]!.type == 'block_comment') { + return group([open, indent(line), indent(comments[0]!.text), line, close]); + } + + return group( + [ + open, + indent(line), + indent( + join( + line, + comments.map((c) => c.text), + ), + ), + line, + close, + ], + { shouldBreak: true }, + ); +} + +/** + * TODO: use this type for the `block()` function. + */ +export type BlockOptions = { + path: AstPath; + print: printFn; + options: ParserOptions; + breakDependency?: Symbol; + + lastLine?: boolean; + lineEnding?: Doc; + skipChildren?: number; + shouldBreak?: boolean; +}; + +/** + */ +export function block({ path, print, options, shouldBreak, skipChildren }: BlockOptions) { + const length = path.node.nonFormattingChildren.length; + + if (length == 0) { + return emptyBlockOrList(path, '{', '}', hardline); + } + + return group( + [ + '{', + options.bracketSpacing ? ifBreak('', ' ') : '', + indent(softline), + indent(join(line, path.map(print, 'namedAndEmptyLineChildren').slice(skipChildren))), + softline, + options.bracketSpacing ? ifBreak('', ' ') : '', + '}', + ], + { shouldBreak }, + ); +} + +export function nonBreakingBlock({ + path, + print, + options, + shouldBreak, // always breaks + skipChildren, +}: BlockOptions) { + const length = path.node.nonFormattingChildren.length; + + if (length == 0) { + return emptyBlockOrList(path, '{', '}', hardlineWithoutBreakParent); + } + + return group([ + '{', + indent(hardlineWithoutBreakParent), + indent( + join( + hardlineWithoutBreakParent, + path.map(print, 'namedAndEmptyLineChildren').slice(skipChildren || 0), + ), + ), + hardlineWithoutBreakParent, + '}', + ]); +} + +export type ListOptions = { + path: AstPath; + print: printFn; + options: MoveOptions; + /** Opening bracket. */ + open: string; + /** Closing bracket. */ + close: string; + /** + * The number of children to skip when printing the list. + */ + skipChildren?: number; + /** + * Whether to add a whitespace after the open bracket and before the close bracket. + * ``` + * { a, b, c } // addWhitespace = true + * {a, b, c} // addWhitespace = false + * ``` + */ + addWhitespace?: boolean; + /** + * Whether to break the list. + */ + shouldBreak?: boolean; + /** + * Group ID for `indentIfBreak` to break the list. + */ + indentGroup?: symbol | null; +}; + +/** + * Prints a list of non-formatting children. Handles commas and trailing comments. + * TODO: keep trailing comments after the last element of the list. + */ +export function list({ + path, + print, + options, + open, + close, + indentGroup = null, + addWhitespace = false, + skipChildren = 0, + shouldBreak = false, +}: ListOptions) { + const length = path.node.nonFormattingChildren.length; + const indentCb: (el: Doc) => Doc = (el) => + indentGroup ? indentIfBreak(el, { groupId: indentGroup }) : indent(el); + + // if there's no children the list should print, we still look up for non- + // formatting nodes, namely comments, to print them. + if (length == skipChildren) { + const lastNode = path.node.nonFormattingChildren[length - 1]!; + const indexInNamedChildren = path.node.namedChildren.indexOf(lastNode); + const otherNamedChildren = path.node.namedChildren + .slice(indexInNamedChildren + 1) + .filter((e) => e.isComment); + + if (!otherNamedChildren.length) { + return [open, close]; + } + + return [ + open, + indentCb(softline), + indentCb( + join( + hardline, + otherNamedChildren.map((c) => c.text), + ), + ), + hardline, + dedent(close), + ]; + } + + const lastNode = path.node.nonFormattingChildren[length - 1]!; + const indexInNamedChildren = path.node.namedChildren.indexOf(lastNode); + + // collect all trailing comments + // after `nonFormattingChildren` and before end + let trailingComments = [] as Doc[]; + if (indexInNamedChildren != -1) { + path.each((path, idx) => { + if (idx + 1 > indexInNamedChildren && path.node.isComment) { + return trailingComments.push(path.node.text); + } + return; + }, 'namedChildren'); + } + + return [ + open, + indentCb(addWhitespace ? line : softline), + shouldBreak ? breakParent : '', + indentCb( + path + .map((path, i) => { + const leading = printLeadingComment(path, options); + const comment = printTrailingComment(path, false); + let shouldBreak = false; + + // if the node has a trailing comment, we should break + if (path.node.trailingComment?.type == 'line_comment') { + shouldBreak = true; + } + + const leadComment = path.node.leadingComment; + + if (leadComment.length > 0 && leadComment![0]!.type == 'line_comment') { + shouldBreak = true; + } + + if ( + leadComment.length > 0 && + leadComment[0]!.type == 'block_comment' && + leadComment[0]!.newline + ) { + shouldBreak = true; + } + + path.node.disableTrailingComment(); + path.node.disableLeadingComment(); + + const breakExpr = shouldBreak ? breakParent : ''; + const shouldDedent = trailingComments.length == 0; + const endingExpr = addWhitespace ? line : softline; + const isLastChild = i == length - 1; + + if (isLastChild) { + return [ + leading, + breakExpr, + print(path), + ifBreak(','), + shouldBreak ? lineSuffix(comment) : comment, + shouldDedent ? dedent(endingExpr) : endingExpr, + ]; + } + + // if we are not at the last child, add a comma + return [ + leading, + breakExpr, + print(path), + ',', + shouldBreak ? lineSuffix(comment) : comment, + line, + ]; + }, 'nonFormattingChildren') + .slice(skipChildren) + .concat( + trailingComments.length + ? [join(hardline, trailingComments), dedent(hardline)] + : [], + ), + ), + dedent(close), + ]; +} diff --git a/external-crates/move/tooling/prettier-move/tests/README.md b/external-crates/move/tooling/prettier-move/tests/README.md new file mode 100644 index 00000000000..19371b3c9ed --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/README.md @@ -0,0 +1,35 @@ +# Prettier Move Tests + +This directory contains tests for the package. + +## Running Tests + +To run the tests, you can use the following command: + +```bash +pnpm test +``` + +To regenerate expectations, you can use the following command: + +```bash +UB=1 pnpm test +``` + +## Test Structure + +The tests should be placed as `.move` files in this directory. All `.move` files will be treated as tests, and if there's no expectation file, one will be generated (`.exp.move`). Ideally, tests should cover all of the CST nodes defined in the `grammar.json`. + +## Special Features + +You can customize behaviour of prettier for a specific file by adding a comment at the top. If the file starts with `// options:`, the test runner will attempt to read the following lines as options for prettier. For example: + +```move +// options: +// tabWidth: 4 +// printWidth: 40 + +module prettier::test {} +``` + +Currently, only 2 options are supported: `tabWidth` and `printWidth`. diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.exp.move new file mode 100644 index 00000000000..cb93b569203 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.exp.move @@ -0,0 +1,22 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::abort_expression; + +fun abort_expression() { + abort 0; + abort (0); + abort (10); + abort { + 10 + }; + abort 100 + 300; + abort if (condition) 100 else 200; + + abort if (condition) { + 100 + } else { + 200 + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.move b/external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.move new file mode 100644 index 00000000000..214d610bb45 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/abort_expression.move @@ -0,0 +1,22 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::abort_expression; + +fun abort_expression() { + abort 0; + abort(0); + abort (10); + abort { + 10 + }; + abort 100 + 300; + abort if (condition) 100 else 200; + + abort if (condition) { + 100 + } else { + 200 + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.exp.move new file mode 100644 index 00000000000..dd587a44bc5 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.exp.move @@ -0,0 +1,100 @@ +// options: +// printWidth: 80 + +module test::if_expression { + public fun basic() { + if (true) call_something(); + if (false) + call_something_else_call_something_else_call_something_else(); + + if (cond) do_this() else { + do_that(); + do_this(); + }; + + if (cond) { + do_this(); + do_that(); + } else do_this(); + + if (true) call_something() + else call_something_else(); + + if (false) { + call_something_else(); + } else { + another_call(); + }; + + if (very_long_binding) { + call_something(); + } else { + call_something_else(); + }; + } + + public fun control_flow() { + if (true) return call_something(); + if (true) + return call_something_else_call_something_else_call_something_else(); + } + + public fun folding() { + if (true) call_something() + else if (false) call_something_else() + else call_something_otherwise(); + + if (true) { + call_something() + } else if (false) { + call_something_else() + } else { + call_something_otherwise() + }; + + // should keep as is, no additions; + if (true) { + let a = b; + }; + + if (very_very_long_if_condition) + very_very_long_if_condition > very_very_long_if_condition; + + let a = if (true) { + call_something_else(); + } else { + call_something_else(); + }; + + if ( + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition + very_very_long_if_condition > 100 && + very_very_long_if_condition + ) + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition; + // should break list of expressions inside parens, with indent; + if ( + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition + very_very_long_if_condition > 100 && + very_very_long_if_condition + ) { + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition; + }; + + if (very_very_long_if_condition > very_very_long_if_condition) + return very_very > very_very_long_if_condition + 100; + + if ( + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition + ) + return very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition > very_very_long_if_condition + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.move b/external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.move new file mode 100644 index 00000000000..4efe48b7e71 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/if_expression.move @@ -0,0 +1,100 @@ +// options: +// printWidth: 80 + +module test::if_expression { + public fun basic() { + if (true) call_something(); + if (false) call_something_else_call_something_else_call_something_else(); + + + if (cond) do_this() + else { + do_that(); + do_this(); + }; + + if (cond) { + do_this(); + do_that(); + } else do_this(); + + + if (true) call_something() + else call_something_else(); + + if (false) { + call_something_else(); + } else { + another_call(); + }; + + if (very_long_binding) { + call_something(); + } else { + call_something_else(); + }; + } + + public fun control_flow() { + if (true) return call_something(); + if (true) return call_something_else_call_something_else_call_something_else(); + } + + public fun folding() { + + if (true) call_something() + else if (false) call_something_else() + else call_something_otherwise(); + + if (true) { + call_something() + } else if (false) { + call_something_else() + } else { + call_something_otherwise() + }; + + // should keep as is, no additions; + if (true) { let a = b; }; + + if (very_very_long_if_condition) + very_very_long_if_condition > very_very_long_if_condition; + + let a = if (true) { + call_something_else(); + } else { + call_something_else(); + }; + + if ( + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition + very_very_long_if_condition > 100 && + very_very_long_if_condition + ) + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition; + // should break list of expressions inside parens, with indent; + if ( + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition + very_very_long_if_condition > 100 && + very_very_long_if_condition + ) { + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition; + }; + + if (very_very_long_if_condition > very_very_long_if_condition) + return very_very > very_very_long_if_condition + 100; + + if ( + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition + ) + return very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition > very_very_long_if_condition + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.exp.move new file mode 100644 index 00000000000..5ca07dd466b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.exp.move @@ -0,0 +1,13 @@ +module test::loop_expression { + public fun test_loop() { + loop break; + + loop { + break; + }; + + loop { + break; + }; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.move b/external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.move new file mode 100644 index 00000000000..5ca07dd466b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/loop_expression.move @@ -0,0 +1,13 @@ +module test::loop_expression { + public fun test_loop() { + loop break; + + loop { + break; + }; + + loop { + break; + }; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.exp.move new file mode 100644 index 00000000000..3da45e52f1e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.exp.move @@ -0,0 +1,53 @@ +// option: +// print_width: 80 + +module test::return_expression { + public fun folding() { + // this is a return expression + return very_very > very_very_long_if_condition + 100; + return very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition > very_very_long_if_condition; // this is a trailing comment for return + return very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition; + return { + if (block_expression()) 1 + else 2 + }; + + // and top comment + return; // another trailing + + return { + a + b + }; + + return vector[ + first_return_value, + second_return_value, + third_return_value, + ]; + + if (cond) { + do_something_very_very_nasty_and_its_super_long_too_hahahahaa() + } else return; + + return ({ + a + b + }, first_return_value, second_return_value); + + return if (some_value) { + some_value + } else { + some_other_value + }; + + return if (some_value) some_value + else some_other_value; + + return ( + very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition, + very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition, + very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition, + ); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.move b/external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.move new file mode 100644 index 00000000000..6d2165b8ead --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/return_expression.move @@ -0,0 +1,54 @@ +// option: +// print_width: 80 + +module test::return_expression { + public fun folding() { + // this is a return expression + return very_very > very_very_long_if_condition + 100; + return very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition || + very_very_long_if_condition > very_very_long_if_condition; // this is a trailing comment for return + return very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition; + return { + if (block_expression()) 1 + else 2 + }; + + // and top comment + return; // another trailing + + return { a + b }; + + return vector[ + first_return_value, + second_return_value, + third_return_value + ]; + + if (cond) { + do_something_very_very_nasty_and_its_super_long_too_hahahahaa() + } + else return; + + return ( + { a + b }, + first_return_value, + second_return_value, + ); + + return if (some_value) { + some_value + } else { + some_other_value + }; + + return if (some_value) some_value + else some_other_value; + + return ( + very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition, + very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition, + very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition_very_very_long_if_condition + ); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.exp.move new file mode 100644 index 00000000000..79065ae0e56 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.exp.move @@ -0,0 +1,24 @@ +// options: +// printWidth: 60 +// tabWidth: 4 + +module test::while_expression { + fun test_while() { + // hey yall + 'a: {}; + + // comments + while (true) { + break; + }; + // hahaha + 'a: while ( + very_very_long_condition || + very_very_long_condition || + very_very_long_condition || + very_very_long_condition + ) { + break; + }; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.move b/external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.move new file mode 100644 index 00000000000..2614091af3e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/control-flow/while_expression.move @@ -0,0 +1,27 @@ +// options: +// printWidth: 60 +// tabWidth: 4 + +module test::while_expression { + fun test_while() { + + // hey yall + 'a: { + + }; + + // comments + while (true) { + break; + }; + // hahaha + 'a: while ( + very_very_long_condition || + very_very_long_condition || + very_very_long_condition || + very_very_long_condition + ) { + break; + }; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.exp.move b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.exp.move new file mode 100644 index 00000000000..2430af53309 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.exp.move @@ -0,0 +1,224 @@ +// options: +// useModuleLabel: true + +module match::test_module; + +fun run(x: u64): u64 { + match (x) { + 1 => 2, + 2 => 3, + x => x, + } +} + +public struct Wrapper(u64) + +// ERROR +fun add_under_wrapper_unless_equal(wrapper: Wrapper, x: u64): u64 { + match (wrapper) { + Wrapper(y) if (y == x) => Wrapper(y), + Wrapper(y) => y + x, + } +} + +public enum MyEnum has drop { + Variant(u64, bool), + OtherVariant(bool, u64), +} + +fun test_or_pattern(x: u64): u64 { + match (x) { + MyEnum::Variant(1 | 2 | 3, true) | + MyEnum::OtherVariant(true, 1 | 2 | 3) => 1, + MyEnum::Variant(8, true) | MyEnum::OtherVariant(_, 6 | 7) => 2, + _ => 3, + } +} + +fun test_lit(x: u64): u8 { + match (x) { + 1 => 2, + 2 => 3, + _ => 4, + } +} + +fun test_var(x: u64): u64 { + match (x) { + y => y, + } +} + +const MyConstant: u64 = 10; + +fun test_constant(x: u64): u64 { + match (x) { + MyConstant => 1, + _ => 2, + } +} + +fun test_or_pattern(x: u64): u64 { + match (x) { + 1 | 2 | 3 => 1, + 4 | 5 | 6 => 2, + _ => 3, + } +} + +// ERROR +fun test_or_at_pattern(x: u64): u64 { + match (x) { + x @ 1 | 2 | 3 => x + 1, + y @ 4 | 5 | 6 => y + 2, + z => z + 3, + } +} + +fun f(x: MyEnum) { + match (x) { + MyEnum::Variant(1, true) => 1, + MyEnum::OtherVariant(_, 3) => 2, + MyEnum::Variant(..) => 3, + MyEnum::OtherVariant(..) => 4, + } +} + +fun f(x: MyEnum) { + match (x) { + MyEnum::Variant(1 | 2 | 10, true) => 1, + MyEnum::OtherVariant(_, 3) => 2, + MyEnum::Variant(..) => 3, + MyEnum::OtherVariant(..) => 4, + } +} + +public struct NonDrop(u64) + +fun drop_nondrop(x: NonDrop) { + match (x) { + NonDrop(1) => 1, + _ => 2, + // ERROR: cannot wildcard match on a non-droppable value + } +} + +fun destructure_nondrop(x: NonDrop) { + match (x) { + NonDrop(1) => 1, + NonDrop(_) => 2, + // OK! + } +} + +fun use_nondrop(x: NonDrop): NonDrop { + match (x) { + NonDrop(1) => NonDrop(8), + x => x, + } +} + +public enum MyEnum { + Variant(u64, bool), + OtherVariant(bool, u64), +} + +public struct Pair(T, T) + +fun f(x: MyEnum): u8 { + match (x) { + MyEnum::Variant(1, true) => 1, + MyEnum::Variant(_, _) => 1, + MyEnum::OtherVariant(_, 3) => 2, + // Now exhaustive since this will match all values of MyEnum::OtherVariant + MyEnum::OtherVariant(..) => 2, + } +} + +fun match_pair_bool(x: Pair): u8 { + match (x) { + Pair(true, true) => 1, + Pair(true, false) => 1, + Pair(false, false) => 1, + // Now exhaustive since this will match all values of Pair + Pair(false, true) => 1, + } +} + +// ERROR +fun match_with_guard(x: u64): u64 { + match (x) { + 1 if (false) => 1, + 1 => 2, + _ => 3, + } +} + +public struct MyStruct(u64) + +fun mut_on_immut(x: &MyStruct): u64 { + match (x) { + MyStruct(mut y) => { + y = &(*y + 1); + *y + }, + } +} + +fun mut_on_value(x: MyStruct): u64 { + match (x) { + MyStruct(mut y) => { + *y = *y + 1; + *y + }, + } +} + +fun mut_on_mut(x: &mut MyStruct): u64 { + match (x) { + MyStruct(mut y) => { + *y = *y + 1; + *y + }, + } +} + +public struct MyStruct(u64, u64, u64, u64) has drop; + +public struct MyStruct2 { + x: u64, + y: u64, + z: u64, + w: u64, +} + +fun wild_match(x: MyStruct) { + match (x) { + MyStruct(.., 1) => 1, + // OK! The `..` pattern can be used at the beginning of the constructor pattern + MyStruct(1, ..) => 2, + // OK! The `..` pattern can be used at the end of the constructor pattern + MyStruct(1, .., 1) => 3, + // OK! The `..` pattern can be used at the middle of the constructor pattern + MyStruct(1, .., 1, 1) => 4, + MyStruct(..) => 5, + } +} + +fun wild_match2(x: MyStruct2) { + match (x) { + MyStruct2 { x: 1, .. } => 1, + MyStruct2 { x: 1, w: 2, .. } => 2, + MyStruct2 { .. } => 3, + } +} + +/// Convert a `u64` index to a `Colour`. +public fun from_index(index: u64): Colour { + match (index) { + 0 => Colour::Empty, + 1 => Colour::Black, // ERROR + 2 => Colour::White, // ERROR + _ => abort 0, + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.move b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.move new file mode 100644 index 00000000000..ea03e20c6be --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter-match_test.move @@ -0,0 +1,223 @@ +// options: +// useModuleLabel: true + +module match::test_module; + +fun run(x: u64): u64 { + match (x) { + 1 => 2, + 2 => 3, + x => x, + } +} + +public struct Wrapper(u64) + +// ERROR +fun add_under_wrapper_unless_equal(wrapper: Wrapper, x: u64): u64 { + match (wrapper) { + Wrapper(y) if (y == x) => Wrapper(y), + Wrapper(y) => y + x, + } +} + +public enum MyEnum has drop { + Variant(u64, bool), + OtherVariant(bool, u64), +} + +fun test_or_pattern(x: u64): u64 { + match (x) { + MyEnum::Variant(1 | 2 | 3, true) | MyEnum::OtherVariant(true, 1 | 2 | 3) => 1, + MyEnum::Variant(8, true) | MyEnum::OtherVariant(_, 6 | 7) => 2, + _ => 3, + } +} + +fun test_lit(x: u64): u8 { + match (x) { + 1 => 2, + 2 => 3, + _ => 4, + } +} + +fun test_var(x: u64): u64 { + match (x) { + y => y, + } +} + +const MyConstant: u64 = 10; + +fun test_constant(x: u64): u64 { + match (x) { + MyConstant => 1, + _ => 2, + } +} + +fun test_or_pattern(x: u64): u64 { + match (x) { + 1 | 2 | 3 => 1, + 4 | 5 | 6 => 2, + _ => 3, + } +} + +// ERROR +fun test_or_at_pattern(x: u64): u64 { + match (x) { + x @ 1 | 2 | 3 => x + 1, + y @ 4 | 5 | 6 => y + 2, + z => z + 3, + } +} + +fun f(x: MyEnum) { + match (x) { + MyEnum::Variant(1, true) => 1, + MyEnum::OtherVariant(_, 3) => 2, + MyEnum::Variant(..) => 3, + MyEnum::OtherVariant(..) => 4, + } +} + +fun f(x: MyEnum) { + match (x) { + MyEnum::Variant(1 | 2 | 10, true) => 1, + MyEnum::OtherVariant(_, 3) => 2, + MyEnum::Variant(..) => 3, + MyEnum::OtherVariant(..) => 4, + } +} + +public struct NonDrop(u64) + +fun drop_nondrop(x: NonDrop) { + match (x) { + NonDrop(1) => 1, + _ => 2, + // ERROR: cannot wildcard match on a non-droppable value + } +} + +fun destructure_nondrop(x: NonDrop) { + match (x) { + NonDrop(1) => 1, + NonDrop(_) => 2, + // OK! + } +} + +fun use_nondrop(x: NonDrop): NonDrop { + match (x) { + NonDrop(1) => NonDrop(8), + x => x, + } +} + +public enum MyEnum { + Variant(u64, bool), + OtherVariant(bool, u64), +} + +public struct Pair(T, T) + +fun f(x: MyEnum): u8 { + match (x) { + MyEnum::Variant(1, true) => 1, + MyEnum::Variant(_, _) => 1, + MyEnum::OtherVariant(_, 3) => 2, + // Now exhaustive since this will match all values of MyEnum::OtherVariant + MyEnum::OtherVariant(..) => 2, + } +} + +fun match_pair_bool(x: Pair): u8 { + match (x) { + Pair(true, true) => 1, + Pair(true, false) => 1, + Pair(false, false) => 1, + // Now exhaustive since this will match all values of Pair + Pair(false, true) => 1, + } +} + +// ERROR +fun match_with_guard(x: u64): u64 { + match (x) { + 1 if (false) => 1, + 1 => 2, + _ => 3, + } +} + +public struct MyStruct(u64) + +fun mut_on_immut(x: &MyStruct): u64 { + match (x) { + MyStruct(mut y) => { + y = &(*y + 1); + *y + }, + } +} + +fun mut_on_value(x: MyStruct): u64 { + match (x) { + MyStruct(mut y) => { + *y = *y + 1; + *y + }, + } +} + +fun mut_on_mut(x: &mut MyStruct): u64 { + match (x) { + MyStruct(mut y) => { + *y = *y + 1; + *y + }, + } +} + +public struct MyStruct(u64, u64, u64, u64) has drop; + +public struct MyStruct2 { + x: u64, + y: u64, + z: u64, + w: u64, +} + +fun wild_match(x: MyStruct) { + match (x) { + MyStruct(.., 1) => 1, + // OK! The `..` pattern can be used at the beginning of the constructor pattern + MyStruct(1, ..) => 2, + // OK! The `..` pattern can be used at the end of the constructor pattern + MyStruct(1, .., 1) => 3, + // OK! The `..` pattern can be used at the middle of the constructor pattern + MyStruct(1, .., 1, 1) => 4, + MyStruct(..) => 5, + } +} + +fun wild_match2(x: MyStruct2) { + match (x) { + MyStruct2 { x: 1, .. } => 1, + MyStruct2 { x: 1, w: 2, .. } => 2, + MyStruct2 { .. } => 3, + } +} + +/// Convert a `u64` index to a `Colour`. +public fun from_index(index: u64): Colour { + match (index) { + 0 => Colour::Empty, + 1 => Colour::Black, // ERROR + 2 => Colour::White, // ERROR + _ => abort 0, + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.exp.move b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.exp.move new file mode 100644 index 00000000000..3c9af22616d --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.exp.move @@ -0,0 +1,55 @@ +module prettier::tree_sitter { + public(package) fun function() {} + + public(package) fun function() {} + + fun macro_fail() { + core::create_deleverage_ticket!( + | + mut a, + pool: &mut cetus_pool::Pool, + lp_position: &mut CetusPosition, + delta_l: u128, + | say::hello(), + ) + } + + fun from_index(index: u64): Colour { + match (index) { + 0 | 2 => Colour::Empty, + 1 => Colour::Black, + 2 => Colour::White, + _ => abort 0, + } + } + + fun clamm() { + // Empties the pool + state.d = + state.d - state.d * lp_coin_amount.to_u256() / total_supply.to_u256(); + + let (coin_a, coin_b, coin_c) = ( + withdraw_coin( + state, + lp_coin_amount, + min_amounts[0], + total_supply, + ctx, + ), + withdraw_coin( + state, + lp_coin_amount, + min_amounts[1], + total_supply, + ctx, + ), + withdraw_coin( + state, + lp_coin_amount, + min_amounts[2], + total_supply, + ctx, + ), + ); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.move b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.move new file mode 100644 index 00000000000..ab939fa942d --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/errors/tree-sitter.move @@ -0,0 +1,34 @@ +module prettier::tree_sitter { + public (package) fun function() {} + public(package) fun function() {} + + + fun macro_fail() { + core::create_deleverage_ticket!(| + mut a, + pool: &mut cetus_pool::Pool, + lp_position: &mut CetusPosition, + delta_l: u128| say::hello() + ) + } + + fun from_index(index: u64): Colour { + match (index) { + 0 | 2 => Colour::Empty, + 1 => Colour::Black, + 2 => Colour::White, + _ => abort 0, + } + } + + fun clamm() { + // Empties the pool + state.d = state.d - state.d * lp_coin_amount.to_u256() / total_supply.to_u256(); + + let (coin_a, coin_b, coin_c) = ( + withdraw_coin(state, lp_coin_amount, min_amounts[0], total_supply, ctx), + withdraw_coin(state, lp_coin_amount, min_amounts[1], total_supply, ctx), + withdraw_coin(state, lp_coin_amount, min_amounts[2], total_supply, ctx), + ); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/call_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/expression/call_expression.exp.move new file mode 100644 index 00000000000..1d63da15bd6 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/call_expression.exp.move @@ -0,0 +1,25 @@ +// options: +// printWidth: 40 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::index_expression; + +fun call_expression() { + call(/* a */ 10, /* b */ 10); + call( + /* a */ 10, + /* b */ 10, + /* c */ 10, + ); + call(/* a */ 10 /* trailing */); +} + +fun misc() { + some_really_cool_function_i_swear( + /* read */ true, + /* write */ true, + /* transfer */ false, + /* delete */ true, + ) +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/call_expression.move b/external-crates/move/tooling/prettier-move/tests/expression/call_expression.move new file mode 100644 index 00000000000..c9a13f0eabb --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/call_expression.move @@ -0,0 +1,17 @@ +// options: +// printWidth: 40 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::index_expression; + +fun call_expression() { + + call(/* a */ 10, /* b */ 10); + call(/* a */ 10, /* b */ 10, /* c */ 10); + call(/* a */ 10 /* trailing */); +} + +fun misc() { + some_really_cool_function_i_swear(/* read */ true, /* write */ true, /* transfer */ false, /* delete */ true) +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/dot_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/expression/dot_expression.exp.move new file mode 100644 index 00000000000..8dbef98407c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/dot_expression.exp.move @@ -0,0 +1,159 @@ +// options: +// printWidth: 35 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::dot_expression; + +fun dot_name() { + // should not break, fits the line + &board.elements.something.else; + + // should break, too long + &board + .elements + .something + .else + .and_then; + + // in assignment we want to try and keep + // the dot expression on the same line as + // the `=` sign + *some_identifier + .get_mut(a, b) + .next = next; + + // borrow expression without block does + // not provide grouping, we need to make + // sure it does not break + &verified_issuer.issuer +} + +fun dot_expression() { + board.place(1, 0); + board.score(vector[0, 1, 0]); + + board + .first() + .second() + .ultra_long_third(); + board + .start() + .then() + .then_else(); + + board + .score(vector[1, 0, 1]) + .score( + vector[0, 1, 0], + vector[0, 0, 1], + ) + .assert_score() + .assert_score(vector[ + 0, + 1, + 0, + ]); + + // a single dot expression should break if + // the rhs is too long; this scenario is yet + // to be implemented + board.very_long_expression_will_it_indent_or_not(); + + // with breakable lists, we should not break + // the chain, unless the chain itself breaks + board.add_element(Element { + id: object::new(ctx), + }); + + // same as above, but with an arguments list + board.add_fields( + field_one, + field_two, + field_three, + ); + + // should not break, fits the line + board.assert_state(vector[]); + + // TODO: come back to this example + // + // should not break, because vector inside + // is a breakable expression and knows how + // to break itself + board.assert_state(vector[ + vector[2, 0, 0, 0], + vector[1, 2, 0, 0], + vector[0, 1, 0, 0], + vector[1, 0, 0, 0], + ]); + + // trailing and leading comments do not + // break the chain + board.place(2, 0); // trail +} + +fun dot_comments() { + // element fits the line but breaks because + // of the comment in between the chain + dot + .some() // t + .else(); // t + + // breaks all chain, comment follows + dot.something().then().else(); // t_comment + + // fits the line, comment is attached + expr.function_call(); // trail + + // breaks correctly, keeps comments where + // they belong + expression + // lead + .function_call(100) // trail + // illustrates real-world scenario + // when code is commented out + // .function_call(); // trail + .function_call(); // trail + + // leading and trailing comments should be kept + // in place + expression + // lead + .div(50); // trailing +} + +fun dot_with_lambda_lists() { + // should not indent unless breaks + vector.length().do!(|el| { + el.destroy_empty(); + }); + + // should indent, breaks as expected + vector + .length() + .do_range!(num, |el| { + el.destroy_empty(); + }); + + // should break and indent correctly + option + .map!(|e| option::some(10)) + .destroy_or!({ + let _ = 1; + 1 + 2 + }); + + // should not break nor add extra indent + object.option.destroy_or!({ + let _ = 1; + 1 + 2 + }); + + // should not break nor add extra indent + // even with line comments inside the block + object.option.destroy_or!({ + // comment + 1 + 2 + }); +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/dot_expression.move b/external-crates/move/tooling/prettier-move/tests/expression/dot_expression.move new file mode 100644 index 00000000000..40122036020 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/dot_expression.move @@ -0,0 +1,135 @@ +// options: +// printWidth: 35 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::dot_expression; + +fun dot_name() { + // should not break, fits the line + &board.elements.something.else; + + // should break, too long + &board.elements.something.else.and_then; + + // in assignment we want to try and keep + // the dot expression on the same line as + // the `=` sign + *some_identifier.get_mut(a, b).next = next; + + // borrow expression without block does + // not provide grouping, we need to make + // sure it does not break + &verified_issuer.issuer +} + +fun dot_expression() { + board.place(1, 0); + board.score(vector[0, 1, 0]); + + board.first().second().ultra_long_third(); + board.start().then().then_else(); + + board + .score(vector[1, 0, 1]) + .score( + vector[0, 1, 0], + vector[0, 0, 1] + ) + .assert_score() + .assert_score(vector[ + 0, 1, 0 + ]); + + // a single dot expression should break if + // the rhs is too long; this scenario is yet + // to be implemented + board.very_long_expression_will_it_indent_or_not(); + + // with breakable lists, we should not break + // the chain, unless the chain itself breaks + board.add_element(Element { id: object::new(ctx) }); + + // same as above, but with an arguments list + board.add_fields(field_one, field_two, field_three); + + // should not break, fits the line + board.assert_state(vector[]); + + // TODO: come back to this example + // + // should not break, because vector inside + // is a breakable expression and knows how + // to break itself + board.assert_state(vector[ + vector[2, 0, 0, 0], + vector[1, 2, 0, 0], + vector[0, 1, 0, 0], + vector[1, 0, 0, 0], + ]); + + // trailing and leading comments do not + // break the chain + board.place(2, 0); // trail +} + +fun dot_comments() { + // element fits the line but breaks because + // of the comment in between the chain + dot.some() // t + .else(); // t + + // breaks all chain, comment follows + dot.something().then().else(); // t_comment + + // fits the line, comment is attached + expr.function_call(); // trail + + // breaks correctly, keeps comments where + // they belong + expression + // lead + .function_call(100) // trail + // illustrates real-world scenario + // when code is commented out + // .function_call(); // trail + .function_call(); // trail + + // leading and trailing comments should be kept + // in place + expression + // lead + .div(50); // trailing +} + + +fun dot_with_lambda_lists() { + // should not indent unless breaks + vector.length().do!(|el| { + el.destroy_empty(); + }); + + // should indent, breaks as expected + vector.length().do_range!(num, |el| { + el.destroy_empty(); + }); + + // should break and indent correctly + option.map!(|e| option::some(10)).destroy_or!({ + let _ = 1; + 1 + 2 + }); + + // should not break nor add extra indent + object.option.destroy_or!({ + let _ = 1; + 1 + 2 + }); + + // should not break nor add extra indent + // even with line comments inside the block + object.option.destroy_or!({ + // comment + 1 + 2 + }); +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/index_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/expression/index_expression.exp.move new file mode 100644 index 00000000000..f58d689b940 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/index_expression.exp.move @@ -0,0 +1,10 @@ +// options: +// printWidth: 35 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::index_expression; + +fun vector_simple() { + *&mut grid[x0, y0] = num; +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/index_expression.move b/external-crates/move/tooling/prettier-move/tests/expression/index_expression.move new file mode 100644 index 00000000000..f58d689b940 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/index_expression.move @@ -0,0 +1,10 @@ +// options: +// printWidth: 35 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::index_expression; + +fun vector_simple() { + *&mut grid[x0, y0] = num; +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.exp.move b/external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.exp.move new file mode 100644 index 00000000000..64b5e1df809 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.exp.move @@ -0,0 +1,272 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::macro_and_lambda; + +fun macro_call() { + // regular cases of macro calls and lambdas: + // - no arguments + // - few arguments + // - breaking / many arguments + stack.some!(); + stack.some!(alice, bob, carl, dave); + stack.some!( + alice, + bob, + carl, + dave, + smith, + ); + + // comment inside + stack.some!( + /* comment */ + ); + stack.some!( + // comment + ); + + // module access macro_call + vector::tabulate!(|i| i); + + // for chains, see `dot_expression` + vector + .length() + .min!(10000) + .do_range!(x, |_| {}); +} + +fun lambda() { + // lambda fits on one line + vector.length().do!(|x| print(&x)); + + // lambda without block does not break first + vector + .length() + .do!(|x| other_function(&x)); + + // call_args breaks + vector + .length() + .do!( + |argument| option(argument), + ); + + // once chain is broken, lambda + // breaks, inner expression breaks + vector + .length() + .do!( + |argument| option::some( + argument, + ), + ); + + // argument list can also break if + // this way it fits; breaks the parent + vector + .length() + .do!( + | + argument, + argument2, + | option::some(argument), + ); + + // single line blocks should be allowed + length.do!(|x| { let y = x; y }); + + // and get expanded when content is + // too long + length.do!(|x| { + let y = x; + y + x + }); + + // if lamda has a block argument, it + // does not require a newline + vector.length().do!(|x| { + // even this comment does not + // break the chain! + function_call(x + 100); // and neither does this one + + // locally broken calls should + // NOT break the chain + vector::tabulate!( + x, + |index| option::some(index), + ); + + // similarly, does not break + vector::tabulate!(x, |index| { + option::some(index) + }); + }); + + // if a block does not fit the line, + // parent group will get broken, and + // we expect correct indentation + vector + .length() + .min(100) + .max(200) + .do!(|x| { function_call(x) }); + + // same applies to multiple calls in + // a row + vector + .map!(|elem| option::some(elem)) + .map!(|elem| { + elem.destroy_some() + }) + .map!(|elem| { + option::some(elem) + }) + .destroy!(|_| {}); + + // trying different breaking cases + vector.length().do!(|elem| { + if (elem % 2 == 0) { + function_call(100) + } else { + function_call(200) + }; + + return + }); + + // conditional group should be broken + // by a non-breaking group (somehow) + // TODO: revisit this example + if (vector.find_index!(|el| { + el % 2 == 0 && el % 3 == 0 + }).is_some()) { + function_call(); + }; +} + +fun f() { + animation.do_ref!(|el| { + contents = + contents + .map!(|mut contents| { + contents.push_back(el.to_string()); + contents + }) + .or!( + vector[ + el.to_string(), + ], + ); + }); + + stack.other!(argument, |x| x.do!()); + stack.another!( + argument, + argument, + argument, + argument, + |x| { + x.do!(); + }, + ); + stack.another!( + argument, + argument, + argument, + |x| x.destroy!(|_| {}), + ); + stack.destroy!( + |e| get_group_int( + b, + e, + visited, + ), + ); + stack.destroy!(|e| { + get_group_int(b, e, visited); + get_group_int(b, e, visited); + get_group_int(b, e, visited); + }); + stack.destroy!(|e| { + get_group_int(b, e, visited); + }); + stack.destroy!(|x| {}); + stack.very_very_very_long!(|x| { + x.do!(); + }); + stack.very_very_very_long_macro_name_with_a_cherry!( + |x| { + x.do!(); + }, + ); + + stack.do!(|el| { + if (some) { + expressions_break; + }; + + if (el.is_some()) { + field::borrow_mut< + K, + Node, + >( + &mut table.id, + *el.borrow(), + ).next = next; + }; + }); + + if (el.is_some()) { + field::borrow_mut< + K, + Node, + >( + &mut table.id, + *el.borrow(), + ).next = next; + }; + + idx_sorted.find_index!(|idx| { + let (el, value) = set + .elems + .get_entry_by_idx( + *idx as u64, + ); + expected > *value + }); + + aha.idx_sorted.find_index!(|idx| { + let (el, value) = set + .elems + .get_entry_by_idx( + *idx as u64, + ); + expected > *value + }); + + aha.idx_sorted.find_index!(|idx| { + // line comment contains a hardline + let (el, value) = set + .elems + .get_entry_by_idx( + *idx as u64, + ); + expected > *value + }); + + let insert_idx = set + .idx_sorted + .find_index!(|idx| { + let (_elem, value) = set + .elements + .get_entry_by_idx( + *idx as u64, + ); + total_value > *value + }) + .destroy_or!( + set.idx_sorted.length(), + ); +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.move b/external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.move new file mode 100644 index 00000000000..e75420ae569 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/macro_call_and_lambda.move @@ -0,0 +1,224 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +module prettier::macro_and_lambda; + +fun macro_call() { + // regular cases of macro calls and lambdas: + // - no arguments + // - few arguments + // - breaking / many arguments + stack.some!(); + stack.some!(alice, bob, carl, dave); + stack.some!( + alice, + bob, + carl, + dave, + smith, + ); + + // comment inside + stack.some!(/* comment */); + stack.some!( + // comment + ); + + // module access macro_call + vector::tabulate!(|i| i); + + // for chains, see `dot_expression` + vector + .length() + .min!(10000) + .do_range!(x, |_| {}); +} + +fun lambda() { + // lambda fits on one line + vector.length().do!(|x| print(&x)); + + // lambda without block does not break first + vector + .length() + .do!(|x| other_function(&x)); + + // call_args breaks + vector + .length() + .do!( + |argument| option(argument) + ); + + // once chain is broken, lambda + // breaks, inner expression breaks + vector + .length() + .do!( + |argument| option::some( + argument + ) + ); + + // argument list can also break if + // this way it fits; breaks the parent + vector + .length() + .do!( + | + argument, + argument2 + | option::some(argument) + ); + + // single line blocks should be allowed + length.do!(|x| { let y = x; y }); + + // and get expanded when content is + // too long + length.do!(|x| { + let y = x; + y + x + }); + + // if lamda has a block argument, it + // does not require a newline + vector.length().do!(|x| { + // even this comment does not + // break the chain! + function_call(x + 100); // and neither does this one + + // locally broken calls should + // NOT break the chain + vector::tabulate!( + x, + |index| option::some(index), + ); + + // similarly, does not break + vector::tabulate!(x, |index| { + option::some(index) + }); + }); + + // if a block does not fit the line, + // parent group will get broken, and + // we expect correct indentation + vector + .length() + .min(100) + .max(200) + .do!(|x| { function_call(x) }); + + // same applies to multiple calls in + // a row + vector + .map!(|elem| option::some(elem)) + .map!(|elem| { + elem.destroy_some() + }) + .map!(|elem| { + option::some(elem) + }) + .destroy!(|_| {}); + + // trying different breaking cases + vector.length().do!(|elem| { + if (elem % 2 == 0) { + function_call(100) + } else { + function_call(200) + }; + + return + }); + + // conditional group should be broken + // by a non-breaking group (somehow) + // TODO: revisit this example + if ( + vector.find_index!(|el| { + el % 2 == 0 && el % 3 == 0 + }).is_some() + ) { + function_call(); + }; +} + +fun f() { + animation.do_ref!(|el| { + contents = contents + .map!(|mut contents| { + contents.push_back(el.to_string()); + contents + }) + .or!(vector[el.to_string()]); + }); + + stack.other!(argument, |x| x.do!()); + stack.another!(argument, argument, argument, argument, |x| { + x.do!(); + }); + stack.another!(argument, argument, argument, |x| x.destroy!(|_| {})); + stack.destroy!(|e| get_group_int(b, e, visited)); + stack.destroy!(|e| { + get_group_int(b, e, visited); + get_group_int(b, e, visited); + get_group_int(b, e, visited); + }); + stack.destroy!(|e| { + get_group_int(b, e, visited); + }); + stack.destroy!(|x| { + + }); + stack.very_very_very_long!(|x| { + x.do!(); + }); + stack.very_very_very_long_macro_name_with_a_cherry!(|x| { + x.do!(); + }); + + stack.do!(|el| { + if (some) { + expressions_break; + }; + + if (el.is_some()) { + field::borrow_mut>(&mut table.id, *el.borrow()).next = next; + }; + }); + + if (el.is_some()) { + field::borrow_mut>(&mut table.id, *el.borrow()).next = next; + }; + + idx_sorted.find_index!( + |idx| { + let (el, value) = set.elems.get_entry_by_idx(*idx as u64); + expected > *value + }, + ); + + + aha.idx_sorted.find_index!( + |idx| { + let (el, value) = set.elems.get_entry_by_idx(*idx as u64); + expected > *value + }, + ); + + aha.idx_sorted.find_index!( + |idx| { + // line comment contains a hardline + let (el, value) = set.elems.get_entry_by_idx(*idx as u64); + expected > *value + }, + ); + + let insert_idx = set.idx_sorted.find_index!(|idx| { + let (_elem, value) = set.elements.get_entry_by_idx(*idx as u64); + total_value > *value + }).destroy_or!(set.idx_sorted.length()); +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/match_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/expression/match_expression.exp.move new file mode 100644 index 00000000000..8608c23f424 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/match_expression.exp.move @@ -0,0 +1,132 @@ +// options: +// printWidth: 50 +// tabWidth: 4 +// useModuleLabel: true + +// TODO: circle back on this once `match` has better support in tree-sitter. +// TODO: I suggest we do not format match expressions for now. +module prettier::pattern_matching; + +fun f() { + // empty match + match (x) {}; + + // empty match with a comment inside + match (x) { + // comment + }; + + // match with a very long expression + // no comma (illegal) + match ( + very_long_expression_that_needs_to_be_wrapped + ) { + Enum => 1, + }; + + // match with a breakable expression + match ({ + let x = 0; + x + 100 + }) { + 100 => 100, + _ => 0, + }; + + // match with a single arm + match (x) { + Enum => 1, + }; + + // match with multiple arms + match (x) { + Enum => 1, + Enum2 => 2, + }; + + // match with multiple arms and a + // default arm + match (x) { + Enum => 1, + Enum2 => 2, + _ => 3, + }; + + // match with arm guards and complex + // patterns + match (x) { + 1 | 2 | 3 => 1, + Enum if (x == 1) => 1, + 1 if (false) => 1, + Wrapper(y) if (y == x) => Wrapper(y), + x @ 1 | 2 | 3 => x + 1, + z => z + 3, + _ => 3, + }; +} + +fun match_pair_bool(x: Pair): u8 { + match (x) { + Pair(true, true) => 1, + Pair(true, false) => 1, + Pair(false, false) => 1, + Pair(false, true) => 1, + } +} + +fun incr(x: &mut u64) { + *x = *x + 1; +} + +fun match_with_guard_incr(x: u64): u64 { + match (x) { + x if ({ incr(&mut x); x == 1 }) => 1, + // ERROR: ^^^ invalid borrow of immutable value + _ => 2, + } +} + +fun match_with_guard_incr2(x: &mut u64): u64 { + match (x) { + x if ({ incr(&mut x); x == 1 }) => 1, + // ERROR: ^^^ invalid borrow of immutable value + _ => 2, + } +} + +// +fun use_enum() { + let _local = tests::enum::test::A(10, 1000); +} + +fun match_arms() { + match (self.beep) { + A::B(c) => { + let c = + c + (elements.length() as u16); + if (is_hey(c, self.hey)) { + self.beep = + A::C(clock.timestamp_ms()); + } else { + self.beep = A::D(c); + } + }, + _ => {}, + }; + + params.do!(|param| { + match (self.beep) { + A::B(c) => { + let c = + c + (elements.length() as u16); + if (is_hey(c, self.hey)) { + self.beep = + A::C(clock.timestamp_ms()); + } else { + self.beep = A::D(c); + } + }, + _ => {}, + } + }) +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/match_expression.move b/external-crates/move/tooling/prettier-move/tests/expression/match_expression.move new file mode 100644 index 00000000000..638c56e52c1 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/match_expression.move @@ -0,0 +1,130 @@ +// options: +// printWidth: 50 +// tabWidth: 4 +// useModuleLabel: true + +// TODO: circle back on this once `match` has better support in tree-sitter. +// TODO: I suggest we do not format match expressions for now. +module prettier::pattern_matching; + +fun f() { + // empty match + match (x) {}; + + // empty match with a comment inside + match (x) { + // comment + }; + + // match with a very long expression + // no comma (illegal) + match ( + very_long_expression_that_needs_to_be_wrapped + ) { + Enum => 1, + }; + + // match with a breakable expression + match ({ + let x = 0; + x + 100 + }) { + 100 => 100, + _ => 0, + }; + + // match with a single arm + match (x) { + Enum => 1, + }; + + // match with multiple arms + match (x) { + Enum => 1, + Enum2 => 2, + }; + + // match with multiple arms and a + // default arm + match (x) { + Enum => 1, + Enum2 => 2, + _ => 3, + }; + + // match with arm guards and complex + // patterns + match (x) { + 1 | 2 | 3 => 1, + Enum if (x == 1) => 1, + 1 if (false) => 1, + Wrapper(y) if (y == x) => Wrapper(y), + x @ (1 | 2 | 3) => x + 1, + z => z + 3, + _ => 3, + }; +} + +fun match_pair_bool(x: Pair): u8 { + match (x) { + Pair(true, true) => 1, + Pair(true, false) => 1, + Pair(false, false) => 1, + Pair(false, true) => 1, + } +} + +fun incr(x: &mut u64) { + *x = *x + 1; +} + +fun match_with_guard_incr(x: u64): u64 { + match (x) { + x if ({ incr(&mut x); x == 1 }) => 1, + // ERROR: ^^^ invalid borrow of immutable value + _ => 2, + } +} + +fun match_with_guard_incr2(x: &mut u64): u64 { + match (x) { + x if ({ incr(&mut x); x == 1 }) => 1, + // ERROR: ^^^ invalid borrow of immutable value + _ => 2, + } +} + + + +// +fun use_enum() { + let _local = tests::enum::test::A(10, 1000); +} + +fun match_arms() { + match (self.beep) { + A::B(c) => { + let c = c + (elements.length() as u16); + if (is_hey(c, self.hey)) { + self.beep = A::C(clock.timestamp_ms()); + } else { + self.beep = A::D(c); + } + }, + _ => {}, + }; + + params.do!(|param| { + match (self.beep) { + A::B(c) => { + let c = c + (elements.length() as u16); + if (is_hey(c, self.hey)) { + self.beep = A::C(clock.timestamp_ms()); + } else { + self.beep = A::D(c); + } + }, + _ => {}, + } + }) +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/vector_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/expression/vector_expression.exp.move new file mode 100644 index 00000000000..fd9723ff605 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/vector_expression.exp.move @@ -0,0 +1,149 @@ +// options: +// printWidth: 35 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::dot_expression; + +fun vector_simple() { + // should be printed as is + vector[]; + + // should fit on one line + vector[alice, bob, carl, dave]; + + // should be expanded to multiple lines + vector[ + alice, + bob, + carl, + dave, + eve, + ]; +} + +// we have 3 list types: vector, block, and +// expression list +fun vector_lists() { + // fits one line + vector[vector[], vector[]]; + + // expanded to multiple lines + vector[ + vector[], + vector[], + vector[], + ]; + + // expanded, with each vector on a new line + vector[ + vector[1, 2, 3, 4, 5], + vector[1, 2, 3, 4, 5], + ]; + + // any vector breaking in a list breaks the list + // but not its elements + vector[ + vector[alice, bob, carl], + vector[alice, bob, carl], + vector[ + alice, + bob, + carl, + dave, + eve, + ], + ]; + + // block in a vector behaves like any other list + // if it can be single-lined, it will, or break + vector[{ 1 }, { 2 }, { 3 }]; + vector[ + { alice + bob + carl }, + { 2 }, + { 3 }, + ]; + + // when block broken, it gets expanded and + // indented like any other list + vector[ + { + let x = 1; + let y = 2; + x + y + }, + ]; + + vector[ + ( + alice + bob + carl + dave + smith, + ), + ]; + + // expression list in a vector should always break + vector[ + (alice + bob + carl), + (bob), + (carl), + ]; + + // any single list in a vector +} + +fun vector_formatting() { + // leading comment + vector[]; // trailing comment + + // line comment breaks the list + // TODO: + vector[ + alice, // alice + // bob, + carl, // that dude + // trailing comment kept + // another comment + // and one more + ]; + + // leading comment + vector[ + /* alice */ 1, + /* bob */ 2, + /* carl */ 3, + ]; // trailing comment + + vector[ + // hey there + alice, + bob, + carl, + ]; +} + +fun vector_type_args() { + // vector with type arguments, should not break + vector[alice, bob]; + + // elements break, but type arguments don't + vector[ + alice, + bob, + carl, + eve, + dave, + ]; + + // should try and break on elements, until + // it can't anymore + vector>[ + alice, + ]; + + // should break on type arguments if breaking + // elements is not enough to fit on one line + vector>[alice]; +} diff --git a/external-crates/move/tooling/prettier-move/tests/expression/vector_expression.move b/external-crates/move/tooling/prettier-move/tests/expression/vector_expression.move new file mode 100644 index 00000000000..376aa199ffd --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/expression/vector_expression.move @@ -0,0 +1,142 @@ +// options: +// printWidth: 35 +// tabWidth: 4 +// useModuleLabel: true + +module prettier::dot_expression; + +fun vector_simple() { + // should be printed as is + vector[]; + + // should fit on one line + vector[alice, bob, carl, dave]; + + // should be expanded to multiple lines + vector[ + alice, + bob, + carl, + dave, + eve + ]; +} + +// we have 3 list types: vector, block, and +// expression list +fun vector_lists() { + // fits one line + vector[vector[], vector[]]; + + // expanded to multiple lines + vector[ + vector[], + vector[], + vector[], + ]; + + // expanded, with each vector on a new line + vector[ + vector[1, 2, 3, 4, 5], + vector[1, 2, 3, 4, 5] + ]; + + // any vector breaking in a list breaks the list + // but not its elements + vector[ + vector[alice, bob, carl], + vector[alice, bob, carl], + vector[ + alice, + bob, + carl, + dave, + eve, + ], + ]; + + // block in a vector behaves like any other list + // if it can be single-lined, it will, or break + vector[{ 1 }, { 2 }, { 3 }]; + vector[ + { alice + bob + carl }, + { 2 }, + { 3 } + ]; + + // when block broken, it gets expanded and + // indented like any other list + vector[ + { + let x = 1; + let y = 2; + x + y + }, + ]; + + vector[ + ( + alice + bob + carl + dave + smith + ) + ]; + + // expression list in a vector should always break + vector[ + (alice + bob + carl), + (bob), + (carl), + ]; + + // any single list in a vector +} + +fun vector_formatting() { + // leading comment + vector[]; // trailing comment + + // line comment breaks the list + // TODO: + vector[ + alice, // alice + // bob, + carl, // that dude + // trailing comment kept + // another comment + // and one more + ]; + + // leading comment + vector[/* alice */ 1, /* bob */ 2, /* carl */ 3]; // trailing comment + + vector[ // hey there + alice, bob, carl + ]; +} + +fun vector_type_args() { + // vector with type arguments, should not break + vector[alice, bob]; + + // elements break, but type arguments don't + vector[ + alice, + bob, + carl, + eve, + dave, + ]; + + // should try and break on elements, until + // it can't anymore + vector>[ + alice + ]; + + // should break on type arguments if breaking + // elements is not enough to fit on one line + vector>[alice]; +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/binary_expression.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/binary_expression.exp.move new file mode 100644 index 00000000000..cd36660e32b --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/binary_expression.exp.move @@ -0,0 +1,51 @@ +// options: +// printWidth: 40 + +module prettier::binary_expression { + fun main() { + alice == bob && bob == carol && (dave > eve && eve > frank) && grace <= heidi && heidi <= ian && jack >= kate && kate >= larry && mary == nancy && nancy == olivia && peter != quincy && quincy != robert; + + a + 10 / (100 as u64) * (b - c) % d; + + let slivers_size = + ( + source_symbols_primary(n_shards) as u64 + (source_symbols_secondary(n_shards) as u64), + ) * (symbol_size(unencoded_length, n_shards) as u64); + + if ( + bytes == &b"bool" || + bytes == &b"u8" || + bytes == &b"u16" || + bytes == &b"u32" || + bytes == &b"u64" || + bytes == &b"u128" || + bytes == &b"u256" || + bytes == &b"address" || + (bytes.length() >= 6 && + bytes[0] == ASCII_V && + bytes[1] == ASCII_E && + bytes[2] == ASCII_C && + bytes[3] == ASCII_T && + bytes[4] == ASCII_O && + bytes[5] == ASCII_R) + ) {}; + + return a < b && b < c && (d > e && e > f) && g <= h && h <= i && j >= k && k >= l && m == n && n == o && p != q && q != r; + + bytes == &b"bool" || + bytes == &b"u8" || + bytes == &b"u16" || + bytes == &b"u32" || + bytes == &b"u64" || + bytes == &b"u128" || + bytes == &b"u256" || + bytes == &b"address" || + (bytes.length() >= 6 && + bytes[0] == ASCII_V && + bytes[1] == ASCII_E && + bytes[2] == ASCII_C && + bytes[3] == ASCII_T && + bytes[4] == ASCII_O && + bytes[5] == ASCII_R) + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/binary_expression.move b/external-crates/move/tooling/prettier-move/tests/functions/binary_expression.move new file mode 100644 index 00000000000..f882a2eee3f --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/binary_expression.move @@ -0,0 +1,52 @@ +// options: +// printWidth: 40 + +module prettier::binary_expression { + fun main() { + alice == bob && bob == carol && (dave > eve && eve > frank) && grace <= heidi && heidi <= ian && jack >= kate && kate >= larry && mary == nancy && nancy == olivia && peter != quincy && quincy != robert; + + a + 10 / (100 as u64) * (b - c) % d; + + let slivers_size = ( + source_symbols_primary(n_shards) as u64 + (source_symbols_secondary(n_shards) as u64), + ) * (symbol_size(unencoded_length, n_shards) as u64); + + + if ( + bytes == &b"bool" || + bytes == &b"u8" || + bytes == &b"u16" || + bytes == &b"u32" || + bytes == &b"u64" || + bytes == &b"u128" || + bytes == &b"u256" || + bytes == &b"address" || + (bytes.length() >= 6 && + bytes[0] == ASCII_V && + bytes[1] == ASCII_E && + bytes[2] == ASCII_C && + bytes[3] == ASCII_T && + bytes[4] == ASCII_O && + bytes[5] == ASCII_R)) { + // do something + }; + + return a < b && b < c && (d > e && e > f) && g <= h && h <= i && j >= k && k >= l && m == n && n == o && p != q && q != r; + + bytes == &b"bool" || + bytes == &b"u8" || + bytes == &b"u16" || + bytes == &b"u32" || + bytes == &b"u64" || + bytes == &b"u128" || + bytes == &b"u256" || + bytes == &b"address" || + (bytes.length() >= 6 && + bytes[0] == ASCII_V && + bytes[1] == ASCII_E && + bytes[2] == ASCII_C && + bytes[3] == ASCII_T && + bytes[4] == ASCII_O && + bytes[5] == ASCII_R) + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.exp.move new file mode 100644 index 00000000000..b406d0d2b39 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.exp.move @@ -0,0 +1,26 @@ +// options: +// printWidth: 40 + +/// Module: kek +module kek::kek { + public struct Kek { + a: u8, + b: u64, + } + + public fun destroy( + k1: Kek, + k2: Kek, + ) { + let Kek { a, .. } = k1; + let Kek { .. } = k2; + + let Slice { + mut kek, + prev: lprev, + next: lnext, + keys: mut lkeys, + vals: mut lvals, + } = left; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.move b/external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.move new file mode 100644 index 00000000000..285dce6a081 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/bind_unpack.move @@ -0,0 +1,23 @@ +// options: +// printWidth: 40 + +/// Module: kek +module kek::kek { + public struct Kek { + a: u8, + b: u64, + } + + public fun destroy(k1: Kek, k2: Kek) { + let Kek { a, .. } = k1; + let Kek { .. } = k2; + + let Slice { + mut kek, + prev: lprev, + next: lnext, + keys: mut lkeys, + vals: mut lvals, + } = left; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/block_item.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/block_item.exp.move new file mode 100644 index 00000000000..179ea0e0ac0 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/block_item.exp.move @@ -0,0 +1,5 @@ +module prettier::block_item { + fun block_item() { + any_expression_really(); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/block_item.move b/external-crates/move/tooling/prettier-move/tests/functions/block_item.move new file mode 100644 index 00000000000..179ea0e0ac0 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/block_item.move @@ -0,0 +1,5 @@ +module prettier::block_item { + fun block_item() { + any_expression_really(); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/expression.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/expression.exp.move new file mode 100644 index 00000000000..7857601e346 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/expression.exp.move @@ -0,0 +1,387 @@ +// options: +// printWidth: 40 + +module prettier::expression { + fun assign_expression() { + a = 1; + *a = 10; + *&a = 100; + a = (copy b); + b = (move c); + + *df::borrow_mut() = + another_call(); + (a, b) = (1, 2); + + strategy.underlying_nominal_value_usdc = + strategy.underlying_nominal_value_usdc - to_withdraw; + } + + fun identified_expression() { + 'a: { + call_something() + }; + } + + fun name_expression() { + name::expression; + expression; + } + + fun call_expression() { + call(); + call(1, 2, 3, 4, 5); + call(Struct {}, Struct {}); + call(Struct { + a: 1, + b: 2, + c: 3, + }); + call( + Struct { a: 1 }, + Struct { a: 1 }, + ); + call( + nested_call( + deeply_nested_call(), + ), + haha(), + ); + call( + nested_call(LongStruct { + a: 1, + }), + ); + } + + fun call_expression_type_arguments() { + call(); + call< + InnerTypeArguments, + InnerTypeArguments, + >(); + + module::another_call( + module::another_call(), + module::another_call(), + module::another_call(), + ); + + module::another_call< + TypeArgument, + >( + module::another_call(), + module::another_call(), + module::another_call(), + ); + } + + fun binary_expression() { + lhs != rhs; + lhs == rhs; + lhs || rhs; + lhs && rhs; + lhs < rhs; + lhs <= rhs; + lhs > rhs; + lhs >= rhs; + lhs << rhs; + lhs >> rhs; + lhs + rhs; + lhs - rhs; + lhs * rhs; + lhs / rhs; + lhs % rhs; + lhs & rhs; + lhs | rhs; + lhs ^ rhs; + } + + fun binary_expression_folding() { + // binary_expression + say_something_really_long && say_something_really_long || say_something_really_long; + + say_something_really_long && say_something_really_long || + say_something_really_long; + + say_something_really_long && // trailing comment + say_something_really_long || + // leading comment + say_something_really_long; + + say_something_really_long + say_something_really_long + say_something_really_long && + say_something_really_long + say_something_really_long + say_something_really_long; + + say_something_really_long > less_than_or_equal_to && + say_something_really_long < greater_than_or_equal_to; + + (say_something_really_long + say_something_really_long + say_something_really_long) && + (say_something_really_long + say_something_really_long + say_something_really_long); + + ( + say_something + say_something + say_something + say_something + say_something, + ); + } + + fun break_expression() { + break; + break 'a; + + 'very_long_label: { + break 'very_long_label; + } + } + + fun continue_expression() { + continue; + continue 'a; + + 'very_long_label: { + continue 'very_long_label; + } + } + + fun pack_expression() { + Positional(); + Positional( + 1000, + vector[10, 20, 30], + ); + PackMe {}; + PackReallyShort {}; + PackWithF { field: 10 }; + PackMyStruct { + id: object::new(ctx), + name: b"hello".to_string(), + }; + PackMyStruct< + WithTypeParameters, + > { + id: object::new(ctx), + name: b"hello".to_string(), + }; + PackMyStruct { + id: object::new(ctx), + name: AnotherStruct { + params: vector[ + b"world".to_string(), + ], + }, + }; + PackMyStruct { + id: object::new(ctx), + point: P(10, 20), + name: AnotherStruct { + params: vector[ + b"world".to_string(), + ], + haha: Another { + id: object::new( + ctx, + ), + param1: vector[ + b"world".to_string(), + b"world".to_string(), + b"world".to_string(), + b"world".to_string(), + ], + param2: vector[ + Packy { + x: 100000, + y: 500000, + }, + Packy { + x: 100, + y: 200, + }, + ], + param3: Positional( + b"very-very-very-long-argument-1", + b"very-very-very-long-argument-2", + b"very-very-very-long-argument-3", + ), + }, + }, + }; + } + + fun vector_expression() { + vector[10, 20, 30, 40]; + vector[ + b"say_something_familiar", + b"to_me", + ]; + vector[vector[10], vector[20]]; + vector[ + vector[10], + vector[20], + vector[30], + ]; + vector[S, T]; + vector>[MyStructT]; + } + + fun unit_expression() { + (); + } + + fun index_expression() { + say[0]; + double_index[variable][another][ + third_one, + ]; + who_you_gonna_call[ + (first_arg, second_arg), + ]; + result.push_back(copy data[i]); + } + + fun expression_list() { + (expr1, expr2, expr3); + (expr1, expr2, expr3); + ( + expr1, + expr2, + expr3, + expr4, + expr5, + ); + ( + expr1, + expr2, + expr3, + expr4, + expr5, + expr6, + expr7, + expr8, + expr9, + expr10, + ); + ( + expr1, + (expr2, expr3, expr4), + expr5, + ); + ( + expr1, + ( + expr2, + expr3, + expr4, + expr5, + ), + expr6, + expr7, + expr8, + expr9, + expr10, + ); + + let request = pool.finish_swap( + request, + ); + + ( + request, + swap_impl< + CoinIn, + CoinOut, + LpCoin, + >( + pool, + clock, + coin_in, + min_amount, + ctx, + ), + ) + } + + fun annotate_expression() { + (expr: Type); + ( + really_long_expression: ReallyLongType + ).say_something(); + let a = + (call_expression(): Type); + let a: Type = call_expression(); + } + + fun cast_expression() { + 100 as u64; + 1000 as u8; + (say_something as u256); + } + + fun dot_expression() { + a().b().c(); + first() + .second() + .ultra_long_third(); + start_a_chain() + .then_call_something() + .then_call_something_else(); + + let a = first() + .second() + .ultra_long_third(); + let a = first() + .second() + .ultra_long_third(); + } + + fun block() { + {}; + { + say_something(); + }; + { + should_this_be_so_long_or_not(); + }; + { + say_something(); + say_something_else(); + }; + ( + first().second(), + first() + .second() + .third() + .fourth(), + ); + { + { + say_something(); + }; + say_something_else(); + say_something_more(); + {}; + }; + } + + fun macro_module_access() { + assert!( + module::call_something(), + ); + assert!( + module::call_something(), + EDoesntQuiteWork, + ); + say_hello::to_the_world!(); + } + + fun match_expression() { + match (x) { + NewEnum::V() => 0, + NewEnum::V1(a, b) => {}, + NewEnum::V2 { x, y } => x, + NewEnum::V3 => 0, + } + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/expression.move b/external-crates/move/tooling/prettier-move/tests/functions/expression.move new file mode 100644 index 00000000000..509eb034503 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/expression.move @@ -0,0 +1,236 @@ +// options: +// printWidth: 40 + +module prettier::expression { + fun assign_expression() { + a = 1; + *a = 10; + *&a = 100; + a = (copy b); + b = (move c); + + *df::borrow_mut() = another_call(); + (a, b) = (1, 2); + + strategy.underlying_nominal_value_usdc = strategy.underlying_nominal_value_usdc - to_withdraw; + } + + fun identified_expression() { + 'a: { call_something() }; + } + + fun name_expression() { + name::expression; + expression; + } + + fun call_expression() { + call(); + call(1, 2, 3, 4, 5); + call(Struct {}, Struct {}); + call(Struct { a: 1, b: 2, c: 3 }); + call(Struct { a: 1 }, Struct { a: 1 }); + call( + nested_call(deeply_nested_call()), + haha(), + ); + call(nested_call(LongStruct { a: 1 })); + } + + fun call_expression_type_arguments() { + call(); + call(); + + module::another_call( + module::another_call(), + module::another_call(), + module::another_call(), + ); + + module::another_call( + module::another_call(), + module::another_call(), + module::another_call(), + ); + } + + fun binary_expression() { + lhs != rhs; + lhs == rhs; + lhs || rhs; + lhs && rhs; + lhs < rhs; + lhs <= rhs; + lhs > rhs; + lhs >= rhs; + lhs << rhs; + lhs >> rhs; + lhs + rhs; + lhs - rhs; + lhs * rhs; + lhs / rhs; + lhs % rhs; + lhs & rhs; + lhs | rhs; + lhs ^ rhs; + } + + fun binary_expression_folding() { + // binary_expression + say_something_really_long && say_something_really_long || say_something_really_long; + + say_something_really_long && say_something_really_long || + say_something_really_long; + + say_something_really_long && // trailing comment + say_something_really_long || + // leading comment + say_something_really_long; + + say_something_really_long + say_something_really_long + say_something_really_long && + say_something_really_long + say_something_really_long + say_something_really_long; + + say_something_really_long > less_than_or_equal_to && + say_something_really_long < greater_than_or_equal_to; + + (say_something_really_long + say_something_really_long + say_something_really_long) && + (say_something_really_long + say_something_really_long + say_something_really_long); + + (say_something + say_something + say_something + say_something + say_something); + } + + fun break_expression() { + break; + break 'a; + + 'very_long_label: { break 'very_long_label; } + } + + fun continue_expression() { + continue; + continue 'a; + + 'very_long_label: { continue 'very_long_label; } + } + + fun pack_expression() { + Positional(); + Positional(1000, vector[10, 20, 30]); + PackMe {}; + PackReallyShort {}; + PackWithF { field: 10 }; + PackMyStruct { id: object::new(ctx), name: b"hello".to_string() }; + PackMyStruct { id: object::new(ctx), name: b"hello".to_string() }; + PackMyStruct { + id: object::new(ctx), + name: AnotherStruct { params: vector[b"world".to_string()] }, + }; + PackMyStruct { + id: object::new(ctx), + point: P(10, 20), + name: AnotherStruct { + params: vector[b"world".to_string()], + haha: Another { + id: object::new(ctx), + param1: vector[b"world".to_string(), b"world".to_string(), b"world".to_string(), b"world".to_string()], + param2: vector[Packy { x: 100000, y: 500000 }, Packy { x: 100, y: 200 }], + param3: Positional(b"very-very-very-long-argument-1", b"very-very-very-long-argument-2", b"very-very-very-long-argument-3") + } }, + }; + } + + fun vector_expression() { + vector[10, 20, 30, 40]; + vector[b"say_something_familiar", b"to_me"]; + vector[vector[10], vector[20]]; + vector[vector[10], vector[20], vector[30]]; + vector[S, T]; + vector>[MyStructT]; + } + + fun unit_expression() { + (); + } + + fun index_expression() { + say[0]; + double_index[variable][another][third_one]; + who_you_gonna_call[(first_arg, second_arg)]; + result.push_back(copy data[i]); + } + + fun expression_list() { + (expr1, expr2, expr3); + (expr1, expr2, expr3); + (expr1, expr2, expr3, expr4, expr5); + (expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9, expr10); + (expr1, (expr2, expr3, expr4), expr5); + (expr1, (expr2, expr3, expr4, expr5), expr6, expr7, expr8, expr9, expr10); + + let request = pool.finish_swap(request); + + ( + request, + swap_impl(pool, clock, coin_in, min_amount, ctx) + ) + } + + fun annotate_expression() { + (expr: Type); + (really_long_expression: ReallyLongType).say_something(); + let a = (call_expression(): Type); + let a: Type = call_expression(); + } + + fun cast_expression() { + 100 as u64; + 1000 as u8; + (say_something as u256); + } + + fun dot_expression() { + a().b().c(); + first().second().ultra_long_third(); + start_a_chain().then_call_something().then_call_something_else(); + + let a = first().second().ultra_long_third(); + let a = first().second().ultra_long_third(); + } + + fun block() { + {}; + { say_something(); }; + { should_this_be_so_long_or_not(); }; + { + say_something(); + say_something_else(); + }; + ( + first().second(), + first().second().third().fourth(), + ); + { + { + say_something(); + }; + say_something_else(); + say_something_more(); + {}; + }; + } + + fun macro_module_access() { + assert!(module::call_something()); + assert!(module::call_something(), EDoesntQuiteWork); + say_hello::to_the_world!(); + } + + fun match_expression() { + match (x) { + NewEnum::V() => 0, + NewEnum::V1(a, b) => {}, + NewEnum::V2 { x, y } => x, + NewEnum::V3 => 0, + } + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/let_statement.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/let_statement.exp.move new file mode 100644 index 00000000000..191a3a16177 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/let_statement.exp.move @@ -0,0 +1,148 @@ +// options: +// printWidth: 60 + +// Testing strategy for let statement: +// +// - bind list / expression list matches, mutability +// - test breakable expressions like expression_list +// - test let assignment with control flow like if, while, loop +// - test let with very long unbreakable expressions +// - test let with long breakable expressions +// - write every example how it should be formatted +module prettier::let_statement { + fun basic() { + let _; + let mut c; + let a = 1; + let x: u64; + let (a, b) = (1, 2); + let c: vector = vector[1, 2, 3]; + let (mut a, mut b) = (1, 2); + let ( + mut something, + something_else, + mut another_thing, + ) = (1, 2, 3); + } + + fun breakable_expressions() { + let something = vector[ + very_long_element_of_the_vector, + ]; + + let (item1, item2) = ( + // breaks here + very_long_expression, + very_long_expression, + ); + + let item = Struct { + that: vector[], + packs: 1000, + itself: false, + }; + + let item = chain + .that_does() + .truly_magically() + .breaks_itself(); + + let item = { + block; + will_be; + block + }; + + let item = macro_call!( + very_long_list_expression_1, + very_long_list_expression_2, + ); + } + + fun unbreakable_expressions() { + let something = + very_long_expression_that_does_not_break_itself; + let Kiosk { id, profits, owner: _, item_count } = + self; + } + + fun break_list() { + let block = { + let a = 1; + let b = 2; + let c = 3; + a + b + c + }; + + let v = vector[ + vector[1, 2, 3], + vector[4, 5, 6], + vector[7, 8, 9], + ]; + + let (a, mut b, c) = ( + very_long_list_expression_1, + very_long_list_expression_2, + very_long_list_expression_3, + ); + } + + fun break_long_value() { + let (a, b, c) = ( + very_very_very_long_value, + very_very_very_long_value, + very_very_very_long_value, + ); + + let z = first().final().second_arg(); + + let ( + very_long_binding, + very_long_binding1, + very_long_binding2, + ) = (1, 2, 3); + + let ( + very_long_binding, + mut very_long_binding1, + very_long_binding2, + ) = ( + very_very_very_long_value, + very_very_very_long_value, + very_very_very_long_value, + ); + + let a = + very_very_very_long_value_very_long_value_very_long_value; + + let c: TypeName>>> = + very_very_very_long_value_very_long_value_very_long_value; + + let to_remain_locked = ( + self.final_unlock_ts_sec - + math::min(self.final_unlock_ts_sec, now), + ); + + let to_remain_locked = + ( + self.final_unlock_ts_sec - math::min(self.final_unlock_ts_sec, now) + ) * self.unlock_per_second; + + let locked_amount_round = + balance::value(&self.locked_balance) / self.unlock_per_second * self.unlock_per_second; + } + + fun misc() { + let a = + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition; + } + + fun let_match() { + let mut stone = match (e.is_black()) { + true => shape::use_(b"#b".to_string()), + false => shape::use_(b"#w".to_string()), + }; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/let_statement.move b/external-crates/move/tooling/prettier-move/tests/functions/let_statement.move new file mode 100644 index 00000000000..d35596fe9c3 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/let_statement.move @@ -0,0 +1,134 @@ +// options: +// printWidth: 60 + +// Testing strategy for let statement: +// +// - bind list / expression list matches, mutability +// - test breakable expressions like expression_list +// - test let assignment with control flow like if, while, loop +// - test let with very long unbreakable expressions +// - test let with long breakable expressions +// - write every example how it should be formatted +module prettier::let_statement { + fun basic() { + let _; + let mut c; + let a = 1; + let x: u64; + let (a, b) = (1, 2); + let c: vector = vector[1, 2, 3]; + let (mut a, mut b) = (1, 2); + let ( + mut something, + something_else, + mut another_thing, + ) = (1, 2, 3); + } + + fun breakable_expressions() { + let something = vector[ + very_long_element_of_the_vector, + ]; + + let (item1, item2) = ( // breaks here + very_long_expression, + very_long_expression, + ); + + let item = Struct { + that: vector[], + packs: 1000, + itself: false + }; + + let item = chain + .that_does() + .truly_magically() + .breaks_itself(); + + let item = { + block; + will_be; + block + }; + + let item = macro_call!( + very_long_list_expression_1, + very_long_list_expression_2, + ); + } + + fun unbreakable_expressions() { + let something = very_long_expression_that_does_not_break_itself; + let Kiosk { id, profits, owner: _, item_count } = self; + } + + fun break_list() { + let block = { + let a = 1; + let b = 2; + let c = 3; + a + b + c + }; + + let v = vector[ + vector[1, 2, 3], + vector[4, 5, 6], + vector[7, 8, 9], + ]; + + let (a, mut b, c) = ( + very_long_list_expression_1, + very_long_list_expression_2, + very_long_list_expression_3 + ); + } + + fun break_long_value() { + let (a, b, c) = ( + very_very_very_long_value, + very_very_very_long_value, + very_very_very_long_value + ); + + let z = first().final().second_arg(); + + let (very_long_binding, very_long_binding1, very_long_binding2) = (1, 2, 3); + + let (very_long_binding, mut very_long_binding1, very_long_binding2) = ( + very_very_very_long_value, + very_very_very_long_value, + very_very_very_long_value + ); + + let a = very_very_very_long_value_very_long_value_very_long_value; + + let c: TypeName>>> = very_very_very_long_value_very_long_value_very_long_value; + + let to_remain_locked = + ( + self.final_unlock_ts_sec - + math::min(self.final_unlock_ts_sec, now), + ); + + let to_remain_locked = ( + self.final_unlock_ts_sec - math::min(self.final_unlock_ts_sec, now) + ) * self.unlock_per_second; + + let locked_amount_round = + balance::value(&self.locked_balance) / self.unlock_per_second * self.unlock_per_second; + } + + fun misc() { + let a = very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition && + very_very_long_if_condition > very_very_long_if_condition; + } + + fun let_match() { + let mut stone = match (e.is_black()) { + true => shape::use_(b"#b".to_string()), + false => shape::use_(b"#w".to_string()), + }; + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/simple.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/simple.exp.move new file mode 100644 index 00000000000..6680b47b6f8 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/simple.exp.move @@ -0,0 +1,33 @@ +module prettier::simple_function { + fun say_hello() {} + + /// This is a simple function + fun simple_function(): u64 { + say_hello(); + 100 + } + + fun breakable_parameters( + first_breakable_parameter: u64, + second_breakable_parameter: u64, + third_breakable_parameter: u64, + fourth_breakable_parameter: u64, + fifth_breakable_parameter: u64, + ): u64 { + first_breakable_parameter + + second_breakable_parameter + + third_breakable_parameter + + fourth_breakable_parameter + + fifth_breakable_parameter + } + + entry fun private_entry() {} + + public fun public_function() {} + + public entry fun public_entry() {} + + public(package) fun public_package_function() {} + + public(package) entry fun public_package_entry() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/simple.move b/external-crates/move/tooling/prettier-move/tests/functions/simple.move new file mode 100644 index 00000000000..50f425575dd --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/simple.move @@ -0,0 +1,28 @@ +module prettier::simple_function { + fun say_hello() {} + /// This is a simple function + fun simple_function(): u64 { + say_hello(); + 100 + } + + fun breakable_parameters( + first_breakable_parameter: u64, + second_breakable_parameter: u64, + third_breakable_parameter: u64, + fourth_breakable_parameter: u64, + fifth_breakable_parameter: u64, + ): u64 { + first_breakable_parameter + + second_breakable_parameter + + third_breakable_parameter + + fourth_breakable_parameter + + fifth_breakable_parameter + } + + entry fun private_entry() {} + public fun public_function() {} + entry public fun public_entry() {} + public(package) fun public_package_function() {} + entry public(package) fun public_package_entry() {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/test.exp.move b/external-crates/move/tooling/prettier-move/tests/functions/test.exp.move new file mode 100644 index 00000000000..bbe7b7a3e54 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/test.exp.move @@ -0,0 +1,96 @@ +module test::functions { + /// Comment for a function. + fun empty() {} + + public fun pub() {} + + public entry fun pub_entry() {} + + public entry fun entry_pub() {} + + fun foo(foo: u64, bar: u64, baz: u64, foo: u64): u64 { + foo + bar + baz + } + + fun foo( + foo: u64, + bar: u64, + baz: u64, + foo: u64, + bar: u64, + baz: u64, + foo: u64, + bar: u64, + baz: u64, + ): u64 { + foo + bar + baz + } + + fun foo( + // first + foo: u64, + // second + bar: u64, + baz: u64, + ): u64 { + foo + bar + baz + } + + fun foo( + foo: u64, // first + bar: u64, // second + baz: u64, + ): u64 { + foo + bar + baz + } + + fun simple(p: u64): u64 {} + + fun simple_generic() {} + + fun long_type_list( + p1: SomeStructWithALongName, + p2: SomeStructWithALongName, + p3: SomeStructWithALongName, + p1: SomeStructWithALongName, + ): u64 {} + + fun long_type_list_and_generics< + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT1: key, + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT2: store, + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT3: drop, + >( + p1: SomeStructWithALongName, + p2: SomeStructWithALongName, + p3: SomeStructWithALongName, + p1: SomeStructWithALongName, + ): u64 {} + + fun long_type_list_generics_and_body< + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT1: key, + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT2: store, + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT3: drop, + >( + p1: SomeStructWithALongName, + p2: SomeStructWithALongName, + p3: SomeStructWithALongName, + p1: SomeStructWithALongName, + ): u64 { + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + } + + native fun simple_native(p: u64): u64; + + public native fun public_native(p: u64): u64; + + native fun simple_native_generic(): u64; + + // Comment for a function. + fun with_comment(p: u64): u64 {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/functions/test.move b/external-crates/move/tooling/prettier-move/tests/functions/test.move new file mode 100644 index 00000000000..c2081f956ce --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/functions/test.move @@ -0,0 +1,118 @@ +module test::functions { + /// Comment for a function. + fun empty() { + } + + public fun pub() { + } + + public entry fun pub_entry() { + } + + entry public fun entry_pub() { + } + + fun foo( + foo: u64, + bar: u64, + baz: u64, + foo: u64, + ): u64 { + foo + bar + baz + } + + fun foo( + foo: u64, + bar: u64, + baz: u64, + foo: u64, + bar: u64, + baz: u64, + foo: u64, + bar: u64, + baz: u64, + ): u64 { + foo + bar + baz + } + + fun foo( + // first + foo: u64, + // second + bar: u64, + baz: u64, + ): u64 { + foo + bar + baz + } + + fun foo( + foo: u64, // first + bar: u64, // second + baz: u64, + ): u64 { + foo + bar + baz + } + + + fun simple(p: u64): u64 { + } + + fun simple_generic( + ) + { + } + + fun long_type_list(p1: SomeStructWithALongName, + p2: SomeStructWithALongName, p3: + + + SomeStructWithALongName, p1: SomeStructWithALongName): u64 { + } + + fun long_type_list_and_generics + + (p1: SomeStructWithALongName, + p2: SomeStructWithALongName, p3: + + + SomeStructWithALongName, p1: SomeStructWithALongName): u64 { + } + + fun long_type_list_generics_and_body + + (p1: SomeStructWithALongName, + p2: SomeStructWithALongName, p3: + + + SomeStructWithALongName, p1: SomeStructWithALongName): u64 { + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + some_long_function_name(); + } + + native fun simple_native(p: u64): u64; + + public native fun public_native(p: u64): u64; + + native fun simple_native_generic( + ): u64; + + + // Comment for a function. + fun with_comment(p: u64): u64 {} +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/enum.macro.exp.move b/external-crates/move/tooling/prettier-move/tests/misc/enum.macro.exp.move new file mode 100644 index 00000000000..7b04ab5aff3 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/enum.macro.exp.move @@ -0,0 +1,172 @@ +module foo::bar { + // Imports + + use fun Self::foo as X.f1; + use fun a::m::foo as X.f2; + + use fun foo as Self::X.f3; + use fun foo as a::m::X.f4; + + use fun foo as X.f5; + + public use fun Self::foo as X.g1; + public use fun a::m::foo as X.g2; + + public use fun foo as Self::X.g3; + public use fun foo as a::m::X.g4; + + public use fun foo as X.g5; + + // Types + + public struct X {} + + public struct Old has key { + x: u64, + } + + public struct NewPost has key (u64, vector, u64) + + public struct NewPoster(u64) has key, store; + + public struct None() + + public enum NewEnum { + V(), + V1(u64, bool), + V2 { x: u64, y: bool }, + V3, + } + + public enum NewEnum has key { + NewVariant(u64), + VariantNoParams, + VariantEmptyParams(), + VariantNamedParams { x: u64 }, + } + + public fun new(mut x: T): T {} + + public fun new_let_mut(): u64 { + let mut x = 0; + x = 1; + let t = x.new(); + let t = x.new(a, b, t.y()); + let Old { mut y } = x.new(); + let NewPost(y) = x.new(); + let NewPoster(mut y) = x.new(); + let NewPoster(mut y, z, i) = x.new(); + let NewPoster(mut y, z, i) = x.new(); + let NewPoster::Variant(mut y, z, i) = x.new(); + + x.foreach!(|y| { x = y; }); + assert!(x == 1, 6); + x + } + + // blocks + public fun block() { + 'a: { + return 'a x; + break 'a x; + return 'a x.foo!(); + break 'a { + x = x + 1; + x + }; + continue 'a; + }; + 'a: loop {}; + 'a: while (true) {}; + while (true) 'a: {}; + // TODO: fix precedence of this + if (true) 1 else 'a: { 2 } + 1; + } + + // Macros + macro fun ignore(_: None) {} + + macro fun for($start: u64, $stop: u64, $body: |u64|) { + let mut i = $start; + let stop = $stop; + while (i < stop) { + $body(i); + i = i + 1 + } + } + + macro fun for_each<$T>($v: &vector<$T>, $body: |&$T|) { + let v = $v; + let mut i = 0; + let n = v.length(); + while (i < n) { + $body(v.borrow(i)); + i = i + 1 + } + } + + macro fun new<$T>($len: u64, $f: |u64| -> $T): vector<$T> { + let len = $len; + let mut v = vector[]; + for!(0, len, |i| v.push_back($f(i))); + v + } + + macro fun sum($v: &vector): u64 { + let mut s = 0; + for_each!($v, |i| s = s + *i); + s + } + + fun t() { + None().ignore!() + } + + entry fun main() { + let v = new!(10, |i| i); + assert!(sum!(&v) == 45, 0); + } + + public struct Cup has drop {} + public macro fun foo( + _: ||, + _: || -> (), + _: || -> u64, + _: || -> (u64), + _: || -> (u64, bool), + _: |&u64|, + _: |&u64| -> (), + _: |&u64| -> u64, + _: |&u64| -> (u64), + _: |&u64| -> (u64, bool), + _: |bool, address|, + _: |bool, address| -> (), + _: |bool, address| -> u64, + _: |bool, address| -> (u64), + _: |bool, address| -> (u64, bool), + _: |bool, address| -> (u64, bool, &u64), + _: || -> || -> ||, + _: || -> || -> || -> || -> (), + _: || -> || -> || -> || -> u64, + _: || -> || -> || -> || -> (u64), + _: Cup<||>, + _: Cup<|| -> u64>, + ) {} + + macro fun call<$T>($f: || -> $T): $T { + $f() + } + + fun t() { + call!(|| -> u64 'a: { + 0 + }); + } + + fun t() { + call!(|| -> () {}); + call!(|| -> () { () }); + call!(|| -> u64 { 0 }); + call!(|| -> (u64, u8) { (0, 0) }); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/enum.macro.move b/external-crates/move/tooling/prettier-move/tests/misc/enum.macro.move new file mode 100644 index 00000000000..b194c4b0e9f --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/enum.macro.move @@ -0,0 +1,171 @@ +module foo::bar { + + // Imports + + use fun Self::foo as X.f1; + use fun a::m::foo as X.f2; + + use fun foo as Self::X.f3; + use fun foo as a::m::X.f4; + + use fun foo as X.f5; + + public use fun Self::foo as X.g1; + public use fun a::m::foo as X.g2; + + public use fun foo as Self::X.g3; + public use fun foo as a::m::X.g4; + + public use fun foo as X.g5; + + // Types + + public struct X {} + + public struct Old has key { + x: u64 + } + + public struct NewPost has key (u64, vector, u64) + + public struct NewPoster(u64) has key, store; + + public struct None() + + public enum NewEnum { + V(), + V1(u64, bool), + V2 { x: u64, y: bool }, + V3 + } + + public enum NewEnum has key { + NewVariant(u64), + VariantNoParams, + VariantEmptyParams(), + VariantNamedParams { x: u64 }, + } + + public fun new(mut x: T): T { + } + + public fun new_let_mut(): u64 { + let mut x = 0; + x = 1; + let t = x.new(); + let t = x.new(a, b, t.y()); + let Old { mut y } = x.new(); + let NewPost(y) = x.new(); + let NewPoster(mut y) = x.new(); + let NewPoster(mut y, z, i) = x.new(); + let NewPoster(mut y, z, i) = x.new(); + let NewPoster::Variant(mut y, z, i) = x.new(); + + x.foreach!(|y| { x = y; }); + assert!(x == 1, 6); + x + } + + // blocks + public fun block() { + 'a: { + return 'a x; + break 'a x; + return'a x.foo!(); + break'a { x = x + 1; x }; + continue 'a; + }; + 'a: loop { }; + 'a: while (true) { }; + while (true) 'a: { }; + // TODO: fix precedence of this + if (true) 1 else 'a: { 2 } + 1; + } + + // Macros + macro fun ignore( + _: None, + ) {} + + macro fun for($start: u64, $stop: u64, $body: |u64|) { + let mut i = $start; + let stop = $stop; + while (i < stop) { + $body(i); + i = i + 1 + } + } + + macro fun for_each<$T>($v: &vector<$T>, $body: |&$T|) { + let v = $v; + let mut i = 0; + let n = v.length(); + while (i < n) { + $body(v.borrow(i)); + i = i + 1 + } + } + + macro fun new<$T>($len: u64, $f: |u64| -> $T): vector<$T> { + let len = $len; + let mut v = vector[]; + for!(0, len, |i| v.push_back($f(i))); + v + } + + macro fun sum($v: &vector): u64 { + let mut s = 0; + for_each!($v, |i| s = s + *i); + s + } + + fun t() { + None().ignore!() + } + + entry fun main() { + let v = new!(10, |i| i); + assert!(sum!(&v) == 45, 0); + } + + public struct Cup has drop {} + public macro fun foo( + _: ||, + _: || -> (), + _: || -> u64, + _: || -> (u64), + _: || -> (u64, bool), + _: |&u64|, + _: |&u64| -> (), + _: |&u64| -> u64, + _: |&u64| -> (u64), + _: |&u64| -> (u64, bool), + _: |bool, address|, + _: |bool, address| -> (), + _: |bool, address| -> u64, + _: |bool, address| -> (u64), + _: |bool, address| -> (u64, bool), + _: |bool, address| -> (u64, bool, &u64), + _: || -> || -> ||, + _: || -> || -> || -> || -> (), + _: || -> | | -> || -> | | -> u64, + _: | | -> || -> | | -> || -> (u64), + _: Cup<||>, + _: Cup<|| -> u64>, + ) {} + + macro fun call<$T>($f: || -> $T): $T { + $f() + } + + fun t() { + call!(|| -> u64 'a: { 0 }); + } + + fun t() { + call!(|| -> () { }); + call!(|| -> () { () }); + call!(|| -> u64 { 0 }); + call!(|| -> (u64, u8) { (0, 0) }); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/formatting.exp.move b/external-crates/move/tooling/prettier-move/tests/misc/formatting.exp.move new file mode 100644 index 00000000000..4862b99559e --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/formatting.exp.move @@ -0,0 +1,84 @@ +// This is a line comment +/* + +this is a multi-line block comment + +*/ + +// This is a line comment + +module tests::formatting { + public struct Beep { + transferred_to_object: VecMap, + } + + public fun list() { + let a = vector[ + /* block */ 100, // hahaha + /* block */ 200, // hihihi + ]; + + let b = vector[100, /* hahaha */ 200 /* hihihi */]; + + let c /* comment in between */ : vector = vector[ + 100, // hahaha + 200, // hihihi + ]; + + let t: /* comment */ vector = vector[100, 200]; + } + + public fun t_comment() { + let very_long_variable = + x"000000000000000000000000000000000000000000000000000000000000000000"; // t_comment + + if ( + x"000000000000000000000000000000000000000000000000000000000000000000" // t_comment + ) { + return; + }; + function_call( + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + ); + + // leading commment + dot.something().then().else(); // t_comment + + vector.length().do!(|el| el.something()); // t_comment + vector.length().do!(|el| el.something().then().else()); // t_comment + vector + .length() + .do!( + |el| el + .something() /* I */ + .then() /* Hate */ + .else() /* You */ + .and() /* Prettier */ + .we() + .expect() + .breaking() + .right() + .here(), + ); // t_comment + + dot + .something() // t_comment + .then() // t_comment + .else(); // t_comment + + dot + .dot() + .function_call( + // leading commment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + // leading commment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + ); + + macro_call!( + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + ); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/formatting.move b/external-crates/move/tooling/prettier-move/tests/misc/formatting.move new file mode 100644 index 00000000000..eb77bac12c4 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/formatting.move @@ -0,0 +1,73 @@ +// This is a line comment +/* + +this is a multi-line block comment + +*/ + +// This is a line comment + +module tests::formatting { + public struct Beep { + transferred_to_object: VecMap, + } + + + + public fun list() { + let a = vector[ + // leading + /* block */ 100, // hahaha + // lead + /* block */ 200, // hihihi + ]; + + let b = vector[100 /* hahaha */, 200 /* hihihi */]; + + + let c /* comment in between */ : vector = vector[ + 100, // hahaha + 200, // hihihi + ]; + + let t: /* comment */ vector = vector[100, 200]; + } + + public fun t_comment() { + let very_long_variable = + x"000000000000000000000000000000000000000000000000000000000000000000"; // t_comment + + if ( + x"000000000000000000000000000000000000000000000000000000000000000000" // t_comment + ) { + return; + }; + function_call( + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + ); + + // leading commment + dot.something().then().else(); // t_comment + + vector.length().do!(|el| el.something()); // t_comment + vector.length().do!(|el| el.something().then().else()); // t_comment + vector.length().do!(|el| el.something()/* I */.then()/* Hate */.else() /* You */.and()/* Prettier */.we().expect().breaking().right().here()); // t_comment + + dot.something() // t_comment + .then() // t_comment + .else(); // t_comment + + dot.dot().function_call( + // leading commment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + // leading commment + x"000000000000000000000000000000000000000000000000000000000000000000", // t_comment + ); + + macro_call!( + x"000000000000000000000000000000000000000000000000000000000000000000" // t_comment + x"000000000000000000000000000000000000000000000000000000000000000000" // t_comment + ); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/misc.exp.move b/external-crates/move/tooling/prettier-move/tests/misc/misc.exp.move new file mode 100644 index 00000000000..c6b4061dabf --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/misc.exp.move @@ -0,0 +1,230 @@ +// options: +// printWidth: 80 +// autoGroupImports: package +// useModuleLabel: true + +/* + * @title Timelock + * + * @notice Locks any object with the store ability for a specific amount of time. + * + * @dev We do not provide a function to read the data inside the {Timelock} to prevent capabilities from being used. + */ +module suitears::timelock; + +use std::{string::String, type_name::{Self, TypeName}}; +use iota::{ + clock::Clock, + coin::Coin, + dynamic_field as df, + iota::IOTA, + table::{Self, Table} +}; + +fun calculate_pending_rewards( + acc: &Account, + stake_factor: u64, + accrued_rewards_per_share: u256, +): u64 { + ( + ( + ((acc.amount as u256) * accrued_rewards_per_share / (stake_factor as u256)) - acc.reward_debt, + ) as u64, + ) +} + +// iota-system/validator_set.move +fun compute_reward_adjustments( + mut slashed_validator_indices: vector, + reward_slashing_rate: u64, + unadjusted_staking_reward_amounts: &vector, + unadjusted_storage_fund_reward_amounts: &vector, +): ( + u64, // sum of staking reward adjustments + VecMap, // mapping of individual validator's staking reward adjustment from index -> amount + u64, // sum of storage fund reward adjustments + VecMap, // mapping of individual validator's storage fund reward adjustment from index -> amount +) { + let unadjusted_storage_fund_reward_amount = + unadjusted_storage_fund_reward_amounts[i]; + let adjusted_storage_fund_reward_amount = // If the validator is one of the slashed ones, then subtract the adjustment. + if (individual_storage_fund_reward_adjustments.contains(&i)) { + let adjustment = individual_storage_fund_reward_adjustments[&i]; + unadjusted_storage_fund_reward_amount - adjustment + } else { + // Otherwise the slashed rewards should be equally distributed among the unslashed validators. + let adjustment = + total_storage_fund_reward_adjustment / num_unslashed_validators; + unadjusted_storage_fund_reward_amount + adjustment + }; + + adjusted_storage_fund_reward_amounts.push_back( + adjusted_storage_fund_reward_amount, + ); +} + +// === Imports === + +public fun lock( + data: T, + c: &Clock, + unlock_time: u64, + ctx: &mut TxContext, +): Timelock { + // It makes no sense to lock in the past + assert!(unlock_time > c.timestamp_ms(), EInvalidTime); +} + +public fun propose( + dao: &mut Dao, + c: &Clock, + authorized_witness: Option, + capability_id: Option, + action_delay: u64, + quorum_votes: u64, + hash: String, + // hash proposal title/content + ctx: &mut TxContext, +): Proposal { + assert!(action_delay >= dao.min_action_delay, EActionDelayTooShort); + assert!(quorum_votes >= dao.min_quorum_votes, EMinQuorumVotesTooSmall); + assert!(hash.length() != 0, EEmptyHash); + + let start_time = c.timestamp_ms() + dao.voting_delay; + + let proposal = Proposal { + id: object::new(ctx), + proposer: ctx.sender(), + start_time, + end_time: start_time + dao.voting_period, + for_votes: 0, + against_votes: 0, + eta: 0, + action_delay, + quorum_votes, + voting_quorum_rate: dao.voting_quorum_rate, + hash, + authorized_witness, + capability_id, + coin_type: dao.coin_type, + }; + + emit(NewProposal { + proposal_id: object::id(&proposal), + proposer: proposal.proposer, + }); + + proposal +} + +public fun inline_fun(): u128 { 1000 } + +// === Public View Function === + +/* + * @notice Returns the unlock time in milliseconds. + * + * @param self A {Timelock} + * @return u64. The `self.unlock_time`. + */ +public fun unlock_time(self: &Timelock): u64 { + self.unlock_time +} + +// === Public Mutative Function === + +/* + * @notice Locks the `data` for `unlock_time` milliseconds. + * + * @param data An object with the store ability. + * @param c The shared `iota::clock::Clock` object. + * @patam unlock_time The lock period in milliseconds. + * @return {Timelock}. + * + * aborts-if + * - `unlock_time` is in the past. + */ +public fun lock( + data: T, + c: &Clock, + unlock_time: u64, + ctx: &mut TxContext, +): Timelock { + // It makes no sense to lock in the past + assert!(unlock_time > c.timestamp_ms(), EInvalidTime); + + Timelock { id: object::new(ctx), data, unlock_time } +} + +/* + * @notice Unlocks a {Timelock} and returns the locked resource `T`. + * + * @param self A {Timelock} + * @param c The shared `iota::clock::Clock` object. + * @return `T`. An object with the store ability. + * + * aborts-if + * - `unlock_time` has not passed. + */ +public fun unlock(self: Timelock, c: &Clock): T { + let Timelock { id, data, unlock_time } = self; + + assert!(c.timestamp_ms() >= unlock_time, ETooEarly); + id.delete(); + data +} + +/// Print the container as an `SVG` element. +public fun to_string(container: &Container): String { + let (name, attributes, elements) = match (container) { + // Desc is a special case, it's just a list of descriptions. + Container::Desc(tags) => { + return (*tags).fold!(b"".to_string(), |mut svg, tag| { + svg.append(tag.to_string()); + svg + }) + }, + // Root is a special case, we append all elements directly. + Container::Root(shapes) => { + return (*shapes).fold!(b"".to_string(), |mut svg, shape| { + svg.append(shape.to_string()); + svg + }) + }, + Container::Defs(shapes) => ( + b"defs", + vec_map::empty(), + shapes.map_ref!(|shape| shape.to_string()), + ), + Container::A(_href, attrs) => (b"a", *attrs, vector[]), + Container::G(shapes, attrs) => ( + b"g", + *attrs, + shapes.map_ref!(|shape| shape.to_string()), + ), + _ => abort ENotImplemented, + }; + + print::print(name.to_string(), attributes, option::some(elements)) +} + +fun content() { + expression + // disappearing_comment_1 + .div(50) // trailing_comment_1 + // disappearing_comment_2 + .mul(50); // trailing_comment_2 + + svg.add_root(vector[ + { + let mut shape = shape::text(str.to_string(), 100, 50); + shape + }, + shape::circle(10, 10, 5), + { + let mut rect = shape::rect(10, 10, 20, 20); + rect + }, + shape::ellipse(30, 30, 10, 5), + ]); +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/misc.move b/external-crates/move/tooling/prettier-move/tests/misc/misc.move new file mode 100644 index 00000000000..cf832c8436c --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/misc.move @@ -0,0 +1,213 @@ +// options: +// printWidth: 80 +// autoGroupImports: package +// useModuleLabel: true + +/* + * @title Timelock + * + * @notice Locks any object with the store ability for a specific amount of time. + * + * @dev We do not provide a function to read the data inside the {Timelock} to prevent capabilities from being used. + */ +module suitears::timelock { + + use std::{string::String, type_name::{Self, TypeName}}; + use iota::{ + clock::Clock, + coin::Coin, + dynamic_field as df, + iota::IOTA, + table::{Self, Table} + }; + + fun calculate_pending_rewards( + acc: &Account, + stake_factor: u64, + accrued_rewards_per_share: u256, + ): u64 { + ((((acc.amount as u256) * accrued_rewards_per_share / (stake_factor as u256)) - acc.reward_debt) as u64) + } + + // iota-system/validator_set.move + fun compute_reward_adjustments( + mut slashed_validator_indices: vector, + reward_slashing_rate: u64, + unadjusted_staking_reward_amounts: &vector, + unadjusted_storage_fund_reward_amounts: &vector, + ): ( + u64, // sum of staking reward adjustments + VecMap, // mapping of individual validator's staking reward adjustment from index -> amount + u64, // sum of storage fund reward adjustments + VecMap, // mapping of individual validator's storage fund reward adjustment from index -> amount + ) { + let unadjusted_storage_fund_reward_amount = unadjusted_storage_fund_reward_amounts[i]; + let adjusted_storage_fund_reward_amount = + // If the validator is one of the slashed ones, then subtract the adjustment. + if (individual_storage_fund_reward_adjustments.contains(&i)) { + let adjustment = individual_storage_fund_reward_adjustments[&i]; + unadjusted_storage_fund_reward_amount - adjustment + } else { + // Otherwise the slashed rewards should be equally distributed among the unslashed validators. + let adjustment = total_storage_fund_reward_adjustment / num_unslashed_validators; + unadjusted_storage_fund_reward_amount + adjustment + }; + + adjusted_storage_fund_reward_amounts.push_back(adjusted_storage_fund_reward_amount); + } + + // === Imports === + + public fun lock(data: T, c: &Clock, unlock_time: u64, ctx: &mut TxContext): Timelock< + T + > { + // It makes no sense to lock in the past + assert!(unlock_time > c.timestamp_ms(), EInvalidTime); + } + + public fun propose( + dao: &mut Dao, + c: &Clock, + authorized_witness: Option, + capability_id: Option, + action_delay: u64, + quorum_votes: u64, + hash: String, + // hash proposal title/content + ctx: &mut TxContext + ): Proposal { + + + assert!(action_delay >= dao.min_action_delay, EActionDelayTooShort); + assert!(quorum_votes >= dao.min_quorum_votes, EMinQuorumVotesTooSmall); + assert!(hash.length() != 0, EEmptyHash); + + let start_time = c.timestamp_ms() + dao.voting_delay; + + + + let proposal = Proposal { + id: object::new(ctx), + proposer: ctx.sender(), + start_time, + end_time: start_time + dao.voting_period, + for_votes: 0, + against_votes: 0, + eta: 0, + action_delay, + quorum_votes, + voting_quorum_rate: dao.voting_quorum_rate, + hash, + authorized_witness, + capability_id, + coin_type: dao.coin_type + }; + + emit( + NewProposal { + proposal_id: object::id(&proposal), + proposer: proposal.proposer + } + ); + + proposal + } + + public fun inline_fun(): u128 { 1000 } + + // === Public View Function === + + /* + * @notice Returns the unlock time in milliseconds. + * + * @param self A {Timelock} + * @return u64. The `self.unlock_time`. + */ + public fun unlock_time(self: &Timelock): u64 { + self.unlock_time + } + + // === Public Mutative Function === + + /* + * @notice Locks the `data` for `unlock_time` milliseconds. + * + * @param data An object with the store ability. + * @param c The shared `iota::clock::Clock` object. + * @patam unlock_time The lock period in milliseconds. + * @return {Timelock}. + * + * aborts-if + * - `unlock_time` is in the past. + */ + public fun lock( + data: T, c: &Clock, unlock_time: u64, ctx: &mut TxContext): Timelock< + T + > { + // It makes no sense to lock in the past + assert!(unlock_time > c.timestamp_ms(), EInvalidTime); + + Timelock {id: object::new(ctx), data, unlock_time} + } + + /* + * @notice Unlocks a {Timelock} and returns the locked resource `T`. + * + * @param self A {Timelock} + * @param c The shared `iota::clock::Clock` object. + * @return `T`. An object with the store ability. + * + * aborts-if + * - `unlock_time` has not passed. + */ + public fun unlock(self: Timelock, c: &Clock): T { + let Timelock { id, data, unlock_time } = self; + + assert!(c.timestamp_ms() >= unlock_time, ETooEarly); + id.delete(); + data + } + + /// Print the container as an `SVG` element. + public fun to_string(container: &Container): String { + let (name, attributes, elements) = match (container) { + // Desc is a special case, it's just a list of descriptions. + Container::Desc(tags) => { + return (*tags).fold!(b"".to_string(), |mut svg, tag| { + svg.append(tag.to_string()); + svg + }) + }, + // Root is a special case, we append all elements directly. + Container::Root(shapes) => { + return (*shapes).fold!(b"".to_string(), |mut svg, shape| { + svg.append(shape.to_string()); + svg + }) + }, + Container::Defs(shapes) => + (b"defs", vec_map::empty(), shapes.map_ref!(|shape| shape.to_string())), + Container::A(_href, attrs) => (b"a", *attrs, vector[]), + Container::G(shapes, attrs) => (b"g", *attrs, shapes.map_ref!(|shape| shape.to_string())), + _ => abort ENotImplemented, + }; + + print::print(name.to_string(), attributes, option::some(elements)) + } + + fun content() { + expression + // disappearing_comment_1 + .div(50) // trailing_comment_1 + // disappearing_comment_2 + .mul(50); // trailing_comment_2 + + svg.add_root(vector[{ + let mut shape = shape::text(str.to_string(), 100, 50); + shape + }, shape::circle(10, 10, 5), { + let mut rect = shape::rect(10, 10, 20, 20); + rect + }, shape::ellipse(30, 30, 10, 5)]); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/other.exp.move b/external-crates/move/tooling/prettier-move/tests/misc/other.exp.move new file mode 100644 index 00000000000..a9bd8cb7a86 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/other.exp.move @@ -0,0 +1,82 @@ +// options: +// printWidth: 100 + +module prettier::other { + fun other() { + let mut fungible_staked_iota_1 = staking_pool.create_fungible_staked_iota_for_testing( + 100_000_000_000, + scenario.ctx(), + ); + let fungible_staked_iota_2 = staking_pool.create_fungible_staked_iota_for_testing( + 200_000_000_000, + scenario.ctx(), + ); + + fungible_staked_iota_1.join(fungible_staked_iota_2); + + // expected to break on the argument list + let new_id = validator_cap::new_unverified_validator_operation_cap_and_transfer( + address, + ctx, + ); + + // expected not to break on the first line + let mut validator = new_from_metadata( + new_metadata( + iota_address, + protocol_pubkey_bytes, + network_pubkey_bytes, + worker_pubkey_bytes, + proof_of_possession, + name.to_ascii_string().to_string(), + description.to_ascii_string().to_string(), + url::new_unsafe_from_bytes(image_url), + url::new_unsafe_from_bytes(project_url), + net_address.to_ascii_string().to_string(), + p2p_address.to_ascii_string().to_string(), + primary_address.to_ascii_string().to_string(), + worker_address.to_ascii_string().to_string(), + bag::new(ctx), + ), + gas_price, + commission_rate, + ctx, + ); + + character.add( + AppKey {}, + BattleApp { + stats, + wins: 0, + losses: 0, + current_battle: option::none(), + }, + ); + + // allow lambda to be on the same line + s.do!(|i| { + let c = s.as_bytes()[i]; + if (c == 37) { + // percent "%" + let a = s.as_bytes()[i + 1]; + let b = s.as_bytes()[i + 2]; + let a = if (a >= 65) a - 55 else a - 48; + let b = if (b >= 65) b - 55 else b - 48; + res.push_back(a * 16 + b); + i = i + 2; + } else { + res.push_back(c); + }; + i = i + 1; + }); + + // some weird stuff is happening with the comment + expr + .div(50) + .add(2) + .mul(random) // ??? + .div(255) + // ??? + .calc_u64(0); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/misc/other.move b/external-crates/move/tooling/prettier-move/tests/misc/other.move new file mode 100644 index 00000000000..02b168b151d --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/misc/other.move @@ -0,0 +1,79 @@ +// options: +// printWidth: 100 + +module prettier::other { + fun other() { + let mut fungible_staked_iota_1 = + staking_pool.create_fungible_staked_iota_for_testing( + 100_000_000_000, + scenario.ctx(), + ); + let fungible_staked_iota_2 = + staking_pool.create_fungible_staked_iota_for_testing( + 200_000_000_000, + scenario.ctx(), + ); + + fungible_staked_iota_1.join(fungible_staked_iota_2); + + // expected to break on the argument list + let new_id = + validator_cap::new_unverified_validator_operation_cap_and_transfer(address, ctx); + + // expected not to break on the first line + let mut validator = new_from_metadata( + new_metadata( + iota_address, + protocol_pubkey_bytes, + network_pubkey_bytes, + worker_pubkey_bytes, + proof_of_possession, + name.to_ascii_string().to_string(), + description.to_ascii_string().to_string(), + url::new_unsafe_from_bytes(image_url), + url::new_unsafe_from_bytes(project_url), + net_address.to_ascii_string().to_string(), + p2p_address.to_ascii_string().to_string(), + primary_address.to_ascii_string().to_string(), + worker_address.to_ascii_string().to_string(), + bag::new(ctx), + ), + gas_price, + commission_rate, + ctx, + ); + + character.add( + AppKey {}, + BattleApp { + stats, // this comment is wiped + wins: 0, losses: 0, current_battle: option::none() }, + ); + + // allow lambda to be on the same line + s.do!(|i| { + let c = s.as_bytes()[i]; + if (c == 37) { + // percent "%" + let a = s.as_bytes()[i + 1]; + let b = s.as_bytes()[i + 2]; + let a = if (a >= 65) a - 55 else a - 48; + let b = if (b >= 65) b - 55 else b - 48; + res.push_back(a * 16 + b); + i = i + 2; + } else { + res.push_back(c); + }; + i = i + 1; + }); + + // some weird stuff is happening with the comment + expr + .div(50) + .add(2) + .mul(random) // ??? + .div(255) + // ??? + .calc_u64(0); + } +} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/annotation.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/annotation.exp.move new file mode 100644 index 00000000000..e16ed4db715 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/annotation.exp.move @@ -0,0 +1,59 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +/// Covers `annotation` node in grammar +module prettier::annotation; + +// if it fits, printed on one line +#[test] +#[allow(unused_imports)] +#[allow(unused_const, unused_variable)] +fun e() {} + +// long annotations will get broken +#[ + expected_error( + abort_code = ::ENotImplemented, + ), +] +fun f() {} + +// a list of annotations will also be +// broken however, will never break the +// assignment +#[ + test, + expected_failure( + abort_code = ::other_module::ENotFound, + ), +] +fun g() {} + +// assignments are printed as is, no breaking +#[ + expected_failure( + arithmetic_error, + location = pkg_addr::other_module, + ), +] +#[ + allow( + unused_const, + unused_variable, + unused_imports, + unused_field, + ), +] +fun h() {} + +// we support literals in annotations +#[error, code = b"string"] +fun i() {} + +// we support full type idents +#[ + error, + abort_code = ::other_module::EArithmeticError, +] +fun j() {} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/annotation.move b/external-crates/move/tooling/prettier-move/tests/module-members/annotation.move new file mode 100644 index 00000000000..adefff774e2 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/annotation.move @@ -0,0 +1,59 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +/// Covers `annotation` node in grammar +module prettier::annotation; + +// if it fits, printed on one line +#[test] +#[allow(unused_imports)] +#[allow(unused_const, unused_variable)] +fun e() {} + +// long annotations will get broken +#[ + expected_error( + abort_code = ::ENotImplemented + ) +] +fun f() {} + +// a list of annotations will also be +// broken however, will never break the +// assignment +#[ + test, + expected_failure( + abort_code = ::other_module::ENotFound + ) +] +fun g() {} + +// assignments are printed as is, no breaking +#[ + expected_failure( + arithmetic_error, + location = pkg_addr::other_module + ) +] +#[ + allow( + unused_const, + unused_variable, + unused_imports, + unused_field + ) +] +fun h() {} + +// we support literals in annotations +#[error, code = b"string"] +fun i() {} + +// we support full type idents +#[ + error, + abort_code = ::other_module::EArithmeticError +] +fun j() {} diff --git a/external-crates/move/tooling/prettier-move/tests/module-members/constant.exp.move b/external-crates/move/tooling/prettier-move/tests/module-members/constant.exp.move new file mode 100644 index 00000000000..59be25b2538 --- /dev/null +++ b/external-crates/move/tooling/prettier-move/tests/module-members/constant.exp.move @@ -0,0 +1,118 @@ +// options: +// printWidth: 40 +// useModuleLabel: true + +/// Covers `constant` node in grammar +module test::constants; + +// standard constant, fits the line +const CONSTANT: vector = b"const"; // trailing + +// breaks on long value, trying to break +// the value first +const CONSTANT: vector = vector[ + 100, 200, +]; + +// alternatively will newline the value +const CONSTANT: vector = + b"constant_too_long"; + +// if there's a risk of breaking the type +// it will first try to break the value +const CONSTANT: vector> = + vector[]; + +// however, types will still break if +// there's no other option. A rare case. +const CONSTANT_ADDRESS: vector< + vector