From f5a594e5ab5445a050b5f5e28a27d9283a4e50e0 Mon Sep 17 00:00:00 2001 From: Timothy Zakian Date: Fri, 19 Apr 2024 14:04:20 -0700 Subject: [PATCH] [1][5/n][enums] All Move tests except source lang tests --- external-crates/move/Cargo.lock | 1 + .../src/unit_tests/prop_tests.rs | 6 +- .../bounds_tests.proptest-regressions | 8 +- .../src/unit_tests/bounds_tests.rs | 86 +++++- .../src/unit_tests/constants_tests.rs | 2 +- .../src/unit_tests/duplication_tests.rs | 7 + .../src/unit_tests/generic_ops_tests.rs | 39 ++- .../src/unit_tests/large_type_test.rs | 5 + .../src/unit_tests/limit_tests.rs | 36 ++- .../src/unit_tests/locals.rs | 3 + .../src/unit_tests/loop_summary_tests.rs | 158 ++++++----- .../src/unit_tests/many_back_edges.rs | 2 + .../src/unit_tests/mod.rs | 4 +- .../src/unit_tests/reference_safety_tests.rs | 11 + .../src/unit_tests/signature_tests.rs | 21 +- .../src/unit_tests/vec_pack_tests.rs | 1 + .../resource_enum_has_resource_field.exp | 1 + .../resource_enum_has_resource_field.mvir | 5 + .../unrestricted_enum_has_resource_field.exp | 28 ++ .../unrestricted_enum_has_resource_field.mvir | 39 +++ .../too_few_type_actuals_enum.exp | 10 + .../too_few_type_actuals_enum.mvir | 11 + .../too_many_type_actuals_enum.exp | 10 + .../too_many_type_actuals_enum.mvir | 11 + .../duplicate_enum_and_struct_names.exp | 10 + .../duplicate_enum_and_struct_names.mvir | 6 + .../check_duplication/duplicate_enum_name.exp | 10 + .../duplicate_enum_name.mvir | 7 + .../duplicate_field_name_enum.exp | 10 + .../duplicate_field_name_enum.mvir | 7 + .../duplicate_variant_name.exp | 10 + .../duplicate_variant_name.mvir | 10 + .../tests/check_duplication/empty_enums.exp | 10 + .../tests/check_duplication/empty_enums.mvir | 7 + .../tests/control_flow/variant_switch.exp | 19 ++ .../tests/control_flow/variant_switch.mvir | 51 ++++ .../control_flow/variant_switch_successor.exp | 10 + .../variant_switch_successor.mvir | 19 ++ .../variant_switch_unconditional_branch.exp | 1 + .../variant_switch_unconditional_branch.mvir | 29 ++ .../tests/enum_defs/enum_match.exp | 1 + .../tests/enum_defs/enum_match.mvir | 39 +++ .../enum_defs/enum_match_out_of_bounds.exp | 10 + .../enum_defs/enum_match_out_of_bounds.mvir | 39 +++ .../enum_defs/module_enum_shared_name.exp | 1 + .../enum_defs/module_enum_shared_name.mvir | 21 ++ .../module_enum_struct_shared_name.exp | 10 + .../module_enum_struct_shared_name.mvir | 5 + .../tests/enum_defs/mutual_recursive_enum.exp | 10 + .../enum_defs/mutual_recursive_enum.mvir | 6 + .../tests/enum_defs/recursive_enum.exp | 46 +++ .../tests/enum_defs/recursive_enum.mvir | 56 ++++ .../tests/enum_defs/ref_in_enum.exp | 37 +++ .../tests/enum_defs/ref_in_enum.mvir | 19 ++ .../instantiation_loops/complex_1_enum.exp | 28 ++ .../instantiation_loops/complex_1_enum.mvir | 123 ++++++++ ...lly_recursive_non_generic_type_ok_enum.exp | 1 + ...ly_recursive_non_generic_type_ok_enum.mvir | 16 ++ ...rgs_type_con_non_generic_types_ok_enum.exp | 1 + ...gs_type_con_non_generic_types_ok_enum.mvir | 24 ++ ...sive_three_args_type_con_shifting_enum.exp | 10 + ...ive_three_args_type_con_shifting_enum.mvir | 23 ++ ...ursive_two_args_swapping_type_con_enum.exp | 10 + ...rsive_two_args_swapping_type_con_enum.mvir | 17 ++ .../mutually_recursive_type_con_enum.exp | 10 + .../mutually_recursive_type_con_enum.mvir | 20 ++ .../nested_types_1_enum.exp | 10 + .../nested_types_1_enum.mvir | 11 + .../nested_types_2_enum.exp | 10 + .../nested_types_2_enum.mvir | 13 + .../nested_types_2_enum_struct.exp | 10 + .../nested_types_2_enum_struct.mvir | 13 + .../recursive_one_arg_type_con_enum.exp | 10 + .../recursive_one_arg_type_con_enum.mvir | 14 + ...ursive_two_args_swapping_type_con_enum.exp | 10 + ...rsive_two_args_swapping_type_con_enum.mvir | 15 + .../instantiation_loops/two_loops_enum.exp | 10 + .../instantiation_loops/two_loops_enum.mvir | 20 ++ .../locals_safety/assign_enum_resource.exp | 19 ++ .../locals_safety/assign_enum_resource.mvir | 46 +++ .../borrow_enum_field_mutable_invalid.exp | 1 + .../borrow_enum_field_mutable_invalid.mvir | 95 +++++++ .../reference_safety/factor_invalid_2.exp | 2 +- .../factor_invalid_2_enum.exp | 10 + .../factor_invalid_2_enum.mvir | 34 +++ .../imm_borrow_on_mut_invalid.exp | 2 +- .../imm_borrow_on_mut_invalid_enum.exp | 19 ++ .../imm_borrow_on_mut_invalid_enum.mvir | 96 +++++++ .../imm_borrow_on_mut_trivial_invalid.exp | 2 +- ...imm_borrow_on_mut_trivial_invalid_enum.exp | 10 + ...mm_borrow_on_mut_trivial_invalid_enum.mvir | 22 ++ .../two_mutable_enum_unpacks.exp | 1 + .../two_mutable_enum_unpacks.mvir | 27 ++ ...s_type_actual_for_bytecode_instruction.exp | 2 +- ...n_struct_inst_for_bytecode_instruction.exp | 4 +- .../pack_invalid_number_arguments_enum.exp | 37 +++ .../pack_invalid_number_arguments_enum.mvir | 48 ++++ .../unpack_extra_binding_enum.exp | 37 +++ .../unpack_extra_binding_enum.mvir | 92 ++++++ .../unpack_missing_binding_enum.exp | 37 +++ .../unpack_missing_binding_enum.mvir | 91 ++++++ .../struct_defs/mutual_recursive_struct.exp | 2 +- .../tests/struct_defs/recursive_struct.exp | 10 +- .../type_safety/assign_local_resource.exp | 11 +- .../type_safety/assign_local_resource.mvir | 11 + .../assign_local_resource_twice.exp | 13 +- .../assign_local_resource_twice.mvir | 14 +- .../type_safety/assign_resource_type_enum.exp | 10 + .../assign_resource_type_enum.mvir | 14 + .../tests/type_safety/cant_deref_resource.exp | 11 +- .../type_safety/cant_deref_resource.mvir | 43 +++ .../type_safety/equality_resource_refs.exp | 2 +- .../type_safety/equality_resource_refs.mvir | 28 ++ .../type_safety/equality_resource_values.exp | 11 +- .../type_safety/equality_resource_values.mvir | 12 + .../generic_abilities_imm_unpack_enum.exp | 1 + .../generic_abilities_imm_unpack_enum.mvir | 23 ++ .../type_safety/generic_abilities_pack.exp | 2 +- .../type_safety/generic_abilities_pack.mvir | 12 + ..._abilities_struct_non_nominal_resource.exp | 11 +- ...abilities_struct_non_nominal_resource.mvir | 13 + .../type_safety/generic_abilities_unpack.exp | 11 +- .../type_safety/generic_abilities_unpack.mvir | 12 + .../generic_abilities_unpack_mut_enum.exp | 1 + .../generic_abilities_unpack_mut_enum.mvir | 19 ++ .../tests/type_safety/generic_call.exp | 2 +- .../tests/type_safety/generic_call.mvir | 24 ++ .../type_safety/generic_field_borrow.exp | 2 +- .../type_safety/generic_field_borrow.mvir | 14 + ...ic_field_unpack_borrow_after_call_enum.exp | 1 + ...c_field_unpack_borrow_after_call_enum.mvir | 17 ++ .../type_safety/generic_import_struct.exp | 2 +- .../type_safety/generic_import_struct.mvir | 29 ++ .../tests/type_safety/generic_option.exp | 2 +- .../tests/type_safety/generic_option.mvir | 39 +++ .../tests/type_safety/generic_pack.exp | 2 +- .../tests/type_safety/generic_pack.mvir | 25 ++ .../generic_pack_type_mismatch.exp | 73 +++++ .../generic_pack_type_mismatch.mvir | 103 +++++++ .../tests/type_safety/generic_struct_def.exp | 2 +- .../tests/type_safety/generic_struct_def.mvir | 11 + .../tests/type_safety/generic_unpack.exp | 2 +- .../tests/type_safety/generic_unpack.mvir | 26 ++ .../generic_unpack_type_mismatch.exp | 19 ++ .../generic_unpack_type_mismatch.mvir | 27 ++ .../invalid_field_write_mut_unpack_enum.exp | 19 ++ .../invalid_field_write_mut_unpack_enum.mvir | 37 +++ .../invalid_resouce_write_unpack_mut_enum.exp | 10 + ...invalid_resouce_write_unpack_mut_enum.mvir | 15 + .../mut_borrow_from_imm_ref_enum.exp | 19 ++ .../mut_borrow_from_imm_ref_enum.mvir | 38 +++ .../mut_call_from_get_resource.exp | 2 +- .../mut_call_from_get_resource.mvir | 66 +++++ .../mut_call_with_imm_ref_enum.exp | 10 + .../mut_call_with_imm_ref_enum.mvir | 33 +++ .../tests/type_safety/pack_enum_with_refs.exp | 82 ++++++ .../type_safety/pack_enum_with_refs.mvir | 89 ++++++ ...ck_generic_enum_invalid_type_arguments.exp | 73 +++++ ...k_generic_enum_invalid_type_arguments.mvir | 103 +++++++ .../pack_generic_enum_non_generically.exp | 10 + .../pack_generic_enum_non_generically.mvir | 11 + .../pack_non_generic_enum_generically.exp | 10 + .../pack_non_generic_enum_generically.mvir | 12 + .../bytecode_ops_abilities_bad.exp | 47 +++- .../bytecode_ops_abilities_bad.mvir | 74 ++++- .../bytecode_ops_abilities_ok.exp | 2 +- .../bytecode_ops_abilities_ok.mvir | 43 ++- .../constraints_abilities_bad.exp | 38 ++- .../constraints_abilities_bad.mvir | 78 ++++++ .../constraints_abilities_ok.exp | 2 +- .../constraints_abilities_ok.mvir | 44 +++ .../phantom_params/fields_abilities_bad.exp | 38 ++- .../phantom_params/fields_abilities_bad.mvir | 40 +++ .../phantom_params/fields_abilities_ok.exp | 2 +- .../phantom_params/fields_abilities_ok.mvir | 18 +- .../phantom_params/struct_definition_bad.exp | 56 +++- .../phantom_params/struct_definition_bad.mvir | 57 ++++ .../phantom_params/struct_definition_ok.exp | 2 +- .../phantom_params/struct_definition_ok.mvir | 62 ++++ .../tests/type_safety/ref_type_param.exp | 38 ++- .../tests/type_safety/ref_type_param.mvir | 45 +++ .../type_safety/ref_type_param_exploits.exp | 47 +++- .../type_safety/ref_type_param_exploits.mvir | 76 +++++ .../tests/type_safety/release.exp | 11 +- .../tests/type_safety/release.mvir | 11 + .../resource_instantiate_bad_type.exp | 11 +- .../resource_instantiate_bad_type.mvir | 14 + ...turn_type_mismatch_and_unused_resource.exp | 20 +- ...urn_type_mismatch_and_unused_resource.mvir | 27 ++ .../type_safety/struct_kind_inference.exp | 47 +++- .../type_safety/struct_kind_inference.mvir | 63 +++++ .../unpack_generic_enum_non_generically.exp | 82 ++++++ .../unpack_generic_enum_non_generically.mvir | 116 ++++++++ .../unpack_generic_enum_wrong_type_arg.exp | 82 ++++++ .../unpack_generic_enum_wrong_type_arg.mvir | 116 ++++++++ .../unpack_non_generic_enum_generically.exp | 82 ++++++ .../unpack_non_generic_enum_generically.mvir | 116 ++++++++ .../tests/type_safety/unpack_resource.exp | 2 +- .../tests/type_safety/unpack_resource.mvir | 52 ++++ .../tests/type_safety/unpack_wrong_type.exp | 11 +- .../tests/type_safety/unpack_wrong_type.mvir | 19 ++ .../type_safety/unrestricted_instantiate.exp | 2 +- .../type_safety/unrestricted_instantiate.mvir | 29 ++ .../unrestricted_instantiate_bad_type.exp | 11 +- .../unrestricted_instantiate_bad_type.mvir | 11 + .../type_safety/unused_resource_holder.exp | 11 +- .../type_safety/unused_resource_holder.mvir | 33 +++ .../variant_switch_invalid_head_type.exp | 91 ++++++ .../variant_switch_invalid_head_type.mvir | 173 ++++++++++++ .../variant_switch_partial_enum_switch.exp | 19 ++ .../variant_switch_partial_enum_switch.mvir | 43 +++ .../variant_switch_valid_head_type.exp | 1 + .../variant_switch_valid_head_type.mvir | 44 +++ .../tests/type_safety/vector_type_param.exp | 29 +- .../tests/type_safety/vector_type_param.mvir | 33 +++ .../declarations/function.exp | 8 + .../bytecode-generation/declarations/let.exp | 3 + .../expressions/binary_add.exp | 3 + .../expressions/borrow.exp | 15 + .../expressions/borrow_mut.exp | 9 + .../expressions/builtins/borrow_global.exp | 30 ++ .../builtins/borrow_global_mut.exp | 30 ++ .../expressions/builtins/exists.exp | 27 ++ .../expressions/builtins/move_to.exp | 33 +++ .../expressions/builtins/vector.exp | 23 +- .../expressions/combined.exp | 3 + .../bytecode-generation/expressions/pack.exp | 3 + .../expressions/unpack.exp | 4 + .../bytecode-generation/statements/assert.exp | 3 + .../bytecode-generation/statements/enums.exp | 107 +++++++ .../bytecode-generation/statements/enums.mvir | 71 +++++ .../bytecode-generation/statements/jump.exp | 6 + .../statements/jump_if.exp | 12 + .../statements/jump_if_false.exp | 12 + .../tests/parsing/comments.exp | 15 + .../tests/parsing/crlf.exp | 15 + .../tests/parsing/enums.exp | 4 + .../tests/parsing/enums.mvir | 6 + .../src/unit_tests/cfg_tests.rs | 228 +++++++++++++-- .../tests/vm_test_harness/print_bytecode.exp | 6 + .../move-vm-integration-tests/Cargo.toml | 1 + .../src/tests/compatibility_tests.rs | 265 ++++++++++++++++++ .../src/tests/instantiation_tests.rs | 31 +- .../src/tests/invariant_violation_tests.rs | 1 + .../src/tests/leak_tests.rs | 1 + .../src/tests/loader_tests.rs | 12 +- .../src/tests/mod.rs | 1 + .../enums/basic_poly_enum_type_mismatch.exp | 46 +++ .../enums/basic_poly_enum_type_mismatch.mvir | 49 ++++ .../tests/enums/enum_variant_mismatch.exp | 46 +++ .../tests/enums/enum_variant_mismatch.mvir | 61 ++++ .../enums/mono/enum_decl_monomorphic.exp | 46 +++ .../enums/mono/enum_decl_monomorphic.mvir | 79 ++++++ .../enum_decl_monomorphic_fail_unpack.exp | 13 + .../enum_decl_monomorphic_fail_unpack.mvir | 35 +++ ...m_decl_monomorphic_mismatched_variants.exp | 10 + ..._decl_monomorphic_mismatched_variants.mvir | 36 +++ .../tests/enums/mono/mut_ref_update.exp | 75 +++++ .../tests/enums/mono/mut_ref_update.mvir | 119 ++++++++ .../enums/mono/mut_ref_update_variant.exp | 47 ++++ .../enums/mono/mut_ref_update_variant.mvir | 84 ++++++ .../tests/enums/poly/basic_poly_enum.exp | 38 +++ .../tests/enums/poly/basic_poly_enum.mvir | 61 ++++ .../enum_decl_poly_mismatched_variants.exp | 10 + .../enum_decl_poly_mismatched_variants.mvir | 36 +++ ...um_decl_poly_mismatched_variants_types.exp | 0 .../tests/enums/poly/poly_mut_ref_update.exp | 75 +++++ .../tests/enums/poly/poly_mut_ref_update.mvir | 119 ++++++++ .../poly/poly_mut_ref_update_variant.exp | 47 ++++ .../poly/poly_mut_ref_update_variant.mvir | 84 ++++++ .../tests/enums/variant_switch_loop.exp | 41 +++ .../tests/enums/variant_switch_loop.mvir | 58 ++++ .../serializer_tests.proptest-regressions | 9 +- 273 files changed, 7847 insertions(+), 228 deletions(-) create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.mvir create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.exp create mode 100644 external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.mvir create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.exp create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.mvir create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.exp create mode 100644 external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.mvir create mode 100644 external-crates/move/crates/move-vm-integration-tests/src/tests/compatibility_tests.rs create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants_types.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.mvir create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.exp create mode 100644 external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.mvir diff --git a/external-crates/move/Cargo.lock b/external-crates/move/Cargo.lock index 861eac63b701d8..c4bc1acc072998 100644 --- a/external-crates/move/Cargo.lock +++ b/external-crates/move/Cargo.lock @@ -2246,6 +2246,7 @@ dependencies = [ "move-bytecode-verifier", "move-compiler", "move-core-types", + "move-ir-to-bytecode", "move-stdlib", "move-stdlib-natives", "move-vm-config", diff --git a/external-crates/move/crates/bytecode-verifier-prop-tests/src/unit_tests/prop_tests.rs b/external-crates/move/crates/bytecode-verifier-prop-tests/src/unit_tests/prop_tests.rs index 790c2b5654b5f4..2d799592a71070 100644 --- a/external-crates/move/crates/bytecode-verifier-prop-tests/src/unit_tests/prop_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-prop-tests/src/unit_tests/prop_tests.rs @@ -14,7 +14,7 @@ use move_binary_format::{ }; use move_bytecode_verifier::{ ability_field_requirements, constants, instantiation_loops::InstantiationLoopChecker, - DuplicationChecker, InstructionConsistency, RecursiveStructDefChecker, SignatureChecker, + DuplicationChecker, InstructionConsistency, RecursiveDataDefChecker, SignatureChecker, }; use move_core_types::{ account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, @@ -106,7 +106,7 @@ proptest! { InstructionConsistency::verify_module(&module).expect("InstructionConsistency failure"); constants::verify_module(&module).expect("constants failure"); ability_field_requirements::verify_module(&module).expect("ability_field_requirements failure"); - RecursiveStructDefChecker::verify_module(&module).expect("RecursiveStructDefChecker failure"); + RecursiveDataDefChecker::verify_module(&module).expect("RecursiveDataDefChecker failure"); InstantiationLoopChecker::verify_module(&module).expect("InstantiationLoopChecker failure"); } @@ -143,7 +143,7 @@ proptest! { #[test] fn valid_recursive_struct_defs(module in CompiledModule::valid_strategy(20)) { - prop_assert!(RecursiveStructDefChecker::verify_module(&module).is_ok()); + prop_assert!(RecursiveDataDefChecker::verify_module(&module).is_ok()); } } diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions index 6baf2ee61f189f..3945bd370c9d0f 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions @@ -4,7 +4,7 @@ # # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. -cc 2beb0a0e65962432af560e626fa109d269b07db8807968413425f0bb14bb3667 # shrinks to module = CompiledModule: { struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } -cc c14ae393a6eefae82c0f4ede2acaa0aa0e993c1bba3fe3e5958e6e31cb5d2957 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [] -cc 88615e15ef42d29405cd91d6d0a573ccbeb833d0c7471f718ee794bc5ba399ca # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 }, StructDefinition { struct_handle: 2, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [OutOfBoundsMutation { src_kind: StructDefinition, src_idx: Index(0), dst_kind: FieldDefinition, offset: 0 }] -cc a34039f5d57751762a6eacf3ca3a2857781fb0bd0af0b7a06a9427f896f29aa9 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x2, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [ BrTrue(1),] } },] type_signatures: [ TypeSignature(Unit), TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [] +cc 2beb0a0e65962432af560e626fa109d269b07db8807968413425f0bb14bb3667 # shrinks to module = CompiledModule: { datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } +cc c14ae393a6eefae82c0f4ede2acaa0aa0e993c1bba3fe3e5958e6e31cb5d2957 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [] +cc 88615e15ef42d29405cd91d6d0a573ccbeb833d0c7471f718ee794bc5ba399ca # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 }, StructDefinition { struct_handle: 2, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [OutOfBoundsMutation { src_kind: StructDefinition, src_idx: Index(0), dst_kind: FieldDefinition, offset: 0 }] +cc a34039f5d57751762a6eacf3ca3a2857781fb0bd0af0b7a06a9427f896f29aa9 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x2, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [ BrTrue(1),] } },] type_signatures: [ TypeSignature(Unit), TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [] diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs index 905bc6540ba44d..830154c1838698 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs @@ -63,7 +63,7 @@ fn invalid_struct_in_fn_return_() { let mut m = basic_test_module(); m.function_handles[0].return_ = SignatureIndex(1); m.signatures - .push(Signature(vec![Struct(StructHandleIndex::new(1))])); + .push(Signature(vec![Datatype(DatatypeHandleIndex::new(1))])); assert_eq!( BoundsChecker::verify_module(&m).unwrap_err().major_status(), StatusCode::INDEX_OUT_OF_BOUNDS @@ -94,7 +94,7 @@ fn invalid_struct_in_field() { let mut m = basic_test_module(); match &mut m.struct_defs[0].field_information { StructFieldInformation::Declared(ref mut fields) => { - fields[0].signature.0 = Struct(StructHandleIndex::new(3)); + fields[0].signature.0 = Datatype(DatatypeHandleIndex::new(3)); assert_eq!( BoundsChecker::verify_module(&m).unwrap_err().major_status(), StatusCode::INDEX_OUT_OF_BOUNDS @@ -111,8 +111,8 @@ fn invalid_struct_with_actuals_in_field() { let mut m = basic_test_module(); match &mut m.struct_defs[0].field_information { StructFieldInformation::Declared(ref mut fields) => { - fields[0].signature.0 = StructInstantiation(Box::new(( - StructHandleIndex::new(0), + fields[0].signature.0 = DatatypeInstantiation(Box::new(( + DatatypeHandleIndex::new(0), vec![TypeParameter(0)], ))); assert_eq!( @@ -167,7 +167,7 @@ fn invalid_struct_as_type_actual_in_exists() { let mut m = basic_test_module(); m.signatures - .push(Signature(vec![Struct(StructHandleIndex::new(3))])); + .push(Signature(vec![Datatype(DatatypeHandleIndex::new(3))])); m.function_instantiations.push(FunctionInstantiation { handle: FunctionHandleIndex::new(0), type_parameters: SignatureIndex::new(1), @@ -239,7 +239,7 @@ fn invalid_struct_for_vector_operation() { let mut skeleton = basic_test_module(); skeleton .signatures - .push(Signature(vec![Struct(StructHandleIndex::new(3))])); + .push(Signature(vec![Datatype(DatatypeHandleIndex::new(3))])); let sig_index = SignatureIndex((skeleton.signatures.len() - 1) as u16); for bytecode in [ VecPack(sig_index, 0), @@ -286,3 +286,77 @@ fn invalid_type_param_for_vector_operation() { ); } } + +#[test] +fn invalid_variant_handle_index_for_enum_operation() { + use Bytecode::*; + + let skeleton = basic_test_module(); + let variant_handle_index = VariantHandleIndex(skeleton.variant_handles.len() as u16); + let variant_handle_inst_index = + VariantInstantiationHandleIndex(skeleton.variant_instantiation_handles.len() as u16); + for bytecode in [ + PackVariant(variant_handle_index), + UnpackVariant(variant_handle_index), + UnpackVariantImmRef(variant_handle_index), + UnpackVariantMutRef(variant_handle_index), + PackVariantGeneric(variant_handle_inst_index), + UnpackVariantGeneric(variant_handle_inst_index), + UnpackVariantGenericImmRef(variant_handle_inst_index), + UnpackVariantGenericMutRef(variant_handle_inst_index), + ] { + let mut m = skeleton.clone(); + m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); + } +} + +#[test] +fn invalid_variant_jump_table_index() { + use Bytecode::*; + + let skeleton = basic_test_module(); + let jt_index = VariantJumpTableIndex( + skeleton.function_defs[0] + .code + .as_ref() + .map(|c| c.jump_tables.len() as u16) + .unwrap_or(0u16), + ); + let mut m = skeleton.clone(); + m.function_defs[0].code.as_mut().unwrap().code = vec![VariantSwitch(jt_index)]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_variant_jump_table_code_offset() { + use Bytecode::*; + + let mut skeleton = basic_test_module_with_enum(); + let enum_index = EnumDefinitionIndex(0); + skeleton.function_defs[0].code.as_mut().unwrap().code = vec![LdU64(0), Pop, Ret]; + skeleton.function_defs[0].code.as_mut().unwrap().jump_tables = vec![VariantJumpTable { + head_enum: enum_index, + jump_table: JumpTableInner::Full(vec![100]), + }]; + + let jt_index = VariantJumpTableIndex( + skeleton.function_defs[0] + .code + .as_ref() + .map(|c| c.jump_tables.len() as u16) + .unwrap_or(0u16), + ); + let mut m = skeleton.clone(); + m.function_defs[0].code.as_mut().unwrap().code = vec![VariantSwitch(jt_index)]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs index 653654119714d0..c3e43fb3b896b9 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs @@ -238,7 +238,7 @@ fn invalid_types() { // TODO cannot check structs are banned currently. This can be handled by IR and source lang // tests - // invalid_type(SignatureToken::Struct(StructHandleIndex(0)), vec![0]); + // invalid_type(SignatureToken::Datatype(DatatypeHandleIndex(0)), vec![0]); } fn tvec(s: SignatureToken) -> SignatureToken { diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs index da0d1fbeb6bb24..72a93d053717c4 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs @@ -16,3 +16,10 @@ fn duplicated_friend_decls() { m.friend_decls.push(handle); DuplicationChecker::verify_module(&m).unwrap_err(); } + +#[test] +fn duplicated_variant_handles() { + let mut m = basic_test_module_with_enum(); + m.variant_handles.push(m.variant_handles[0].clone()); + DuplicationChecker::verify_module(&m).unwrap_err(); +} diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs index 92ab3aa12cba58..aec9fdbe195490 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs @@ -36,33 +36,33 @@ fn make_module() -> CompiledModule { address_identifiers: vec![ AccountAddress::ZERO, // Module address ], - struct_handles: vec![ - StructHandle { + datatype_handles: vec![ + DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: AbilitySet::PRIMITIVES, type_parameters: vec![], }, - StructHandle { + DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(2), abilities: AbilitySet::PRIMITIVES, - type_parameters: vec![StructTypeParameter { + type_parameters: vec![DatatypeTyParameter { constraints: AbilitySet::PRIMITIVES, is_phantom: false, }], }, - StructHandle { + DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(3), abilities: AbilitySet::EMPTY | Ability::Key, type_parameters: vec![], }, - StructHandle { + DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), abilities: AbilitySet::EMPTY | Ability::Key, - type_parameters: vec![StructTypeParameter { + type_parameters: vec![DatatypeTyParameter { constraints: AbilitySet::PRIMITIVES, is_phantom: false, }], @@ -71,7 +71,7 @@ fn make_module() -> CompiledModule { struct_defs: vec![ // struct S { f: u64 } StructDefinition { - struct_handle: StructHandleIndex(0), + struct_handle: DatatypeHandleIndex(0), field_information: StructFieldInformation::Declared(vec![FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(SignatureToken::U64), @@ -79,7 +79,7 @@ fn make_module() -> CompiledModule { }, // struct GS { f: T } StructDefinition { - struct_handle: StructHandleIndex(1), + struct_handle: DatatypeHandleIndex(1), field_information: StructFieldInformation::Declared(vec![FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(SignatureToken::TypeParameter(0)), @@ -87,7 +87,7 @@ fn make_module() -> CompiledModule { }, // struct R has key { f: u64 } StructDefinition { - struct_handle: StructHandleIndex(2), + struct_handle: DatatypeHandleIndex(2), field_information: StructFieldInformation::Declared(vec![FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(SignatureToken::U64), @@ -95,7 +95,7 @@ fn make_module() -> CompiledModule { }, // struct GR has key { f: T } StructDefinition { - struct_handle: StructHandleIndex(3), + struct_handle: DatatypeHandleIndex(3), field_information: StructFieldInformation::Declared(vec![FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(SignatureToken::TypeParameter(0)), @@ -138,6 +138,7 @@ fn make_module() -> CompiledModule { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Ret], + jump_tables: vec![], }), }, // fun g_fn() { return; } @@ -149,6 +150,7 @@ fn make_module() -> CompiledModule { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Ret], + jump_tables: vec![], }), }, // fun test_fn() { ... } - tests will fill up the code @@ -160,6 +162,7 @@ fn make_module() -> CompiledModule { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![], + jump_tables: vec![], }), }, ], @@ -180,6 +183,10 @@ fn make_module() -> CompiledModule { struct_def_instantiations: vec![], function_instantiations: vec![], field_instantiations: vec![], + enum_defs: vec![], + enum_def_instantiations: vec![], + variant_handles: vec![], + variant_instantiation_handles: vec![], } } @@ -193,6 +200,7 @@ fn generic_call_to_non_generic_func() { Bytecode::CallGeneric(FunctionInstantiationIndex(0)), Bytecode::Ret, ], + jump_tables: vec![], }); module.function_instantiations.push(FunctionInstantiation { handle: FunctionHandleIndex(0), @@ -214,6 +222,7 @@ fn non_generic_call_to_generic_func() { module.function_defs[2].code = Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + jump_tables: vec![], }); let err = InstructionConsistency::verify_module(&module) .expect_err("Call to generic function must fail"); @@ -235,6 +244,7 @@ fn generic_pack_on_non_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module .struct_def_instantiations @@ -263,6 +273,7 @@ fn non_generic_pack_on_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); let err = InstructionConsistency::verify_module(&module) .expect_err("Pack to generic struct must fail"); @@ -285,6 +296,7 @@ fn generic_unpack_on_non_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module .struct_def_instantiations @@ -314,6 +326,7 @@ fn non_generic_unpack_on_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module .struct_def_instantiations @@ -343,6 +356,7 @@ fn generic_mut_borrow_field_on_non_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module.field_instantiations.push(FieldInstantiation { handle: FieldHandleIndex(0), @@ -374,6 +388,7 @@ fn non_generic_mut_borrow_field_on_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module .struct_def_instantiations @@ -407,6 +422,7 @@ fn generic_borrow_field_on_non_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module.field_instantiations.push(FieldInstantiation { handle: FieldHandleIndex(0), @@ -438,6 +454,7 @@ fn non_generic_borrow_field_on_generic_struct() { Bytecode::Pop, Bytecode::Ret, ], + jump_tables: vec![], }); module .struct_def_instantiations diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs index 70953906af9bde..23b8c452d89154 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs @@ -48,6 +48,7 @@ fn test_large_types() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -68,6 +69,7 @@ fn test_large_types() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -89,6 +91,7 @@ fn test_large_types() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -109,6 +112,7 @@ fn test_large_types() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Ret], + jump_tables: vec![], }), }); @@ -131,6 +135,7 @@ fn test_large_types() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![], + jump_tables: vec![], }), }); diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs index b30eaea22f91cf..e7eda3d0ed0842 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs @@ -38,11 +38,11 @@ fn test_function_handle_type_instantiation() { #[test] fn test_struct_handle_type_instantiation() { let mut m = basic_test_module(); - m.struct_handles.push(StructHandle { + m.datatype_handles.push(DatatypeHandle { module: ModuleHandleIndex::new(0), name: IdentifierIndex::new(0), abilities: AbilitySet::ALL, - type_parameters: std::iter::repeat(StructTypeParameter { + type_parameters: std::iter::repeat(DatatypeTyParameter { constraints: AbilitySet::ALL, is_phantom: false, }) @@ -97,7 +97,7 @@ fn big_vec_unpacks() { const N_TYPE_PARAMS: usize = 16; let mut st = SignatureToken::Vector(Box::new(SignatureToken::U8)); let type_params = vec![st; N_TYPE_PARAMS]; - st = SignatureToken::StructInstantiation(Box::new((StructHandleIndex(0), type_params))); + st = SignatureToken::DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), type_params))); const N_VEC_PUSH: u16 = 1000; let mut code = vec![]; // 1. CopyLoc: ... -> ... st @@ -115,7 +115,7 @@ fn big_vec_unpacks() { code.push(Bytecode::Pop); } code.push(Bytecode::Ret); - let type_param_constraints = StructTypeParameter { + let type_param_constraints = DatatypeTyParameter { constraints: AbilitySet::EMPTY, is_phantom: false, }; @@ -126,7 +126,7 @@ fn big_vec_unpacks() { address: AddressIdentifierIndex(0), name: IdentifierIndex(0), }], - struct_handles: vec![StructHandle { + datatype_handles: vec![DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: AbilitySet::ALL, @@ -153,7 +153,7 @@ fn big_vec_unpacks() { constant_pool: vec![], metadata: vec![], struct_defs: vec![StructDefinition { - struct_handle: StructHandleIndex(0), + struct_handle: DatatypeHandleIndex(0), field_information: StructFieldInformation::Native, }], function_defs: vec![FunctionDefinition { @@ -164,8 +164,13 @@ fn big_vec_unpacks() { code: Some(CodeUnit { locals: SignatureIndex(0), code, + jump_tables: vec![], }), }], + enum_defs: vec![], + enum_def_instantiations: vec![], + variant_handles: vec![], + variant_instantiation_handles: vec![], }; // save module and verify that it can ser/de @@ -199,7 +204,7 @@ const MAX_FUNCTIONS: usize = 1000; #[test] fn max_struct_test() { let config = VerifierConfig { - max_struct_definitions: Some(MAX_STRUCTS), + max_data_definitions: Some(MAX_STRUCTS), max_fields_in_struct: Some(MAX_FIELDS), max_function_definitions: Some(MAX_FUNCTIONS), ..Default::default() @@ -238,7 +243,7 @@ fn max_struct_test() { #[test] fn max_fields_test() { let config = VerifierConfig { - max_struct_definitions: Some(MAX_STRUCTS), + max_data_definitions: Some(MAX_STRUCTS), max_fields_in_struct: Some(MAX_FIELDS), max_function_definitions: Some(MAX_FUNCTIONS), ..Default::default() @@ -303,7 +308,7 @@ fn max_fields_test() { #[test] fn max_functions_test() { let config = VerifierConfig { - max_struct_definitions: Some(MAX_STRUCTS), + max_data_definitions: Some(MAX_STRUCTS), max_fields_in_struct: Some(MAX_FIELDS), max_function_definitions: Some(MAX_FUNCTIONS), ..Default::default() @@ -348,7 +353,7 @@ fn max_functions_test() { #[test] fn max_mixed_config_test() { let config = VerifierConfig { - max_struct_definitions: Some(MAX_STRUCTS), + max_data_definitions: Some(MAX_STRUCTS), max_fields_in_struct: Some(MAX_FIELDS), max_function_definitions: Some(MAX_FUNCTIONS), ..Default::default() @@ -362,7 +367,7 @@ fn max_mixed_config_test() { let config = VerifierConfig { max_function_definitions: None, - max_struct_definitions: None, + max_data_definitions: None, max_fields_in_struct: None, ..Default::default() }; @@ -392,7 +397,7 @@ fn max_mixed_config_test() { assert_eq!(res, Ok(())); let config = VerifierConfig { - max_struct_definitions: Some(MAX_STRUCTS), + max_data_definitions: Some(MAX_STRUCTS), max_fields_in_struct: Some(MAX_FIELDS), ..Default::default() }; @@ -434,7 +439,7 @@ fn max_mixed_config_test() { ); let config = VerifierConfig { - max_struct_definitions: Some(MAX_STRUCTS), + max_data_definitions: Some(MAX_STRUCTS), max_function_definitions: Some(MAX_FUNCTIONS), ..Default::default() }; @@ -739,14 +744,14 @@ fn multi_struct(module: &mut CompiledModule, count: usize) { module .identifiers .push(Identifier::new(format!("A_{}", i)).unwrap()); - module.struct_handles.push(StructHandle { + module.datatype_handles.push(DatatypeHandle { module: module.self_module_handle_idx, name: IdentifierIndex((module.identifiers.len() - 1) as u16), abilities: AbilitySet::EMPTY, type_parameters: vec![], }); module.struct_defs.push(StructDefinition { - struct_handle: StructHandleIndex((module.struct_handles.len() - 1) as u16), + struct_handle: DatatypeHandleIndex((module.datatype_handles.len() - 1) as u16), field_information: StructFieldInformation::Declared(vec![]), }); } @@ -806,6 +811,7 @@ fn multi_functions(module: &mut CompiledModule, count: usize) { code: Some(CodeUnit { locals: SignatureIndex((module.signatures.len() - 1) as u16), code: vec![Bytecode::Ret], + jump_tables: vec![], }), }); } diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs index 6451e165a72324..c4e5a51558fe17 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs @@ -35,6 +35,7 @@ fn test_locals() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Ret], + jump_tables: vec![], }), }); @@ -67,6 +68,7 @@ fn test_locals() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::LdTrue, Bytecode::LdU8(0), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -89,6 +91,7 @@ fn test_locals() { code: Some(CodeUnit { locals: SignatureIndex(1), code: vec![], + jump_tables: vec![], }), }); diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs index 4cc1a8c16c0491..0bfba81b9f36f8 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs @@ -24,13 +24,16 @@ macro_rules! assert_node { fn linear_summary() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ Nop, - /* */ Branch(2), - /* B2, L1 */ Nop, - /* */ Branch(4), - /* B4, L2 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ Nop, + /* */ Branch(2), + /* B2, L1 */ Nop, + /* */ Branch(4), + /* B4, L2 */ Ret, + ], + &[], + )) }; let n: Vec<_> = summary.preorder().collect(); @@ -66,12 +69,15 @@ fn linear_summary() { fn non_loop_back_branch_summary() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ Nop, - /* */ Branch(3), - /* B2, L2 */ Ret, - /* B3, L1 */ Branch(2), - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ Nop, + /* */ Branch(3), + /* B2, L2 */ Ret, + /* B3, L1 */ Branch(2), + ], + &[], + )) }; let n: Vec<_> = summary.preorder().collect(); @@ -107,12 +113,15 @@ fn non_loop_back_branch_summary() { fn branching_summary() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ LdTrue, - /* */ BrTrue(3), - /* B2, L2 */ Nop, - /* B3, L1 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(3), + /* B2, L2 */ Nop, + /* B3, L1 */ Ret, + ], + &[], + )) }; let n: Vec<_> = summary.preorder().collect(); @@ -152,13 +161,16 @@ fn branching_summary() { fn looping_summary() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ LdTrue, - /* */ BrTrue(4), - /* B2, L2 */ Nop, - /* */ Branch(0), - /* B4, L1 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(4), + /* B2, L2 */ Nop, + /* */ Branch(0), + /* B4, L1 */ Ret, + ], + &[], + )) }; let n: Vec<_> = summary.preorder().collect(); @@ -194,14 +206,17 @@ fn looping_summary() { fn branches_in_loops_summary() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ LdTrue, - /* */ BrTrue(3), - /* B2, L3 */ Nop, - /* B3, L1 */ LdFalse, - /* */ BrFalse(0), - /* B5, L2 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(3), + /* B2, L3 */ Nop, + /* B3, L1 */ LdFalse, + /* */ BrFalse(0), + /* B5, L2 */ Ret, + ], + &[], + )) }; let n: Vec<_> = summary.preorder().collect(); @@ -245,22 +260,25 @@ fn branches_in_loops_summary() { fn loops_in_branches_summary() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ LdTrue, - /* */ BrTrue(8), - /* B2, L5 */ Nop, - /* B3, L6 */ LdFalse, - /* */ BrFalse(3), - /* B5, L7 */ LdTrue, - /* */ BrTrue(2), - /* B7, L8 */ Branch(13), - /* B8, L1 */ Nop, - /* B9, L2 */ LdTrue, - /* */ BrTrue(8), - /* B11, L3 */ LdFalse, - /* */ BrFalse(9), - /* B13, L4 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(8), + /* B2, L5 */ Nop, + /* B3, L6 */ LdFalse, + /* */ BrFalse(3), + /* B5, L7 */ LdTrue, + /* */ BrTrue(2), + /* B7, L8 */ Branch(13), + /* B8, L1 */ Nop, + /* B9, L2 */ LdTrue, + /* */ BrTrue(8), + /* B11, L3 */ LdFalse, + /* */ BrFalse(9), + /* B13, L4 */ Ret, + ], + &[], + )) }; let n: Vec<_> = summary.preorder().collect(); @@ -344,13 +362,16 @@ fn loops_in_branches_summary() { fn loop_collapsing() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ LdTrue, - /* */ BrTrue(4), - /* B2, L2 */ Nop, - /* */ Branch(0), - /* B4, L1 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(4), + /* B2, L2 */ Nop, + /* */ Branch(0), + /* B4, L1 */ Ret, + ], + &[], + )) }; let mut partition = LoopPartition::new(&summary); @@ -370,16 +391,19 @@ fn loop_collapsing() { fn nested_loop_collapsing() { let summary = { use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new(&[ - /* B0, L0 */ Nop, - /* B1, L1 */ LdTrue, - /* */ BrTrue(1), - /* B3, L2 */ LdFalse, - /* */ BrFalse(0), - /* B5, L3 */ LdTrue, - /* */ BrTrue(0), - /* B7, L4 */ Ret, - ])) + LoopSummary::new(&VMControlFlowGraph::new( + &[ + /* B0, L0 */ Nop, + /* B1, L1 */ LdTrue, + /* */ BrTrue(1), + /* B3, L2 */ LdFalse, + /* */ BrFalse(0), + /* B5, L3 */ LdTrue, + /* */ BrTrue(0), + /* B7, L4 */ Ret, + ], + &[], + )) }; let mut partition = LoopPartition::new(&summary); diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs index fe527fcbdf0f5c..feda780b5cf935 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs @@ -46,6 +46,7 @@ fn many_backedges() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::LdTrue, Bytecode::LdU8(0), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -68,6 +69,7 @@ fn many_backedges() { code: Some(CodeUnit { locals: SignatureIndex(1), code: vec![], + jump_tables: vec![], }), }); diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs index 9c7cb692c024cf..17676ad1fe5573 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs @@ -5,6 +5,7 @@ use move_binary_format::file_format_common::VERSION_MAX; use move_vm_config::verifier::{ MeterConfig, VerifierConfig, DEFAULT_MAX_CONSTANT_VECTOR_LEN, DEFAULT_MAX_IDENTIFIER_LENGTH, + DEFAULT_MAX_VARIANTS, }; pub mod binary_samples; @@ -37,7 +38,7 @@ pub(crate) fn production_config() -> (VerifierConfig, MeterConfig) { max_type_nodes: Some(256), max_push_size: Some(10000), max_dependency_depth: Some(100), - max_struct_definitions: Some(200), + max_data_definitions: Some(200), max_fields_in_struct: Some(30), max_function_definitions: Some(1000), @@ -50,6 +51,7 @@ pub(crate) fn production_config() -> (VerifierConfig, MeterConfig) { allow_receiving_object_id: true, reject_mutable_random_on_entry_functions: true, bytecode_version: VERSION_MAX, + max_variants_in_enum: Some(DEFAULT_MAX_VARIANTS), }, MeterConfig::default(), ) diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs index 2fff034c142afd..567364efe296c8 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs @@ -35,6 +35,7 @@ fn test_bicliques() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -61,6 +62,7 @@ fn test_bicliques() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![], + jump_tables: vec![], }), }); let code = &mut m.function_defs[1].code.as_mut().unwrap().code; @@ -87,6 +89,7 @@ fn test_bicliques() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Ret], + jump_tables: vec![], }), }); @@ -109,6 +112,7 @@ fn test_bicliques() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![], + jump_tables: vec![], }), }); let code = &mut m.function_defs[i as usize + 2].code.as_mut().unwrap().code; @@ -160,6 +164,7 @@ fn test_merge_state_large_graph() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -185,6 +190,7 @@ fn test_merge_state_large_graph() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -205,6 +211,7 @@ fn test_merge_state_large_graph() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -226,6 +233,7 @@ fn test_merge_state_large_graph() { code: Some(CodeUnit { locals: SignatureIndex(1), code: vec![], + jump_tables: vec![], }), }); let code = &mut m.function_defs[i as usize + 3].code.as_mut().unwrap().code; @@ -282,6 +290,7 @@ fn test_merge_state() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + jump_tables: vec![], }), }); @@ -313,6 +322,7 @@ fn test_merge_state() { code: Some(CodeUnit { locals: SignatureIndex(2), code: vec![], + jump_tables: vec![], }), }); let code = &mut m.function_defs[i as usize + 1].code.as_mut().unwrap().code; @@ -395,6 +405,7 @@ fn test_copyloc_pop() { code: Some(CodeUnit { locals: SignatureIndex(2), code: vec![], + jump_tables: vec![], }), }); let code = &mut m.function_defs[i as usize].code.as_mut().unwrap().code; diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs index 41d2d4e5410819..ad7b496b0a23f0 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs @@ -33,7 +33,7 @@ fn no_verify_locals_good() { name: IdentifierIndex(0), }], self_module_handle_idx: ModuleHandleIndex(0), - struct_handles: vec![], + datatype_handles: vec![], signatures: vec![ Signature(vec![Address]), Signature(vec![U64]), @@ -78,6 +78,7 @@ fn no_verify_locals_good() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![Ret], + jump_tables: vec![], }), }, FunctionDefinition { @@ -88,9 +89,14 @@ fn no_verify_locals_good() { code: Some(CodeUnit { locals: SignatureIndex(1), code: vec![Ret], + jump_tables: vec![], }), }, ], + enum_defs: vec![], + enum_def_instantiations: vec![], + variant_handles: vec![], + variant_instantiation_handles: vec![], }; assert!(verify_module_unmetered(&compiled_module_good).is_ok()); } @@ -106,7 +112,7 @@ fn big_signature_test() { } for _ in 0..INSTANTIATION_DEPTH { let type_params = vec![st; N_TYPE_PARAMS]; - st = SignatureToken::StructInstantiation(Box::new((StructHandleIndex(0), type_params))); + st = SignatureToken::DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), type_params))); } const N_READPOP: u16 = 7500; @@ -122,7 +128,7 @@ fn big_signature_test() { } code.push(Bytecode::Ret); - let type_param_constraints = StructTypeParameter { + let type_param_constraints = DatatypeTyParameter { constraints: AbilitySet::EMPTY, is_phantom: false, }; @@ -134,7 +140,7 @@ fn big_signature_test() { address: AddressIdentifierIndex(0), name: IdentifierIndex(0), }], - struct_handles: vec![StructHandle { + datatype_handles: vec![DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: AbilitySet::ALL, @@ -161,7 +167,7 @@ fn big_signature_test() { constant_pool: vec![], metadata: vec![], struct_defs: vec![StructDefinition { - struct_handle: StructHandleIndex(0), + struct_handle: DatatypeHandleIndex(0), field_information: StructFieldInformation::Native, }], function_defs: vec![FunctionDefinition { @@ -172,8 +178,13 @@ fn big_signature_test() { code: Some(CodeUnit { locals: SignatureIndex(0), code, + jump_tables: vec![], }), }], + enum_def_instantiations: vec![], + enum_defs: vec![], + variant_handles: vec![], + variant_instantiation_handles: vec![], }; // save module and verify that it can ser/de diff --git a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs index 540962b3cbb245..96667cee33f04d 100644 --- a/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs +++ b/external-crates/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs @@ -32,6 +32,7 @@ fn test_vec_pack() { code: Some(CodeUnit { locals: SignatureIndex(0), code: vec![], + jump_tables: vec![], }), }); diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.mvir new file mode 100644 index 00000000000000..de40c69d44526f --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_enum_has_resource_field.mvir @@ -0,0 +1,5 @@ +//# publish +module 0x42.Test { + struct All has key, store, copy, drop { b: bool } + enum T { V { f: Self.All } } // can drop abilities +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.exp new file mode 100644 index 00000000000000..5e99c309ea853f --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.exp @@ -0,0 +1,28 @@ +processed 3 tasks + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x42::Test, + indices: [(EnumDefinition, 0), (VariantTag, 1), (FieldDefinition, 0)], + offsets: [], +} + +task 1 'publish'. lines 15-27: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x42::Test, + indices: [(EnumDefinition, 0), (VariantTag, 1), (FieldDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 29-39: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x42::Test, + indices: [(StructDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.mvir new file mode 100644 index 00000000000000..e11b3506caaab8 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_enum_has_resource_field.mvir @@ -0,0 +1,39 @@ +//# publish +module 0x42.Test { +import 0x1.XUS; + struct Coin has store { value: u64 } + enum T has copy, drop { + V0 { }, + V1 { + // does not have copy or drop + fc: Self.Coin, + fint: u64, + }, + } +} + +//# publish +module 0x42.Test { +import 0x1.XUS; + enum T has copy, drop { + V0 { }, + V1 { + // does not have copy or drop + fc: Self.Coin, + fint: u64, + }, + } + enum Coin has store { V { value: u64 } } +} + +//# publish +module 0x42.Test { +import 0x1.XUS; + struct T has copy, drop { + // does not have copy or drop + fc: Self.Coin, + fint: u64, + } + + enum Coin has store { V { value: u64 } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.exp new file mode 100644 index 00000000000000..6f873d8ae353d2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.mvir new file mode 100644 index 00000000000000..02e169fe91cb15 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals_enum.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + enum S { V{ b: bool } } + + foo() { + // missing type arg + let x: Self.S<>; + label b0: + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.exp new file mode 100644 index 00000000000000..6f873d8ae353d2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.mvir new file mode 100644 index 00000000000000..0672e3cda17b15 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals_enum.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + enum S { V { b: bool } } + + foo() { + // type arg mismatch + let x: Self.S; + label b0: + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.exp new file mode 100644 index 00000000000000..97c3bde1807574 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x42::M, + indices: [(EnumDefinition, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.mvir new file mode 100644 index 00000000000000..6008de53ea5029 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_and_struct_names.mvir @@ -0,0 +1,6 @@ +//# publish +module 0x42.M { + // duplicate structs and enums + struct T{b: bool} + enum T{ V{ x: u64 } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.exp new file mode 100644 index 00000000000000..97c3bde1807574 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x42::M, + indices: [(EnumDefinition, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.mvir new file mode 100644 index 00000000000000..31043b06dda9de --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_enum_name.mvir @@ -0,0 +1,7 @@ +//# publish +module 0x42.M { + // duplicate enums + enum T{ V{ b: bool} } + enum T{ V{ x: u64} } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.exp new file mode 100644 index 00000000000000..5771c52239300a --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-7: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x1::M, + indices: [(FieldDefinition, 1), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.mvir new file mode 100644 index 00000000000000..213c0909e64183 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name_enum.mvir @@ -0,0 +1,7 @@ +//# publish +module 0x1.M { + // duplicate field of the same name + enum T{ V { f: u64, f: u64 } } +} + +// check: DUPLICATE_ELEMENT diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.exp new file mode 100644 index 00000000000000..36c193b22e1e14 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x1::M, + indices: [(EnumDefinition, 0), (VariantTag, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.mvir new file mode 100644 index 00000000000000..dbb2d850d28d9b --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_variant_name.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x1.M { + // duplicate variant of the same name + enum T { + V { }, + V { f: u64, f: u64 } + } +} + +// check: DUPLICATE_ELEMENT diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.exp new file mode 100644 index 00000000000000..ca5fe731b46932 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::EmptyStruct'. Got VMError: { + major_status: MALFORMED, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.mvir new file mode 100644 index 00000000000000..9374fe60ce7506 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_enums.mvir @@ -0,0 +1,7 @@ +//# publish +module 0x1.EmptyStruct { + // no empty enums allowed + enum Empty { } + +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.exp new file mode 100644 index 00000000000000..85a33c64606fd1 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::PolymorphicEnums'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::PolymorphicEnums, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 13)], +} + +task 1 'publish'. lines 27-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::MonomorphicEnums'. Got VMError: { + major_status: MOVELOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x2::MonomorphicEnums, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 12)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.mvir new file mode 100644 index 00000000000000..5649d709618433 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch.mvir @@ -0,0 +1,51 @@ +//# publish +module 0x1.PolymorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: T } + } + + public f(t: T, e: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return move(e); + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + // `e` is not handled here so, unused value without drop error should be reported + return move(y); + } +} + +//# publish +module 0x2.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + public f(): u64 { + let x: Self.EnumWithTwoVariants; + let y: u64; + label b0: + x = EnumWithTwoVariants.Two { x: 42 }; + variant_switch EnumWithTwoVariants (&x) { + One : b2, + Two : b1, + }; + label b1: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + label b2: + EnumWithTwoVariants.One { } = move(x); + // `y` is not assigned in this branch so we should report a move loc unavailable error + return move(y); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.exp new file mode 100644 index 00000000000000..38fb31af816e4a --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.mvir new file mode 100644 index 00000000000000..69beecdc39fded --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_successor.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x42.m { + enum X { A { }, B { } } + + foo(x: Self.X) { + label b0: + variant_switch X (&x) { + A : b1, + B : b2, + }; + label b1: + X.A { } = move(x); + jump b3; + label b2: + // Fail to unpack `x` here so should result in an unused value with drop error + label b3: + return ; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.mvir new file mode 100644 index 00000000000000..1535b76aa59940 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/variant_switch_unconditional_branch.mvir @@ -0,0 +1,29 @@ +//# publish +module 0x42.m { + enum X { V1 { x: u64 }, V2 { } } + + entry foo(x: Self.X) { + let y: u64; + label bv: + variant_switch X (&x) { + V1 : b0, + V2 : b4, + }; + // This block is unreachable since `variant_switch` is an unconditional jump. + // If `variant_switch` is a conditional jump, then this block is reachable, and would + // raise an unused value without drop error. But, since we guarantee exhaustiveness, we + // are guaranteed that we cannot fall through here and so this block is unreachable. + label fallthrough: + return; + label b0: + X.V1 { x: y } = move(x); + jump_if (move(y) > 42) b3; + label b1: + return; + label b3: + return; + label b4: + X.V2 {} = move(x); + abort 0; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.mvir new file mode 100644 index 00000000000000..b7f900c2236772 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match.mvir @@ -0,0 +1,39 @@ +//# publish +module 0x42.m { + + enum Threes has { + One { pos0: T } , + Two{}, + Three { pos0: T } + } + + t0(): u64 { + let loc3: u64; + let loc1: Self.Threes; + let inner: u64; + let copier: u64; + label l0: + loc1 = Threes.Three{pos0: 0}; + + variant_switch Threes (&loc1) { + One : l1, + Two : l2, + Three : l3 + }; + label l1: + Threes.One{pos0: copier } = move(loc1); + loc3 = 1u64; + jump l4; + label l2: + Threes.Two{ } = move(loc1); + loc3 = 1u64; + jump l4; + label l3: + Threes.Three{pos0: inner} = move(loc1); + copier = copy(inner); + loc3 = copy(copier); + jump l4; + label l4: + return move(loc3); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.exp new file mode 100644 index 00000000000000..a456a27bea8cbc --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INVALID_ENUM_SWITCH, + sub_status: None, + location: undefined, + indices: [(VariantTag, 2)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.mvir new file mode 100644 index 00000000000000..8316cfc9c8cd0c --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/enum_match_out_of_bounds.mvir @@ -0,0 +1,39 @@ +//# publish +module 0x42.m { + + enum Threes has { + One { pos0: T } , + Two{}, + Three { pos0: T } + } + + t0(): u64 { + let loc3: u64; + let loc1: Self.Threes; + let inner: u64; + let copier: u64; + label l0: + loc1 = Threes.Three{pos0: 0}; + + variant_switch Threes (&loc1) { + One : l1, + Two : l2, + }; + label l1: + Threes.One{pos0: copier } = move(loc1); + loc3 = 1u64; + jump l4; + label l2: + Threes.Two{ } = move(loc1); + loc3 = 1u64; + jump l4; + label l3: + Threes.Three{pos0: inner} = move(loc1); + copier = copy(inner); + loc3 = copy(copier); + jump l4; + label l4: + return move(loc3); + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.exp new file mode 100644 index 00000000000000..5d92c423f3fd86 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.mvir new file mode 100644 index 00000000000000..69b127ece26d96 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_shared_name.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x42.M { + enum M has drop { V { } } + public new(): Self.M { + label b0: + return M.V { }; + } +} + +//# run + +module 0x43.m { +import 0x42.M; + +entry foo() { + let x: M.M; +label b0: + x = M.new(); + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.exp new file mode 100644 index 00000000000000..4ff3c0403265f6 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-5: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x42::m, + indices: [(EnumDefinition, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.mvir new file mode 100644 index 00000000000000..f1fa84ea37f9a2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/module_enum_struct_shared_name.mvir @@ -0,0 +1,5 @@ +//# publish +module 0x42.m { + struct X { x: bool } + enum X { V { x: bool } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.exp new file mode 100644 index 00000000000000..25c763799d4d79 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: RECURSIVE_DATATYPE_DEFINITION, + sub_status: None, + location: 0x42::M, + indices: [(EnumDefinition, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.mvir new file mode 100644 index 00000000000000..64d85bc2d38331 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/mutual_recursive_enum.mvir @@ -0,0 +1,6 @@ +//# publish +module 0x42.M { + // cannot have mutually recursive enums + enum A{ V { b: Self.B } } + enum B{ V { a: Self.A } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.exp new file mode 100644 index 00000000000000..44d0918b6ab2d4 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.exp @@ -0,0 +1,46 @@ +processed 6 tasks + +task 1 'publish'. lines 10-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M0'. Got VMError: { + major_status: RECURSIVE_DATATYPE_DEFINITION, + sub_status: None, + location: 0x1::M0, + indices: [(EnumDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 16-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { + major_status: RECURSIVE_DATATYPE_DEFINITION, + sub_status: None, + location: 0x1::M1, + indices: [(EnumDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 30-36: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: RECURSIVE_DATATYPE_DEFINITION, + sub_status: None, + location: 0x1::M2, + indices: [(EnumDefinition, 1)], + offsets: [], +} + +task 4 'publish'. lines 38-45: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: RECURSIVE_DATATYPE_DEFINITION, + sub_status: None, + location: 0x1::M3, + indices: [(EnumDefinition, 0)], + offsets: [], +} + +task 5 'publish'. lines 47-56: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: RECURSIVE_DATATYPE_DEFINITION, + sub_status: None, + location: 0x1::M3, + indices: [(EnumDefinition, 3)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.mvir new file mode 100644 index 00000000000000..5302408391dc03 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/recursive_enum.mvir @@ -0,0 +1,56 @@ +//# publish +module 0x1.Cup { + enum Cup { V { f: T } } + public cup(f: T): Self.Cup { + label b0: + return Cup.V { f: move(f) }; + } +} + +//# publish +module 0x1.M0 { + // recursive enum + enum Foo { V { f: Self.Foo } } +} + +//# publish +module 0x1.M1 { + import 0x1.Cup; + // recursive enum + enum Foo { V { f: Cup.Cup } } + + // would blow up the stack + public foo(): Self.Foo { + label b0: + return Foo.V { f: Cup.cup(Self.foo()) }; + } + +} + +//# publish +module 0x1.M2 { + import 0x1.signer; + + enum X { V { y: vector } } + enum Y { V { x: vector } } +} + +//# publish +module 0x1.M3 { + import 0x1.Cup; + + // recursive enum + enum Foo { V { f: Cup.Cup } } + +} + +//# publish +module 0x1.M3 { + import 0x1.Cup; + + // indirect recursive enum + enum A { V { b: Self.B } } + enum B { V { c: Self.C } } + enum C { V { d: vector } } + enum D { V { x: Cup.Cup>> } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.exp new file mode 100644 index 00000000000000..2f6da114fb5755 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-4: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M1, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 1 'publish'. lines 6-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M2, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 11-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M3, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 16-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M4, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.mvir new file mode 100644 index 00000000000000..57603abb5c2381 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/enum_defs/ref_in_enum.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x42.M1 { + enum S { V { x: &u64 } } +} + +//# publish +module 0x42.M2 { + enum S { V { x: &mut u64 } } +} + +//# publish +module 0x42.M3 { + enum S { V { t: &T } } +} + +//# publish +module 0x42.M4 { + enum S { V { t: &mut T } } +} 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 new file mode 100644 index 00000000000000..88822b962886ea --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.exp @@ -0,0 +1,28 @@ +processed 3 tasks + +task 0 'publish'. lines 1-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} + +task 1 'publish'. lines 53-70: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M2, + indices: [], + offsets: [], +} + +task 2 'publish'. lines 72-122: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..48c02eeb5a308b --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1_enum.mvir @@ -0,0 +1,123 @@ +//# publish +module 0x1.M { + enum S { V{ b: bool } } + + a() { + label b0: + Self.b, u64>(); + return; + } + + b() { + label b0: + Self.f(); + Self.c, bool>(); + return; + } + + c() { + label b0: + Self.c(); + Self.d(); + Self.e(); + return; + } + + d() { + label b0: + Self.b(); + return; + } + + e() { + label b0: + return; + } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f>(); + return; + } +} +// There are two disjoint loops in the resulting graph, but only one error +// loop: f#T --> g#T --S--> f#T +// loop: c#T1 --> c#T2 --> d#T --> b#T2 --S--> c#T1 + +//# publish +module 0x1.M2 { + enum S { V { b: bool } } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f>(); + return; + } +} +// loop: f#T --> g#T --S--> f#T +// check: LOOP_IN_INSTANTIATION_GRAPH + +//# publish + +module 0x1.M3 { + enum S { V{ b: bool } } + + a() { + label b0: + Self.b, u64>(); + return; + } + + b() { + label b0: + Self.f(); + Self.c, bool>(); + return; + } + + c() { + label b0: + Self.c(); + Self.d(); + Self.e(); + return; + } + + d() { + label b0: + Self.b(); + return; + } + + e() { + label b0: + return; + } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + // Switched to just to isolate the loop + Self.f(); + return; + } +} +// loop: c#T1 --> c#T2 --> d#T --> b#T2 --S--> c#T1 + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.exp @@ -0,0 +1 @@ +processed 1 task 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 new file mode 100644 index 00000000000000..7047b775fde225 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok_enum.mvir @@ -0,0 +1,16 @@ +//# publish +module 0x1.M { + enum S { V{ b: bool } } + + f() { + label b0: + Self.g>(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.mvir new file mode 100644 index 00000000000000..83c2d5830e489c --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok_enum.mvir @@ -0,0 +1,24 @@ +//# publish +module 0x1.M { + enum S { V { b: bool } } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.h>(); + return; + } + + h() { + label b0: + // The bool breaks the chain. + Self.f(); + return; + } +} + 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 new file mode 100644 index 00000000000000..3b9f372dec8271 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..94016c7ddefad6 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting_enum.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + enum S { V{ b: bool } } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + // indirect loop (takes a while) + Self.h>(); + return; + } + + h() { + label b0: + Self.f(); + return; + } +} 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 new file mode 100644 index 00000000000000..6457e989da40ed --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..37bbd0a6a9a658 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con_enum.mvir @@ -0,0 +1,17 @@ +//# publish +module 0x1.M { + enum S { V { b: bool } } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + // indirect loop with swap + Self.f>(); + return; + } +} 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 new file mode 100644 index 00000000000000..e68aa0a009bca3 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..5630abc40ab0aa --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con_enum.mvir @@ -0,0 +1,20 @@ +//# publish + +// Not good: infinitely many types/instances. +// f, g>, f>, g>>, ... + +module 0x1.M { + enum S { V { b: bool } } + + f() { + label b0: + Self.g>(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} 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 new file mode 100644 index 00000000000000..011ac8091e033b --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..5c2ae8ba244fe8 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1_enum.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + enum S { V { b: bool }, R { } } + + foo() { + label b0: + // loop + Self.foo>>(); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.exp new file mode 100644 index 00000000000000..e7a1ab8d9a1103 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.mvir new file mode 100644 index 00000000000000..be3bb842838957 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum.mvir @@ -0,0 +1,13 @@ +//# publish + +module 0x1.M { + enum S { V{ b: bool } } + enum R { V{ b: bool } } + + foo() { + label b0: + // instantiation loop + Self.foo>>>(); + return; + } +} 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 new file mode 100644 index 00000000000000..e7a1ab8d9a1103 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..3de1969878886f --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2_enum_struct.mvir @@ -0,0 +1,13 @@ +//# publish + +module 0x1.M { + struct S { b: bool } + enum R { V{ b: bool } } + + foo() { + label b0: + // instantiation loop + Self.foo>>>(); + return; + } +} 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 new file mode 100644 index 00000000000000..e7a1ab8d9a1103 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..1c8c5e8a77e44c --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con_enum.mvir @@ -0,0 +1,14 @@ +//# publish + +// Bad! Can have infinitely many instances: f, f>, f>>, ... + +module 0x1.M { + enum S { V{ b: bool } } + + f(x: T) { + label b0: + Self.f>(S.V { b: true }); + return; + } +} + 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 new file mode 100644 index 00000000000000..2d87672574bf7f --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..562d14461a04e9 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con_enum.mvir @@ -0,0 +1,15 @@ +//# publish + +// Similar to the case with one argument, but swaps the two type parameters. +// f => f, T1> => f, S> => f>, S> => ... + +module 0x1.M { + enum S { V{ x: T } } + + f(a: T1, b: T2) { + label b0: + Self.f, T1>(S.V { x: move(b) }, move(a)); + return; + } +} + 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 new file mode 100644 index 00000000000000..e68aa0a009bca3 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..dd3e44bdb88721 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops_enum.mvir @@ -0,0 +1,20 @@ +//# publish + +// Two loops in the resulting graph. +// One error for the loop. + +module 0x1.M { + enum S { V { b: bool } } + + f() { + label b0: + Self.f>(); + return; + } + + g() { + label b0: + Self.g>(); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.exp new file mode 100644 index 00000000000000..ac7fb92c935c22 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.exp @@ -0,0 +1,19 @@ +processed 3 tasks + +task 1 'run'. lines 19-32: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::m'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x2::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 2 'run'. lines 34-46: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000003::m'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x3::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.mvir new file mode 100644 index 00000000000000..7cd0bbb7d7d0d2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_enum_resource.mvir @@ -0,0 +1,46 @@ +//# publish +module 0x1.M { + enum EnumValue { + Nothing { }, + Coin { value: u64 } + } + + nothing(): Self.EnumValue { + label b0: + return EnumValue.Nothing { }; + } + + zero(): Self.EnumValue { + label b0: + return EnumValue.Coin { value: 0 }; + } +} + +//# run +module 0x2.m { +import 0x1.M; + +entry foo() { + let z: M.EnumValue; + let x: u64; +label b0: + z = M.nothing(); + // invalid assignment + z = M.zero(); + return; +} +} + +//# run +module 0x3.m { +import 0x1.M; + +entry foo() { + let z: M.EnumValue; +label b0: + z = M.zero(); + // invalid assignment + z = M.zero(); + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.exp new file mode 100644 index 00000000000000..fc5a4436b29d40 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.mvir new file mode 100644 index 00000000000000..e59f2945a6ca3d --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_enum_field_mutable_invalid.mvir @@ -0,0 +1,95 @@ +//# publish +module 0x1.M { + enum E has drop { + V { f0: u64 } + } + + foo(b: bool, in: &mut Self.E, other: Self.E) { + let x: &mut u64; + let y: &Self.E; + let ye: &u64; + label start: + jump_if (move(b)) t; + label f: + // Borrow mut ref + &mut E.V { f0: x } = copy(in); + // fill y with a diffrent immut ref + y = &other; + jump end; + label t: + // Freeze the ref + y = freeze(move(in)); + label end: + &E.V { f0: ye } = move(y); + return; + } +} + +//# publish +module 0x1.M1 { + enum E has drop { + V { f0: u64 } + } + + foo(b: bool, in: &mut Self.E, other: Self.E) { + let x: &mut u64; + let y: &Self.E; + let ye: &u64; + label start: + jump_if (move(b)) t; + label f: + x = Self.bar(move(in)); + y = &other; + jump end; + label t: + y = freeze(move(in)); + label end: + &E.V { f0: ye } = move(y); + return; + } + + bar(a: &mut Self.E): &mut u64 { + let x: &mut u64; + label b0: + &mut E.V { g: x } = move(a); + return move(x); + } +} + +//# publish +module 0x1.M2 { + enum E has drop { + V { f0: u64 } + } + + foo(b: bool, in: &mut Self.E, other: Self.E, t: u64) { + let x: &mut u64; + let y: &Self.E; + let ye: &u64; + label start: + jump_if (move(b)) t; + label f: + x = Self.bar(move(in)); + y = &other; + jump end; + label t: + x = &mut t; + y = freeze(move(in)); + label end: + &E.V { f0: ye } = move(y); + Self.baz(move(x)); + return; + } + + bar(a: &mut Self.E): &mut u64 { + let x: &mut u64; + label b0: + &mut E.V { g: x } = move(a); + return move(x); + } + + baz(x: &mut u64) { + label b0: + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp index 92041c10d46218..16602f305c647a 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp @@ -2,7 +2,7 @@ processed 1 task task 0 'publish'. lines 1-31: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, + major_status: FIELD_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, location: 0x1::M, indices: [(FunctionDefinition, 0)], diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.exp new file mode 100644 index 00000000000000..0b814354e6e234 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: FIELD_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 13)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.mvir new file mode 100644 index 00000000000000..66001656fb7820 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2_enum.mvir @@ -0,0 +1,34 @@ +//# publish +module 0x1.M { + enum S { V { g: u64 } } + + t1(root: &mut Self.S, cond: bool) { + let x1: u64; + let x2: u64; + let eps: &u64; + let g_mut: &mut u64; + let g_imm: &u64; + label b0: + x1 = 0; + x2 = 1; + jump_if (move(cond)) b2; + label b1: + eps = &x1; + jump b3; + label b2: + eps = Self.bar(copy(root)); + label b3: + // Error: root has weak empty borrow and hence a field cannot be borrowed mutably + &mut S.V { g: g_mut } = move(root); + g_imm = freeze(move(g_mut)); + return; + } + + bar(a: &mut Self.S): &u64 { + let x: &u64; + label b0: + &S.V { g: x } = freeze(move(a)); + return move(x); + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp index 186848589cbb9a..6f2cc6e5b15d5b 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp @@ -2,7 +2,7 @@ processed 2 tasks task 0 'publish'. lines 1-47: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, + major_status: FIELD_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, location: 0x1::Tester, indices: [(FunctionDefinition, 2)], diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.exp new file mode 100644 index 00000000000000..116193e35c4b65 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-47: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: FIELD_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 5)], +} + +task 1 'publish'. lines 49-96: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: FREEZEREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 5)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.mvir new file mode 100644 index 00000000000000..cc8fe73c66ce35 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid_enum.mvir @@ -0,0 +1,96 @@ +//# publish +module 0x1.Tester { + import 0x1.signer; + + enum Initializer { V { x: u64, y: u64 } } + enum Point { V { x: u64, y: u64 } } + + // the key struct is here to just give a feeling why the computation might not be reorderable + set_and_pick(init: &mut Self.Initializer, p: &mut Self.Point): &mut u64 { + let ix: &mut u64; + let iy: &mut u64; + let px: &mut u64; + let py: &mut u64; + + label b0: + &mut Initializer.V { x: ix, y: iy } = move(init); + &mut Point.V { x: px, y: py } = copy(p); + *move(px) = *move(ix); + *move(py) = *move(iy); + &mut Point.V { x: px, y: py } = copy(p); + jump_if (*copy(px) >= *copy(py)) b2; + label b1: + return move(py); + label b2: + return move(px); + } + + bump_and_give(u: &mut u64): &u64 { + label b0: + *copy(u) = *copy(u) + 1; + return freeze(move(u)); + } + + larger_field_1(init: &mut Self.Initializer, point_ref: &mut Self.Point): &u64 { + let field_ref: &mut u64; + let returned_ref: &u64; + let x_val: u64; + let px: &mut u64; + let py: &mut u64; + let _t: &mut u64; + label b0: + field_ref = Self.set_and_pick(move(init), copy(point_ref)); + // this borrow is invalid because of field_ref + &mut Point.V { x: px, y: py } = move(point_ref); + abort 0; + } +} + +//# publish +module 0x1.Tester { + import 0x1.signer; + + enum Initializer { V { x: u64, y: u64 } } + enum Point { V { x: u64, y: u64 } } + + // the key struct is here to just give a feeling why the computation might not be reorderable + set_and_pick(init: &mut Self.Initializer, p: &mut Self.Point): &mut u64 { + let ix: &mut u64; + let iy: &mut u64; + let px: &mut u64; + let py: &mut u64; + + label b0: + &mut Initializer.V { x: ix, y: iy } = move(init); + &mut Point.V { x: px, y: py } = copy(p); + *move(px) = *move(ix); + *move(py) = *move(iy); + &mut Point.V { x: px, y: py } = copy(p); + jump_if (*copy(px) >= *copy(py)) b2; + label b1: + return move(py); + label b2: + return move(px); + } + + bump_and_give(u: &mut u64): &u64 { + label b0: + *copy(u) = *copy(u) + 1; + return freeze(move(u)); + } + + larger_field_1(init: &mut Self.Initializer, point_ref: &mut Self.Point): &u64 { + let field_ref: &mut u64; + let returned_ref: &u64; + let x_val: u64; + let px: &mut u64; + let py: &mut u64; + let pxi: &u64; + let pyi: &u64; + label b0: + field_ref = Self.set_and_pick(move(init), copy(point_ref)); + // this freeze is invalid because of field_ref + &Point.V { x: pxi, y: pyi } = freeze(move(point_ref)); + abort 0; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp index fd136e2a4d2d2c..61f81292ab7fd5 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp @@ -2,7 +2,7 @@ processed 1 task task 0 'publish'. lines 1-29: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, + major_status: FIELD_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, location: 0x1::Tester, indices: [(FunctionDefinition, 1)], diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.exp new file mode 100644 index 00000000000000..c0ca90f4ab2c47 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: FIELD_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 4)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.mvir new file mode 100644 index 00000000000000..62cb491460107b --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid_enum.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.Tester { + enum X { V { f: u64 } } + + bump_and_give(x_ref: &mut Self.X): &u64 { + let f_ref: &mut u64; + label b0: + &mut X.V { f: f_ref } = move(x_ref); + *(copy(f_ref)) = *copy(f_ref) + 1; + return freeze(move(f_ref)); + } + + contrived_example_no(x_ref: &mut Self.X): &u64 { + let returned_ref: &u64; + let f_ref: &mut u64; + label b0: + returned_ref = Self.bump_and_give(copy(x_ref)); + // ERROR Cannot mutably borrow from `x_ref` it is being borrowed by `returned_ref` + &mut X.V { f: f_ref } = move(x_ref); + return move(returned_ref); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.mvir new file mode 100644 index 00000000000000..e7dae2764256d3 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_enum_unpacks.mvir @@ -0,0 +1,27 @@ +//# publish +module 0x42.M { + enum Foo { + V { + a: u64, + b: u64, + } + } + + public create_mutable_field_addresses(addr: &mut Self.Foo) { + let a_ref: &mut u64; + let b_ref: &mut u64; + let aa_ref: &mut u64; + let bb_ref: &mut u64; + label b0: + // multiple mutable references to same ref valid + &mut Foo.V { a: a_ref, b: b_ref } = copy(addr); + &mut Foo.V { a: aa_ref, b: bb_ref } = copy(addr); + _ = move(a_ref); + _ = move(b_ref); + _ = move(aa_ref); + _ = move(bb_ref); + _ = move(addr); + return; + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp index 3182feedca234d..7993ace08503c1 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp @@ -5,6 +5,6 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, location: 0x1::M, - indices: [(Signature, 2), (FunctionDefinition, 1)], + indices: [(Signature, 3), (FunctionDefinition, 1)], offsets: [], } diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp index d648d45c989d77..6e0c78e84686a3 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp @@ -14,7 +14,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, location: 0x1::M, - indices: [(Signature, 1), (FunctionDefinition, 0)], + indices: [(Signature, 2), (FunctionDefinition, 0)], offsets: [], } @@ -23,7 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, location: 0x1::M, - indices: [(Signature, 1), (FunctionDefinition, 0)], + indices: [(Signature, 2), (FunctionDefinition, 0)], offsets: [], } 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 new file mode 100644 index 00000000000000..8ba44f4249824c --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonoTooMany'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::MonoTooMany, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonoTooFew'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::MonoTooFew, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 2 'publish'. lines 25-35: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::PolyTooMany'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::PolyTooMany, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 3 'publish'. lines 37-47: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::PolyTooFew'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..3e2d8e28706bda --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pack_invalid_number_arguments_enum.mvir @@ -0,0 +1,48 @@ +//# publish +module 0x1.MonoTooMany { + enum Foo{ V { x: u64 } } + + bar(x: u64, y: u64): Self.Foo { + let t: Self.Foo; + label b0: + t = Foo.V { x: move(x), y: move(y) }; + return move(t); + } +} + +//# publish +module 0x1.MonoTooFew { + enum Foo{ V { x: u64 } } + + bar(x: u64, y: u64): Self.Foo { + let t: Self.Foo; + label b0: + t = Foo.V { }; + return move(t); + } +} + +//# publish +module 0x1.PolyTooMany { + enum Foo{ V { x: T } } + + bar(x: u64, y: u64): Self.Foo { + let t: Self.Foo; + label b0: + t = Foo.V { x: move(x), y: move(y) }; + return move(t); + } +} + +//# publish +module 0x1.PolyTooFew { + enum Foo{ V { x: T } } + + bar(x: u64, y: u64): Self.Foo { + let t: Self.Foo; + label b0: + t = Foo.V { }; + return move(t); + } +} + 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 new file mode 100644 index 00000000000000..43362a1eda0ea0 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 1 'publish'. lines 25-46: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x1::Test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} + +task 2 'publish'. lines 48-69: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 3 'publish'. lines 71-92: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..32ac8099c2664a --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding_enum.mvir @@ -0,0 +1,92 @@ +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: u64, x: Self.X } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x) }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // extra binding, invalid positive stack size + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } + +} + +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: H, x: Self.X } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x) }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // extra binding, invalid positive stack size and also non-generic unpack + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} + +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: H, x: Self.X } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x) }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // extra binding, invalid positive stack size and invalid instantiation + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} + +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: H, x: Self.X } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x) }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // extra binding, invalid positive stack size + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} 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 new file mode 100644 index 00000000000000..42b683af48f070 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 1 'publish'. lines 24-45: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x1::Test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} + +task 2 'publish'. lines 47-68: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 3 'publish'. lines 70-91: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..fd83f799ce1253 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding_enum.mvir @@ -0,0 +1,91 @@ +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V { i: u64, x: Self.X, b: bool, y: u64 } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x), b: false, y: 0 }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // unused item in unpack, invalid positive stack + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} + +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: H, x: Self.X, b: bool, y: u64 } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x), b: false, y: 0 }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // missing binding, invalid positive stack size and also non-generic unpack + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} + +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: H, x: Self.X, b: bool, y: u64 } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x), b: false, y: 0 }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // missing binding, invalid stack size and invalid instantiation + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} + +//# publish +module 0x1.Test { + struct X { b: bool } + enum T { V{ i: H, x: Self.X, b: bool, y: u64 } } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T.V { i: 0, x: move(x), b: false, y: 0 }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // missing binding, invalid stack size + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp index e6cc45c48b1e0e..f237bf495001cd 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp @@ -2,7 +2,7 @@ processed 1 task task 0 'publish'. lines 1-6: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, + major_status: RECURSIVE_DATATYPE_DEFINITION, sub_status: None, location: 0x42::M, indices: [(StructDefinition, 1)], diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp index 86c3d655286c67..3a1d0f2f7fcfd9 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp @@ -2,7 +2,7 @@ processed 6 tasks task 1 'publish'. lines 10-14: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M0'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, + major_status: RECURSIVE_DATATYPE_DEFINITION, sub_status: None, location: 0x1::M0, indices: [(StructDefinition, 0)], @@ -11,7 +11,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 2 'publish'. lines 16-28: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, + major_status: RECURSIVE_DATATYPE_DEFINITION, sub_status: None, location: 0x1::M1, indices: [(StructDefinition, 0)], @@ -20,7 +20,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 3 'publish'. lines 30-37: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, + major_status: RECURSIVE_DATATYPE_DEFINITION, sub_status: None, location: 0x1::M2, indices: [(StructDefinition, 1)], @@ -29,7 +29,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 4 'publish'. lines 39-46: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, + major_status: RECURSIVE_DATATYPE_DEFINITION, sub_status: None, location: 0x1::M3, indices: [(StructDefinition, 0)], @@ -38,7 +38,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 task 5 'publish'. lines 48-58: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, + major_status: RECURSIVE_DATATYPE_DEFINITION, sub_status: None, location: 0x1::M3, indices: [(StructDefinition, 3)], diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp index 509d5fddf0c132..efc5d7e33e5598 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-11: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } + +task 1 'publish'. lines 13-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir index 97702f867c1b8b..016aaa470650e3 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir @@ -9,3 +9,14 @@ module 0x42.A { return; } } + +//# publish +module 0x42.A { + enum Coin has store { V { value: u64 } } + + public t(resource1: Self.Coin, resource2: Self.Coin) { + label b0: + *&mut resource1 = move(resource2); // cannot mutate without drop ability + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp index 04ab2b89db996b..07fe9896c8c489 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp @@ -1,6 +1,6 @@ -processed 1 task +processed 2 tasks -task 0 'publish'. lines 1-13: +task 0 'publish'. lines 1-12: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } + +task 1 'publish'. lines 14-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x43::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir index 4f3eab0fae2b4f..4aca052f99bc04 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir @@ -1,7 +1,19 @@ //# publish module 0x42.A { struct Coin has store { value: u64 } - struct T { f: Self.Coin } + + public t(resource_ref: &mut Self.Coin, resource1: Self.Coin, resource2: Self.Coin) { + label b0: + // cannot modify without drop ability + *move(resource_ref) = move(resource1); + *move(resource_ref) = move(resource2); + return; + } +} + +//# publish +module 0x43.A { + enum Coin has store { V { value: u64 } } public t(resource_ref: &mut Self.Coin, resource1: Self.Coin, resource2: Self.Coin) { label b0: diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.exp new file mode 100644 index 00000000000000..a830d1e9baf17e --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.mvir new file mode 100644 index 00000000000000..8f6527847ce0a6 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type_enum.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x42.A { + struct Coin has store { value: u64 } + enum T { V { f: Self.Coin } } + + public t(this: &mut Self.T, y: Self.Coin) { + let x: &mut Self.Coin; + label b0: + &mut T.V { f: x } = move(this); + *move(x) = move(y); // cannot assign/mutate without drop ability + return; + } +} +// check: WRITEREF_WITHOUT_DROP_ABILITY diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp index 22c3e9e7ddea14..b82d0ea0b8c719 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-42: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 4)], offsets: [(FunctionDefinitionIndex(4), 13)], } + +task 1 'publish'. lines 44-85: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::Token'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x2::Token, + indices: [(FunctionDefinition, 4)], + offsets: [(FunctionDefinitionIndex(4), 13)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir index 191086b1e4f67b..92835730f53c6c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir @@ -40,3 +40,46 @@ module 0x1.Token { return; } } + +//# publish +module 0x2.Token { + import 0x1.signer; + + enum T has key { V{v: u64}} + + public new(v: u64): Self.T { + label b0: + return T.V {v: move(v)}; + } + + public value(this: &Self.T): u64 { + let vref: &u64; + let res: u64; + label b0: + &T.V{ v: vref } = move(this); + // T does not have copy + res = *move(vref); + return move(res); + } + + public publish(account: &signer, t: Self.T) { + label b0: + abort(0); + } + + fake(addr: address): &mut Self.T { label b0: abort(0); } + + public test(account: &signer) { + let addr: address; + let t: Self.T; + let tref: &mut Self.T; + let y: Self.T; + label b0: + addr = signer.address_of(copy(account)); + t = Self.new(0); + Self.publish(copy(account), move(t)); + tref = Self.fake(move(addr)); + y = *move(tref); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp index 5d92c423f3fd86..457ace9c4acb66 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp @@ -1 +1 @@ -processed 2 tasks +processed 4 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir index 5aa54e5651a8df..92cbc318952c1e 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir @@ -25,3 +25,31 @@ label b0: return; } } + +//# publish +module 0x2.Token { + enum T has key { V { b: bool } } + + public test() { + let t: Self.T; + let t_ref: &Self.T; + let b: bool; + label b0: + t = T.V{ b: true }; + t_ref = &t; + assert(copy(t_ref) == move(t_ref), 42); // == works over refs, even if resources without drop + T.V{ b } = move(t); + return; + } +} + +//# run +module 0x43.m { +import 0x2.Token; + +entry foo() { +label b0: + Token.test(); + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp index 9f367810cbad14..6b929dd95b327c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-11: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::Token'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::Token, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir index 13fa89cfc085ad..6b69803b6404d8 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir @@ -9,3 +9,15 @@ module 0x1.Token { return; } } + +//# publish +module 0x2.Token { + enum T has key { V { b: bool } } + + public test() { + let no: bool; + label b0: + no = T.V{ b: true } == T.V{ b: true }; // == requires drop + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.mvir new file mode 100644 index 00000000000000..181749b05ab0b2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_unpack_enum.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + enum Foo { V{ x: T }} + + baz(x: u64) { + label b0: + return; + } + + bar(x: Self.Foo) { + let ref: &Self.Foo; + let y: &u64; + let z: u64; + label b0: + ref = &x; + &Foo.V { x: y } = &x; + _ = move(ref); + _ = move(y); + Foo.V { x: z } = move(x); + return; + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir index d9ef85f771d4bf..fbff4343573f32 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir @@ -9,3 +9,15 @@ module 0x1.M { return move(f); } } + +//# publish +module 0x2.M { + enum Foo { V { x: T1, y: T2 } } + + foo(x: T): Self.Foo { + let f: Self.Foo; + label b0: + f = Foo.V { x: 42, y: move(x) }; + return move(f); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp index 6e22edc070f946..d27714f20ec3e2 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-12: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } + +task 1 'publish'. lines 14-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x2::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir index 37c45a84839d9a..8b0d06a4693dda 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir @@ -10,3 +10,16 @@ module 0x1.M { return move(y); } } + +//# publish +module 0x2.M { + enum R { V{ b: bool } } + enum Box { V{ x: T } } + + foo(x: Self.Box): Self.Box { + let y: Self.Box; + label b0: + y = copy(x); // type does not have copy + return move(y); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp index 59701471c163df..c9a735a9dd74b8 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-11: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x2::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir index 61d1cc178365b1..178340d99dc5fe 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir @@ -9,3 +9,15 @@ module 0x1.M { return; // unused type parameter value without drop } } + +//# publish +module 0x2.M { + enum Foo { V{ x: T } } + + baz(x: Self.Foo) { + let y: T; + label b0: + Foo.V { x: y } = move(x); + return; // unused type parameter value without drop + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.mvir new file mode 100644 index 00000000000000..a795377912a559 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack_mut_enum.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x1.M { + enum Foo{ V { x: T } } + + baz(x: u64) { + label b0: + return; + } + + bar(x: Self.Foo) { + let y: &mut u64; + let z: u64; + label b0: + &mut Foo.V { x: y } = &mut x; + _ = move(y); + Foo.V { x: z } = move(x); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir index c3095185b81611..5d6e3dbfc4d716 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir @@ -21,3 +21,27 @@ module 0x1.M { return; } } + +//# publish +module 0x2.M { + enum Foo { V{ f: bool } } + + public id(x: T): T { + label b0: + return move(x); + } + + public bar(x: T1, y: T2) { + label b0: + abort 0; + } + + foo() { + let x: Self.Foo; + label b0: + _ = Self.id(3); + x = Self.id(Foo.V { f: false }); + Self.bar(move(x), false); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir index 317dbb6e76f7db..a6b12ce8b7e834 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir @@ -7,3 +7,17 @@ module 0x1.M { return *(&(&(&s).S::f).X::v); } } + +//# publish +module 0x2.M { + enum X has drop { V { v: u64 } } + enum S has drop { V { f: T } } + t(s: Self.S): u64 { + let v: &u64; + let f: &Self.X; + label b0: + &S.V { f } = &s; + &X.V { v } = move(f); + return *move(v); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.exp new file mode 100644 index 00000000000000..6cd67db3f64724 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.mvir new file mode 100644 index 00000000000000..01679750bb353a --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_unpack_borrow_after_call_enum.mvir @@ -0,0 +1,17 @@ +//# publish + +module 0x1.M { + enum X has drop { V{ v: u64 }} + id(x: &T): &T { + label b0: + return move(x); + } + + t(x: Self.X): u64 { + let t: &u64; + label b0: + &X.V { v: t } = Self.id(&x); + return *move(t); + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp index fc5a4436b29d40..2301000e50ae44 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp @@ -1 +1 @@ -processed 3 tasks +processed 6 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir index e0c3b495ca1969..e23c568cb399e6 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir @@ -26,3 +26,32 @@ label b0: return; } } + +//# publish +module 0x3.M { + enum Foo has key { V { x: T } } + + enum Bar { V { x: T3, y: T2, z: T1 } } +} + +//# run +module 0x3.m { +import 0x3.M; + +entry foo() { + let x: M.Foo; +label b0: + return; +} +} + +//# run +module 0x4.m { +import 0x3.M; + +entry foo() { + let x: M.Bar, bool>; +label b0: + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir index 7e91ea2933d76c..3a0ee38104fef0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir @@ -37,3 +37,42 @@ module 0x42.Option { return Self.unwrap_or>(Self.none>(), Self.none()); } } + +//# publish + +// example using generics in a few common/interesting/non-trivial ways -- with actual enums! +module 0x43.Option { + enum T has copy, drop, store { + None { }, + Some { v: E } + } + + public none(): Self.T { + label b0: + return T.None { }; + } + + public some(e: E): Self.T { + label b0: + return T.Some { v: move(e) }; + } + + public unwrap_or(x: Self.T, e: E): E { + let v: E; + label b0: + variant_switch T (&x) { + None : b1, + Some : b2, + }; + label b1: + T.Some { v: v } = move(x); + return move(v); + label b2: + return move(e); + } + + public really_none(): Self.T { + label b0: + return Self.unwrap_or>(Self.none>(), Self.none()); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp index 5d92c423f3fd86..457ace9c4acb66 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp @@ -1 +1 @@ -processed 2 tasks +processed 4 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir index 7d49fc36fdd17e..37862fb98b520a 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir @@ -22,3 +22,28 @@ module 0x1.N { abort 0; } } + +//# publish +module 0x2.M { + enum Foo { V { x: T } } + + foo() { + let x: Self.Foo; + label b0: + x = Foo.V { x : 42 }; // valid + abort 0; + } +} + +//# publish +module 0x2.N { + enum Foo { V { x: T1, y: T2 } } + enum Bar has key { V { f: bool } } + + foo() { + let x: Self.Foo; + label b0: + x = Foo.V { x : 42, y: Bar.V { f: false } }; // valid + abort 0; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.exp new file mode 100644 index 00000000000000..342fbf770e586f --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.exp @@ -0,0 +1,73 @@ +processed 8 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'publish'. lines 13-24: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::N'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::N, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 2 'publish'. lines 26-37: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::O'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 3 'publish'. lines 39-50: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::P'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::P, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 4 'publish'. lines 53-63: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 5 'publish'. lines 65-76: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::N'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::N, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 6 'publish'. lines 78-89: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 7 'publish'. lines 91-102: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::P'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::P, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.mvir new file mode 100644 index 00000000000000..b5c8541a71780f --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack_type_mismatch.mvir @@ -0,0 +1,103 @@ +//# publish +module 0x1.M { + struct Foo { x: T } + + foo() { + let x: Self.Foo; + label b0: + x = Foo { x : true }; // invalid + abort 0; + } +} + +//# publish +module 0x1.N { + struct Foo { x: T1, y: T2 } + struct Bar has key { f: bool } + + foo() { + let x: Self.Foo; + label b0: + x = Foo { x : 42, y: Bar { f: 42 } }; // invalid + abort 0; + } +} + +//# publish +module 0x1.O { + struct Foo { x: T1, y: T2 } + struct Bar has key { f: T } + + foo() { + let x: Self.Foo>; + label b0: + x = Foo> { x : 42, y: Bar { f: 42 } }; // invalid + abort 0; + } +} + +//# publish +module 0x1.P { + struct Foo { x: T1, y: T2 } + struct Bar has key { f: T } + + foo() { + let x: Self.Foo>; + label b0: + x = Foo> { x : 42, y: Bar { f: 42 } }; // invalid + abort 0; + } +} + + +//# publish +module 0x2.M { + enum Foo { V { x: T } } + + foo() { + let x: Self.Foo; + label b0: + x = Foo.V { x : true }; // invalid + abort 0; + } +} + +//# publish +module 0x2.N { + enum Foo { V { x: T1, y: T2 } } + enum Bar has key { V { f: bool } } + + foo() { + let x: Self.Foo; + label b0: + x = Foo.V { x : 42, y: Bar.V { f: 42 } }; // invalid + abort 0; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T1, y: T2 } } + enum Bar has key { V { f: T } } + + foo() { + let x: Self.Foo>; + label b0: + x = Foo.V> { x : 42, y: Bar.V { f: 42 } }; // invalid + abort 0; + } +} + +//# publish +module 0x2.P { + enum Foo { V { x: T1, y: T2 } } + enum Bar has key { V { f: T } } + + foo() { + let x: Self.Foo>; + label b0: + x = Foo.V> { x : 42, y: Bar.V { f: 42 } }; // invalid + abort 0; + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir index 4c98c1df908d81..a0a6d395002a62 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir @@ -8,3 +8,14 @@ module 0x1.M { struct Foo { x: T } struct Bar { x1: T2, x2: T3, x3: T4, x4: T1 } } + +//# publish + +// This test checks that for each enum definition +// 1) type parameters have correct kind constraints +// 2) fields have correct types + +module 0x2.M { + enum Foo { V { x: T } } + enum Bar { V { x1: T2, x2: T3, x3: T4, x4: T1 } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp index 5d92c423f3fd86..457ace9c4acb66 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp @@ -1 +1 @@ -processed 2 tasks +processed 4 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir index 74b746057c36ca..396bc5ce25a22e 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir @@ -23,3 +23,29 @@ module 0x1.N { return; } } + +//# publish +module 0x2.M { + enum Foo { V { x: T } } + + foo() { + let x: u64; + label b0: + Foo.V { x: x } = Foo.V { x: 42 }; // valid + return; + } +} + +//# publish +module 0x2.N { + enum Foo { V { x: T1, y: T2 } } + + foo() { + let x: u64; + let y: bool; + label b0: + // valid + Foo.V { x: x, y: y } = Foo.V { x: 42, y: true }; + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.exp new file mode 100644 index 00000000000000..3e09a9890d79b4 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::O'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 1 'publish'. lines 15-27: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.mvir new file mode 100644 index 00000000000000..4e846ed8e6c8ea --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack_type_mismatch.mvir @@ -0,0 +1,27 @@ +//# publish +module 0x1.O { + struct Foo { x: T1, y: T2 } + + foo() { + let x: u64; + let y: bool; + label b0: + // invalid + Foo { x: x, y: y } = Foo { x: 42, y: true }; + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T1, y: T2 } } + + foo() { + let x: u64; + let y: bool; + label b0: + // invalid + Foo.V { x: x, y: y } = Foo.V { x: 42, y: true }; + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.exp new file mode 100644 index 00000000000000..cbd2e1afd6010a --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: WRITEREF_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 5)], +} + +task 1 'publish'. lines 20-37: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: WRITEREF_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 5)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.mvir new file mode 100644 index 00000000000000..a180bfb149180a --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write_mut_unpack_enum.mvir @@ -0,0 +1,37 @@ +//# publish +module 0x42.Test { + enum T{V { fr: bool} } + + public new(): Self.T { + label b0: + return T.V{fr: false}; + } + + public no(this: &mut Self.T) { + let x: &mut bool; + label b0: + &mut T.V {fr: x} = move(this); + // type mismatch on assignment/mutation + *move(x) = 0; + return; + } +} + +//# publish +module 0x42.Test { + enum T {V { fr: B } } + + public new(): Self.T { + label b0: + return T.V {fr: false}; + } + + public no(this: &mut Self.T) { + let x: &mut bool; + label b0: + &mut T.V {fr: x} = move(this); + // type mismatch on assignment/mutation + *move(x) = 0; + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.exp new file mode 100644 index 00000000000000..33e1bc9c8953c3 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::RTest'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x43::RTest, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.mvir new file mode 100644 index 00000000000000..d546b5516ce5a2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resouce_write_unpack_mut_enum.mvir @@ -0,0 +1,15 @@ +//# publish +module 0x43.RTest { + enum Coin has store { V{ value: u64 } } + enum T { V{ f: Self.Coin } } + + public update(t: &mut Self.T, i: Self.Coin) { + let x: &mut Self.Coin; + label b0: + &mut T.V { f: x } = move(t); + // cannot assign to ref where type does not have drop + *move(x) = move(i); + return; + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.exp new file mode 100644 index 00000000000000..3a26085aabbd4c --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Token, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 1)], +} + +task 1 'publish'. lines 27-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Token, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.mvir new file mode 100644 index 00000000000000..fee621f1491bb2 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref_enum.mvir @@ -0,0 +1,38 @@ +//# publish +module 0x42.Token { + enum T { V{value: u64}} + public new(m: u64): Self.T { + label b0: + return T.V{value: copy(m)}; + } + public destroy(t: Self.T) { + let value: u64; + label b0: + T.V {value} = move(t); + return; + } + + public bump_value(this: &Self.T) { + let val: &mut u64; + let x: u64; + label b0: + // cannot unpack mut from an imm ref + &mut T.V { value: val } = move(this); + x = *copy(val) + 1; + *move(val) = copy(x); + return; + } +} + +//# publish +module 0x42.Token { + enum T { V{value: B }} + + public bump_value(this: &Self.T, new: B) { + let val: &mut B; + label b0: + // cannot unpack mut from an imm ref + &mut T.V { value: val } = move(this); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir index aeee94c8396b23..b953092719047a 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir @@ -63,3 +63,69 @@ module 0x42.Token { return; } } + +//# publish +module 0x43.Token { + import 0x1.signer; + + enum T has key {V { balance: u64} } + + public new(balance: u64): Self.T { + label b0: + return T.V {balance: copy(balance)}; + } + + public value(this: &Self.T): u64 { + let b: u64; + let b_ref: &u64; + label b0: + &T.V {balance: b_ref} = move(this); + b = *move(b_ref); + return move(b); + } + + public bump(this: &mut Self.T) { + let val: &mut u64; + let x: u64; + label b0: + &mut T.V {balance: val} = move(this); + x = *copy(val) + 1; + *move(val) = copy(x); + return; + } + + public publish(account: &signer, t: Self.T) { + label b0: + abort(0); + } + + fake(addr: address): &mut Self.T { label b0: abort(0); } + + public test(account: &signer) { + let z: Self.T; + let addr1: address; + let struct1: &mut Self.T; + let imm_struct1: &Self.T; + let struct1_original_balance: u64; + let struct1_new_balance: u64; + label b0: + z = Self.new(0); + Self.publish(copy(account), move(z)); + + addr1 = signer.address_of(move(account)); + // returns mut reference, test its usage + struct1 = Self.fake(copy(addr1)); + + imm_struct1 = freeze(copy(struct1)); + struct1_original_balance = Self.value(move(imm_struct1)); + assert(move(struct1_original_balance) == 0, 42); + + Self.bump(copy(struct1)); + + imm_struct1 = freeze(move(struct1)); + struct1_new_balance = Self.value(move(imm_struct1)); + assert(move(struct1_new_balance) == 1, 43); + + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.exp new file mode 100644 index 00000000000000..db9153197af6ea --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { + major_status: CALL_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Token, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 4)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.mvir new file mode 100644 index 00000000000000..120d256d1ee571 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref_enum.mvir @@ -0,0 +1,33 @@ +//# publish +module 0x42.Token { + enum T{ V { value: u64 } } + public new(m: u64): Self.T { + label b0: + return T.V{value: copy(m)}; + } + public destroy(t: Self.T) { + let value: u64; + label b0: + T.V {value} = move(t); + return; + } + + public read_value(this: &Self.T): u64 { + let val: &u64; + label b0: + &T.V { value: val } = move(this); + // type mismatch, cannot make imm to mut + Self.bump_value(move(this)); + return *move(val); + } + + public bump_value(this: &mut Self.T) { + let val: &mut u64; + let x: u64; + label b0: + &mut T.V { value: val } = move(this); + x = *copy(val) + 1; + *move(val) = copy(x); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.exp new file mode 100644 index 00000000000000..20f8665c0de641 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.exp @@ -0,0 +1,82 @@ +processed 9 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x2::O, + indices: [], + offsets: [], +} + +task 2 'publish'. lines 25-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x2::O, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 30-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 4 'publish'. lines 42-52: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x2::O, + indices: [], + offsets: [], +} + +task 5 'publish'. lines 54-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x2::O, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 6 'publish'. lines 62-72: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'publish'. lines 74-84: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x2::O, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 8 'publish'. lines 86-89: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x2::O, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.mvir new file mode 100644 index 00000000000000..ff3a4ae1c1ad21 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_enum_with_refs.mvir @@ -0,0 +1,89 @@ +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &u64): Self.Foo<&u64> { + let y: Self.Foo<&u64>; + label b0: + y = Foo.V<&u64> { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: &T } } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &mut u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &mut u64): Self.Foo<&mut u64> { + let y: Self.Foo<&mut u64>; + label b0: + y = Foo.V<&mut u64> { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: &mut T } } +} + + +// Mono decls now + +//# publish +module 0x2.O { + enum Foo { V { x: u64 } } + + foo(x: &mut u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: &mut u64 } } + + foo(x: &mut u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: &mut u64 } } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.exp new file mode 100644 index 00000000000000..f3db392fd90fcd --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.exp @@ -0,0 +1,73 @@ +processed 9 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 2 'publish'. lines 25-35: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 3 'publish'. lines 37-47: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::O, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} + +task 4 'publish'. lines 49-59: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} + +task 5 'publish'. lines 61-71: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} + +task 7 'publish'. lines 79-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 8 'publish'. lines 92-103: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.mvir new file mode 100644 index 00000000000000..50b269e73af157 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_invalid_type_arguments.mvir @@ -0,0 +1,103 @@ +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + + +//# publish +module 0x1.O { + enum Foo { V { x: T } } +} + +//# publish +module 0x2.O { + import 0x1.O; + enum Foo { V { x: T } } + + foo(x: u64): O.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + +//# publish +module 0x2.O { + import 0x1.O; + enum Foo { V { x: T } } + + foo(x: u64): O.Foo { + let y: O.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.exp new file mode 100644 index 00000000000000..2db8d8685caded --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::O, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.mvir new file mode 100644 index 00000000000000..bb201fba6ad4d4 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_generic_enum_non_generically.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.exp new file mode 100644 index 00000000000000..1500bfdbb522cc --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::O, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.mvir new file mode 100644 index 00000000000000..6fb1ae97547164 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/pack_non_generic_enum_generically.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x2.O { + enum Foo { V { x: u64 } } + + foo(x: u64): Self.Foo { + let y: Self.Foo; + label b0: + y = Foo.V { x: move(x) }; + return move(y); + } +} + diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp index 9e70f34422ea3f..c2551604b63163 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp @@ -1,4 +1,4 @@ -processed 6 tasks +processed 12 tasks task 1 'publish'. lines 10-22: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { @@ -44,3 +44,48 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 0), (FunctionHandle, 0)], offsets: [], } + +task 7 'publish'. lines 82-94: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M2'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x2::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 8 'publish'. lines 96-108: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M3'. Got VMError: { + major_status: POP_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x2::M3, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 9 'publish'. lines 110-121: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M4'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x2::M4, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 10 'publish'. lines 123-133: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M5'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x2::M5, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 11 'publish'. lines 135-146: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M9'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x2::M9, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir index 5e843b4c555e54..361ebc9446fc70 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir @@ -1,7 +1,7 @@ //# publish // This file contains tests checking that type arguments used in phantom position -// (phantom arguments) are not considered when deriving the abilities for a struct. +// (phantom arguments) are not considered when deriving the abilities for a struct or enum. module 0x1.M1 { struct NoAbilities { a: bool } @@ -72,3 +72,75 @@ module 0x1.M9 { return RequireStore> { a: true }; } } + +//# publish + +module 0x2.M1 { + enum NoAbilities { V { a: bool } } +} + +//# publish +module 0x2.M2 { + import 0x2.M1; + + enum HasDrop has drop { V { a: bool } } + + // `WriteRef` requires drop + f(ref: &mut Self.HasDrop) { + label b0: + *move(ref) = HasDrop.V { a : true }; + return; + } +} + +//# publish +module 0x2.M3 { + import 0x2.M1; + + enum HasDrop has drop { V { a: bool } } + + // `Pop` requires drop + f() { + label b0: + _ = HasDrop.V { a: true }; + return; + } + } + +//# publish + module 0x2.M4 { + import 0x2.M1; + + enum HasDrop has drop { V { a: bool } } + + // Leaving value in local requires drop + f(x: Self.HasDrop) { + label b0: + return; + } + } + +//# publish + module 0x2.M5 { + import 0x2.M1; + enum HasCopy has copy { V { a : bool } } + + // `CopyLoc` requires copy + f(x: Self.HasCopy): Self.HasCopy * Self.HasCopy { + label b0: + return (copy(x), move(x)); + } + } + +//# publish +module 0x2.M9 { + import 0x2.M1; + + enum HasStore has store { V { a: bool } } + enum RequireStore { V { a: bool } } + + f(): Self.RequireStore> { + label b0: + return RequireStore.V> { a: true }; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir index 1a54ba91d100c8..eb3054b4f81913 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir @@ -1,7 +1,7 @@ //# publish // Test checking that type arguments used in phantom position (phantom arguments) -// are not considered when deriving the abilities for a struct by checking against +// are not considered when deriving the abilities for a struct/enum by checking against // abilities required for specific bytecode operatiosn. module 0x1.M { @@ -43,3 +43,44 @@ module 0x1.M { return RequireStore> { a: true }; } } + +//# publish +module 0x2.M { + enum NoAbilities { V{ a: bool } } + enum HasDrop has drop { V{ a: bool }} + enum HasCopy has copy { V{ a : bool }} + enum HasStore has store { V{ a: bool }} + enum HasKey has key { V{ a : bool } } + enum RequireStore { V{ a: bool }} + + // `WriteRef` requires drop + f1(ref: &mut Self.HasDrop) { + label b0: + *move(ref) = HasDrop.V { a: true }; + return; + } + + // `Pop` requires drop + f2() { + label b0: + _ = HasDrop.V { a: true }; + return; + } + + // Leaving value in local requires drop + f3(x: Self.HasDrop) { + label b0: + return; + } + + // `CopyLoc` requires copy + f4(x: Self.HasCopy): Self.HasCopy * Self.HasCopy { + label b0: + return (copy(x), move(x)); + } + + f8(): Self.RequireStore> { + label b0: + return RequireStore.V> { a: true }; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp index 4df09dd1d0e380..6ae865c2d107b9 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp @@ -1,4 +1,4 @@ -processed 6 tasks +processed 12 tasks task 1 'publish'. lines 7-15: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { @@ -35,3 +35,39 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 0), (FunctionDefinition, 1)], offsets: [], } + +task 7 'publish'. lines 83-91: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x2::M2, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 1)], + offsets: [], +} + +task 8 'publish'. lines 93-112: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x2::M3, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 5)], + offsets: [], +} + +task 9 'publish'. lines 114-124: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x2::M4, + indices: [(Signature, 0), (FunctionDefinition, 1)], + offsets: [], +} + +task 11 'publish'. lines 138-153: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M5'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x2::M5, + indices: [(Signature, 0), (FunctionDefinition, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir index ced372110a291e..3d377b5e56b4f4 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir @@ -73,3 +73,81 @@ module 0x1.M5 { return; } } + +//# publish +module 0x2.M1 { + enum NoAbilities { V{ a: bool } } + enum HasAbilities has drop, copy, store, key { V{ a: bool } } +} + +//# publish +module 0x2.M2 { + import 0x2.M1; + + enum S1 { V{ a: bool }} + enum S2 { + V { a: Self.S1> } + } +} + +//# publish +module 0x2.M3 { + import 0x2.M1; + + enum HasDrop has drop { V{ a: bool }} + enum HasCopy has copy { V{ a: bool }} + enum HasStore has store { V{ a: bool }} + enum HasKey has key { V{ a: bool }} + + enum S1 { V{ a: bool }} + enum S2 { + V { + a: Self.S1< Self.HasDrop, + Self.HasCopy, + Self.HasStore, + Self.HasKey + > + } + } +} + +//# publish +module 0x2.M4 { + import 0x2.M1; + + f1() { label b0: return; } + f2() { + label b0: + Self.f1>(); + return; + } +} + + +//# publish +module 0x2.M3Valid { + import 0x2.M1; + + enum HasDrop has drop { V{ a: bool }} + enum HasCopy has copy { V{ a: bool }} + enum HasStore has store { V{ a: bool }} + enum HasKey has key { V{ a: bool }} + +} + +//# publish +module 0x2.M5 { + import 0x2.M1; + import 0x2.M3Valid; + + f1() { label b0: return; } + f2() { + label b0: + Self.f1< M3Valid.HasDrop, + M3Valid.HasCopy, + M3Valid.HasStore, + M3Valid.HasKey + >(); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir index c59b6a17d4611a..cbc2dc8039e122 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir @@ -39,3 +39,47 @@ module 0x1.M { return; } } + +//# publish +module 0x2.M { + enum NoAbilities { V{ a: bool } } + enum HasDrop has drop { V{ a: bool }} + enum HasCopy has copy { V{ a: bool }} + enum HasStore has store { V{ a: bool }} + enum HasKey has key { V{ a: bool }} + enum HasAbilities has drop, copy, store, key { V{ a: bool } } + + enum S1 { V{ a: bool }} + enum S2 { + V { a: Self.S1>, } + } + + enum S3 { V{ a: bool }} + enum S4 { + V { + a: Self.S3< Self.HasDrop, + Self.HasCopy, + Self.HasStore, + Self.HasKey + > + } + } + + f1() { label b0: return; } + f2() { + label b0: + Self.f1>(); + return; + } + + f3() { label b0: return; } + f4() { + label b0: + Self.f3< Self.HasDrop, + Self.HasCopy, + Self.HasStore, + Self.HasKey + >(); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp index 43e65b417613a5..eec1e39402cef0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp @@ -1,4 +1,4 @@ -processed 5 tasks +processed 10 tasks task 1 'publish'. lines 16-21: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { @@ -35,3 +35,39 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } + +task 6 'publish'. lines 56-61: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M2'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x2::M2, + indices: [(EnumDefinition, 0), (VariantTag, 0), (FieldDefinition, 0)], + offsets: [], +} + +task 7 'publish'. lines 63-68: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M3'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x2::M3, + indices: [(EnumDefinition, 0), (VariantTag, 0), (FieldDefinition, 0)], + offsets: [], +} + +task 8 'publish'. lines 70-75: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M4'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x2::M4, + indices: [(EnumDefinition, 0), (VariantTag, 0), (FieldDefinition, 0)], + offsets: [], +} + +task 9 'publish'. lines 77-82: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M5'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x2::M5, + indices: [(EnumDefinition, 0), (VariantTag, 0), (FieldDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir index 27420506f62d9a..ca6e01c8e3ec33 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir @@ -40,3 +40,43 @@ module 0x1.M5 { struct S has key { a: M1.HasStore } } + +//# publish + +module 0x2.M1 { + enum NoAbilities { V{ a: bool } } + + enum HasDrop has drop { V{ a: bool }} + enum HasCopy has copy { V{ a : bool }} + enum HasStore has store { V{ a : bool } } + enum HasKey has key { V{ a : bool } } + +} + +//# publish +module 0x2.M2 { + import 0x2.M1; + + enum S has drop { V{ a: M1.HasDrop }} +} + +//# publish +module 0x2.M3 { + import 0x2.M1; + + enum S has copy { V{ a: M1.HasCopy }} +} + +//# publish +module 0x2.M4 { + import 0x2.M1; + + enum S has store { V{ a: M1.HasStore }} +} + +//# publish +module 0x2.M5 { + import 0x2.M1; + + enum S has key { V{ a: M1.HasStore }} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp index 6cd67db3f64724..5d92c423f3fd86 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp @@ -1 +1 @@ -processed 1 task +processed 2 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir index f42204d00e07fa..2a6b8707027f2c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir @@ -1,7 +1,7 @@ //# publish // This module checks that phantom arguments are not considered by checking against -// the abilities required for the fields of a struct. +// the abilities required for the fields of a struct/enum. module 0x1.M { struct NoAbilities { a: bool } @@ -16,3 +16,19 @@ module 0x1.M { struct S3 has store { a: Self.HasStore } struct S4 has key { a: Self.HasStore } } + +//# publish + +module 0x2.M { + enum NoAbilities { V{ a: bool } } + + enum HasDrop has drop { V{ a: bool }} + enum HasCopy has copy { V{ a : bool }} + enum HasStore has store { V{ a : bool } } + enum HasKey has key { V{ a : bool } } + + enum S1 has drop { V{ a: Self.HasDrop }} + enum S2 has copy { V{ a: Self.HasCopy }} + enum S3 has store { V{ a: Self.HasStore }} + enum S4 has key { V{ a: Self.HasStore }} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp index 2dd0de8772574c..2699bb8c177367 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp @@ -1,4 +1,4 @@ -processed 6 tasks +processed 12 tasks task 0 'publish'. lines 1-11: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { @@ -53,3 +53,57 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FieldDefinition, 0), (StructDefinition, 1)], offsets: [], } + +task 6 'publish'. lines 58-68: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M1'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x2::M1, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 7 'publish'. lines 70-76: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M2'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x2::M2, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 8 'publish'. lines 78-85: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M3'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x2::M3, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 1)], + offsets: [], +} + +task 9 'publish'. lines 87-96: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M4'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x2::M4, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 2)], + offsets: [], +} + +task 10 'publish'. lines 98-104: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M5'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x2::M5, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 0)], + offsets: [], +} + +task 11 'publish'. lines 106-113: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M6'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x2::M6, + indices: [(FieldDefinition, 0), (VariantTag, 0), (EnumDefinition, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir index 2eeaa025b777aa..ec2317f2271b8b 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir @@ -54,3 +54,60 @@ module 0x1.M6 { a: Self.S1 } } + +//# publish + +// Tests checking incorrect enum declarations using phantom parameters +// in illegal positions. + +module 0x2.M1 { + // A phantom parameter cannot be used as the type of a field + enum S1 { + V { a: T } + } +} + +//# publish +module 0x2.M2 { + // The parameter of vector is non-phantom and a phantom parameter shouldn't be allowed in that position + enum S2 { + V { a: vector } + } +} + +//# publish +module 0x2.M3 { + // A phantom parameter cannot be used as the argument to a non-phantom parameter + enum S1 { V{ f: bool }} + enum S2 { + V { a: Self.S1 } + } +} + +//# publish +module 0x2.M4 { + // More complicated test where the phantom position violation is inside another + // type argument. + enum S1 { V{ a: T}} + enum S2 { V{ a : T } } + enum S3 { + V { a: Self.S1> } + } +} + +//# publish +module 0x2.M5 { + // Mixing phantom and non-phantom parameters + enum S { + V { a: T2 } + } +} + +//# publish +module 0x2.M6 { + // Phantom parameters should satisfy constraints + enum S1 { V{ a: bool } } + enum S2 { + V { a: Self.S1 } + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp index fc5a4436b29d40..5027f10bfe9630 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp @@ -1 +1 @@ -processed 3 tasks +processed 7 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir index 6cf2dd6cc7bc92..886efb75529d9d 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir @@ -45,3 +45,65 @@ module 0x1.M3 { a: Self.S1 } } + +//# publish +module 0x2.M1 { + // Not using a phantom parameter at all is ok. + enum S1 { + V { a: u64 } + } + + // Phantom parameters can be used in phantom position. + enum S2 { + V { + a: Self.S1, + b: vector> + } + } + + // It's ok to not use a non-phantom parameter (backward-compatibility). + enum S3 { + V { a: u64 } + } + + // Mixing phantom and non-phantom parameters + enum S4 { + V { + a: T2, + b: T4 + } + } +} + +//# publish +module 0x2.M2 { + import 0x2.M1; + + // Phantom position across modules + enum S { + V { a: M1.S2> } + } +} + +//# publish +module 0x2.M3 { + // Phantom parameters should be allowed to be declared with constraints. + + enum S1 { + V { a: u64 } + } + + enum S2 { + V { a: Self.S1 } + } +} + +//# publish +module 0x2.M4 { + import 0x1.M1; + + // Phantom position across modules + enum S { + V { a: M1.S2> } + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp index 4d754d64d1ff61..c06e2b281c323a 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp @@ -1,4 +1,4 @@ -processed 4 tasks +processed 8 tasks task 0 'publish'. lines 1-10: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { @@ -35,3 +35,39 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 0), (FunctionHandle, 0)], offsets: [], } + +task 4 'publish'. lines 46-55: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 5 'publish'. lines 57-66: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 6 'publish'. lines 68-77: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M3'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} + +task 7 'publish'. lines 79-89: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M4, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir index c4c7b958ee8367..eaea2431735798 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir @@ -42,3 +42,48 @@ module 0x42.M4 { return move(v); } } + +//# publish +module 0x43.M1 { + enum S { V{ t: T } } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(s: &Self.S) { + label b0: + return; + } +} + +//# publish +module 0x43.M2 { + struct S { t: T } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(s: &mut Self.S) { + label b0: + return; + } +} + +//# publish +module 0x43.M3 { + enum S { V{ t: T } } + + // should get flagged--missing type argument + public bad_sig(s: &Self.S) { + label b0: + return; + } +} + +//# publish +module 0x43.M4 { + enum Box { V{ t: T } } + enum S { V{ t: T } } + + // should be rejected + public bad_sig(v: Self.Box>): Self.Box> { + label b0: + return move(v); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp index 6ce6fc50cc2de7..6d0efc6903d510 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp @@ -1,4 +1,4 @@ -processed 5 tasks +processed 10 tasks task 0 'publish'. lines 1-11: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { @@ -44,3 +44,48 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 0), (FunctionHandle, 0)], offsets: [], } + +task 5 'publish'. lines 74-86: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 6 'publish'. lines 88-98: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 7 'publish'. lines 100-112: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M3, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 8 'publish'. lines 114-130: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M4, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 9 'publish'. lines 132-148: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M5'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M5, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir index 0eafaeb052106d..7043b6f7f1ad26 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir @@ -70,3 +70,79 @@ module 0x42.M5 { return move(x); } } + +//# publish +module 0x43.M1 { + enum S { V{ t: T } } + + // note: T does not have copy + // if this worked, it would be very bad because `T` can be (e.g.) a Coin + public copy_inner(s: &Self.S): T { // should get flagged w/ constraint not satisfied + let t: &T; + label b0: + &S.V { t: t } = *move(s); + return *move(t); + } +} + +//# publish +module 0x43.M2 { + enum S has copy { V{ t: T } } + + // note: T does not have copy + // if this worked, it would be very bad because `T` can be (e.g.) a Coin + public copy_direct(s: &Self.S): Self.S { // should get flagged w/ constraint not satisfied + label b0: + return *move(s); + } +} + +//# publish +module 0x43.M3 { + enum S has store { V{ t: T } } + + // note: T does not have store + // if this worked, it would be very bad because `T` can be (e.g.) a hot potato + public store_inner(s: &mut Self.S, t: T) { // should get flagged w/ constraint not satisfied + let tt: &mut T; + label b0: + &mut S.V { t: tt } = move(s); + return; + } +} + +//# publish +module 0x43.M4 { + enum S { V{ t: T } } + + public bad_sig(s: &Self.S) { // should get flagged w/ constraint not satisfied + label b0: + return; + } + + public call(): Self.S { + let x: Self.S; + label b0: + x = S.V { t: 10 }; + Self.bad_sig(&x); + return move(x); + } +} + +//# publish +module 0x43.M5 { + enum S { V{ t: T } } + + public bad_sig(s: &Self.S) { // should get flagged w/ constraint not satisfied + label b0: + return; + } + + public call(s: signer): Self.S { + let x: Self.S; + label b0: + x = S.V { t: move(s) }; + Self.bad_sig(&x); + return move(x); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp index f3a7de94e648da..b60171276fcd01 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-10: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } + +task 1 'publish'. lines 12-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x2::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir index 69598020b7116d..9a6b6d45c5712c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir @@ -8,3 +8,14 @@ module 0x1.M { return; } } + +//# publish +module 0x2.M { + enum Coin { V { value: u64 } } + t(): Self.Coin { + label b0: + // cannot pop without the drop ability + _ = Coin.V { value: 0 }; + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp index f8cfe0681b77f7..37f8c1746afbf3 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-14: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 1)], } + +task 1 'publish'. lines 16-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::Test'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x43::Test, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir index 4c7aa6e7a2ebee..84a25682c804d5 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir @@ -12,3 +12,17 @@ module 0x42.Test { } } + +//# publish + +module 0x43.Test { + struct B { b: bool } + enum A { V { b: bool } } + enum T { V { ft: Self.B } } + + public t1(x: Self.A): Self.T { + label b0: + // arg type mismatch + return T.V{ft: move(x)}; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp index 63337530dac687..bf517ace6f8e74 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp @@ -1,4 +1,4 @@ -processed 4 tasks +processed 6 tasks task 0 'publish'. lines 1-13: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { @@ -35,3 +35,21 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } + +task 4 'publish'. lines 55-67: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 5 'publish'. lines 69-80: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x2::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir index e0e97d3a4cf952..2c97f30353bde5 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir @@ -51,3 +51,30 @@ module 0x1.M2 { return move(r); } } + +//# publish +module 0x2.M { + enum R { V { flag: bool } } + + // Type checking is done before memory safety checks + // wrong return type + t1(): bool { + let c: Self.R; + label b0: + c = R.V { flag: false }; + return 0; + } +} + +//# publish +module 0x2.M { + enum R { V { flag: bool } } + + t1(): u64 { + let c: Self.R; + label b0: + c = R.V { flag: false }; + // unused resource + return 0; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp index 65b2121aeca2cb..42d184643827ef 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp @@ -1,4 +1,4 @@ -processed 5 tasks +processed 10 tasks task 0 'publish'. lines 1-12: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { @@ -44,3 +44,48 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } + +task 5 'publish'. lines 64-75: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M1'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x2::M1, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 6 'publish'. lines 77-88: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M2'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x2::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'publish'. lines 90-100: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M3'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x2::M3, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 8 'publish'. lines 102-113: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M4'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x2::M4, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 9 'publish'. lines 115-125: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::M5'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x2::M5, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir index dbcbbe7cf485ab..f5b7d8b2111dd0 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir @@ -60,3 +60,66 @@ module 0x1.M5 { return (copy(s), move(s)); } } + +//# publish +// ensure that generic enums instantiated with enum types behave like resources +module 0x2.M1 { + enum MyResource { V{ b: bool } } + enum S { V{ t: T } } + + // verifer should reject; didn't move resource; + public p(s: Self.S) { + label b0: + return; + } +} + +//# publish +module 0x2.M2 { + enum MyResource { V{ b: bool } } + enum S { V{ t: T } } + + // verifier should reject; drops s2 on the floor + public p(s1: Self.S, s2: Self.S): Self.S { + label b0: + s1 = move(s2); + return move(s1); + } +} + +//# publish +module 0x2.M3 { + enum MyResource { V{ b: bool } } + enum S { V{ t: T } } + + // verifier should reject; copies s + public p(s: &Self.S): Self.S { + label b0: + return *move(s); + } +} + +//# publish +module 0x2.M4 { + enum MyResource { V{ b: bool } } + enum S { V{ t: T } } + + // verifier should reject; drops s1 on the floor + public p(s1: &mut Self.S, s2: Self.S) { + label b0: + *move(s1) = move(s2); + return; + } +} + +//# publish +module 0x2.M5 { + enum MyResource { V{ b: bool } } + enum S { V{ t: T } } + + // verifier should reject; copies s + public p(s: Self.S): Self.S * Self.S { + label b0: + return (copy(s), move(s)); + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.exp new file mode 100644 index 00000000000000..1b164f1a5379f9 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.exp @@ -0,0 +1,82 @@ +processed 9 tasks + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByValue, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'publish'. lines 14-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByImmRef, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'publish'. lines 27-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByMutRef, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3 'publish'. lines 40-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByValue, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 4 'publish'. lines 53-64: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByImmRef, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 5 'publish'. lines 66-77: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByMutRef, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 6 'publish'. lines 79-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByValue, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'publish'. lines 92-103: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByImmRef, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 8 'publish'. lines 105-116: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: GENERIC_MEMBER_OPCODE_MISMATCH, + sub_status: None, + location: 0x2::ByMutRef, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.mvir new file mode 100644 index 00000000000000..92696f92590fac --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_non_generically.mvir @@ -0,0 +1,116 @@ +//# publish +module 0x2.ByValue { + enum Foo { V { x: T } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: T } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: T } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByValue { + enum Foo { V { x: T } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: T } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: T } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByValue { + enum Foo { V { x: T } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: T } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: T } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.exp new file mode 100644 index 00000000000000..888a1ba190653c --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.exp @@ -0,0 +1,82 @@ +processed 9 tasks + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByValue, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'publish'. lines 14-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByImmRef, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'publish'. lines 27-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByMutRef, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3 'publish'. lines 40-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByValue, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 4 'publish'. lines 53-64: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByImmRef, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 5 'publish'. lines 66-77: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByMutRef, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 6 'publish'. lines 79-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByValue, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'publish'. lines 92-103: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByImmRef, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 8 'publish'. lines 105-116: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::ByMutRef, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.mvir new file mode 100644 index 00000000000000..7def0b74b3b5c7 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_generic_enum_wrong_type_arg.mvir @@ -0,0 +1,116 @@ +//# publish +module 0x2.ByValue { + enum Foo { V { x: T } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: T } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: T } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByValue { + enum Foo { V { x: T } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: T } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: T } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByValue { + enum Foo { V { x: T } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: T } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: T } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.exp new file mode 100644 index 00000000000000..eeda9dd87477cd --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.exp @@ -0,0 +1,82 @@ +processed 9 tasks + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByValue, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 1 'publish'. lines 14-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByImmRef, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 27-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByMutRef, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 40-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByValue, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 4 'publish'. lines 53-64: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByImmRef, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 5 'publish'. lines 66-77: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByMutRef, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 6 'publish'. lines 79-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByValue'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByValue, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 7 'publish'. lines 92-103: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByImmRef'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByImmRef, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} + +task 8 'publish'. lines 105-116: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::ByMutRef'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x2::ByMutRef, + indices: [(Signature, 2), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.mvir new file mode 100644 index 00000000000000..7044e1a21962bd --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_non_generic_enum_generically.mvir @@ -0,0 +1,116 @@ +//# publish +module 0x2.ByValue { + enum Foo { V { x: u64 } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: u64 } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: u64 } } + + foo(y: Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByValue { + enum Foo { V { x: u64 } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: u64 } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: u64 } } + + foo(y: &Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByValue { + enum Foo { V { x: u64 } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByImmRef { + enum Foo { V { x: u64 } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + &Foo.V { x } = move(y); + return; + } +} + +//# publish +module 0x2.ByMutRef { + enum Foo { V { x: u64 } } + + foo(y: &mut Self.Foo) { + let x: u64; + label b0: + // invalid + &mut Foo.V { x } = move(y); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp index 5d92c423f3fd86..457ace9c4acb66 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp @@ -1 +1 @@ -processed 2 tasks +processed 4 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir index 552d9d15e7c6ec..1e667859b95237 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir @@ -49,3 +49,55 @@ label b0: return; } } + +//# publish +module 0x3.Test { + enum X { V{ b: bool } } + enum T { V{ i: u64, x: Self.X, b: bool } } + + public new_x(): Self.X { + label b0: + return X.V { b: true }; + } + + public new_t(x: Self.X): Self.T { + label b0: + return T.V { i: 0, x: move(x), b: false }; + } + + public destroy_x(x: Self.X) { + let b: bool; + label b0: + X.V { b } = move(x); + return; + } + + // can unpack a resource and return it + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + T.V { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } + +} + +//# run +module 0x43.m { +import 0x3.Test; + +entry foo() { + let x: Test.X; + let i: u64; + let t: Test.T; + let b: bool; +label b0: + x = Test.new_x(); + t = Test.new_t(move(x)); + i, x, b = Test.destroy_t(move(t)); + Test.destroy_x(move(x)); + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp index 776bf60546e181..50ce6b9144a044 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-19: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 1)], } + +task 1 'publish'. lines 21-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::Test'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x2::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir index 7f64ff16904ac5..d2e7f81d57c8fa 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir @@ -17,3 +17,22 @@ module 0x1.Test { } } + +//# publish +module 0x2.Test { + enum X { V { b: bool } } + enum T { V { b: bool } } + + public new_t(): Self.T { + label b0: + return T.V { b: true }; + } + + public destroy_t(t: Self.T) { + let b: bool; + label b0: + // wrong struct in unpack + X.V { b } = move(t); + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp index 5d92c423f3fd86..457ace9c4acb66 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp @@ -1 +1 @@ -processed 2 tasks +processed 4 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir index 0cd8850fe57fea..8f6d235d13bf46 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir @@ -27,3 +27,32 @@ label b0: return; } } + +//# publish +module 0x43.Test { + enum T has drop {V {fint: u64, fv: bool} } + + public t1(fint: u64, fv: bool): Self.T { + label b0: + return T.V{fint: move(fint), fv: move(fv)}; + } + + public t2(fint: u64): Self.T { + label b0: + return T.V{fint: move(fint), fv: false}; + } +} + +//# run +module 0x43.m { +import 0x43.Test; + +entry foo() { + let t1: Test.T; + let t2: Test.T; +label b0: + t1 = Test.t1(0, false); + t2 = Test.t2(0); + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp index 6603cc3260298e..bed47e219a539c 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp @@ -1,4 +1,4 @@ -processed 1 task +processed 2 tasks task 0 'publish'. lines 1-10: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 1)], } + +task 1 'publish'. lines 12-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::Test'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x43::Test, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir index 9e987f11c3a8b2..c3d75cab595282 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir @@ -8,3 +8,14 @@ module 0x42.Test { return T{fint: false}; } } + +//# publish +module 0x43.Test { + enum T{V {fint: u64} } + + public t1(): Self.T { + label b0: + // arg type mismatch + return T.V{fint: false}; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp index df341dbc495459..219cc64871ae65 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp @@ -1,4 +1,4 @@ -processed 2 tasks +processed 4 tasks task 1 'run'. lines 18-33: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { @@ -8,3 +8,12 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } + +task 3 'run'. lines 51-66: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::m'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x43::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir index 594869d2567114..ed1369f7f71434 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir @@ -31,3 +31,36 @@ label b0: return; } } + +//# publish +module 0x43.A { + enum Coin has store { V{ value: u64 } } + enum T { V{ g: Self.Coin } } + + public zero(): Self.Coin { + label b0: + return Coin.V { value: 0 }; + } + public new(g: Self.Coin): Self.T { + label b0: + return T.V {g: move(g)}; + } + +} + +//# run + +module 0x43.m { +import 0x43.A; + +entry foo() { + let zero_resource: A.Coin; + let s: A.T; +label b0: + zero_resource = A.zero(); + // unused resources + s = A.new(move(zero_resource)); + + return; +} +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.exp new file mode 100644 index 00000000000000..fd8e982e072254 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.exp @@ -0,0 +1,91 @@ +processed 11 tasks + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_SWITCH_BAD_OPERAND, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'publish'. lines 16-29: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_SWITCH_BAD_OPERAND, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'publish'. lines 31-44: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_SWITCH_BAD_OPERAND, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3 'publish'. lines 46-59: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_TYPE_MISMATCH, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 4 'publish'. lines 61-74: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_SWITCH_BAD_OPERAND, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 5 'publish'. lines 77-92: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_TYPE_MISMATCH, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 6 'publish'. lines 94-109: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: ENUM_SWITCH_BAD_OPERAND, + sub_status: None, + location: 0x2::O, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 8 'publish'. lines 127-141: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::P'. Got VMError: { + major_status: ENUM_TYPE_MISMATCH, + sub_status: None, + location: 0x2::P, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 9 'publish'. lines 143-157: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::P'. Got VMError: { + major_status: ENUM_TYPE_MISMATCH, + sub_status: None, + location: 0x2::P, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 10 'publish'. lines 159-173: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::P'. Got VMError: { + major_status: ENUM_TYPE_MISMATCH, + sub_status: None, + location: 0x2::P, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.mvir new file mode 100644 index 00000000000000..743a66f0c87185 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_invalid_head_type.mvir @@ -0,0 +1,173 @@ +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &mut Self.Foo) { + label b0: + // mut ref is not allowed + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: Self.Foo) { + label b0: + // by value is not allowed + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: u64) { + label b0: + // non-enum is not allowed + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &u64) { + label b0: + // non-enum is not allowed + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &mut u64) { + label b0: + // non-enum is not allowed + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + + +//# publish +module 0x2.O { + struct Bar { x: bool } + + enum Foo { V { x: T } } + + foo(x: &Self.Bar) { + label b0: + // type mismatch + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + struct Bar { x: bool } + + enum Foo { V { x: T } } + + foo(x: &mut Self.Bar) { + label b0: + // type mismatch and invalid operand + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.P { + enum Foo { V { x: T } } + enum Bar { V { x: T } } + + foo(x: &Self.Bar) { + label b0: + // valid + variant_switch Bar move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.P { + enum Foo { V { x: T } } + enum Bar { V { x: T } } + + foo(x: &Self.Foo) { + label b0: + // type mismatch + variant_switch Bar move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.P { + enum Foo { V { x: T } } + enum Bar { V { x: u64 } } + + foo(x: &Self.Foo) { + label b0: + // type mismatch + variant_switch Bar move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.P { + enum Foo { V { x: T } } + enum Bar { V { x: u64 } } + + foo(x: &Self.Bar) { + label b0: + // type mismatch + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.exp new file mode 100644 index 00000000000000..d4f8d00ce9bc72 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.exp @@ -0,0 +1,19 @@ +processed 3 tasks + +task 1 'publish'. lines 16-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_ENUM_SWITCH, + sub_status: None, + location: undefined, + indices: [(VariantTag, 0)], + offsets: [], +} + +task 2 'publish'. lines 30-43: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000002::O'. Got VMError: { + major_status: INVALID_ENUM_SWITCH, + sub_status: None, + location: undefined, + indices: [(VariantTag, 1)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.mvir new file mode 100644 index 00000000000000..f229f4fb895bed --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_partial_enum_switch.mvir @@ -0,0 +1,43 @@ +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &Self.Foo) { + label b0: + // valid + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T } } + + foo(x: &Self.Foo) { + label b0: + // invalid + variant_switch Foo move(x) { + }; + label b1: + return; + } +} + +//# publish +module 0x2.O { + enum Foo { V { x: T }, X { } } + + foo(x: &Self.Foo) { + label b0: + // invalid + variant_switch Foo move(x) { + V : b1, + }; + label b1: + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.exp new file mode 100644 index 00000000000000..fc5a4436b29d40 --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.mvir new file mode 100644 index 00000000000000..a216da66a7ffeb --- /dev/null +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/variant_switch_valid_head_type.mvir @@ -0,0 +1,44 @@ +//# publish +module 0x2.A { + enum Foo has drop { V { x: T } } + + foo(x: Self.Foo) { + label b0: + // valid + variant_switch Foo (&x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.B { + enum Foo { V { x: T } } + + foo(x: &Self.Foo) { + label b0: + // valid + variant_switch Foo copy(x) { + V : b1, + }; + label b1: + return; + } +} + +//# publish +module 0x2.C { + enum Foo { V { x: T } } + + foo(x: &mut Self.Foo) { + label b0: + // mut ref is not allowed + variant_switch Foo freeze(copy(x)) { + V : b1, + }; + label b1: + return; + } +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp index 1417dd4262bee2..a1586d2c211c10 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp @@ -1,4 +1,4 @@ -processed 3 tasks +processed 6 tasks task 0 'publish'. lines 1-10: Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { @@ -26,3 +26,30 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 0), (FunctionHandle, 0)], offsets: [], } + +task 3 'publish'. lines 34-43: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 4 'publish'. lines 45-54: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 5 'publish'. lines 56-65: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000043::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x43::M3, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir index 4568022f97e81f..30a34bde8d05b2 100644 --- a/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir +++ b/external-crates/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir @@ -30,3 +30,36 @@ module 0x42.M3 { return; } } + +//# publish +module 0x43.M1 { + enum S { V { t: T } } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: vector>): vector> { + label b0: + return move(v); + } +} + +//# publish +module 0x43.M2 { + enum S { V { t: T } } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: &vector>) { + label b0: + return; + } +} + +//# publish +module 0x43.M3 { + enum S { V { t: T } } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: &mut vector>) { + label b0: + return; + } +} 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 b1840c75983876..3da00d8143d5be 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 @@ -7,6 +7,8 @@ struct Coin { value: u64 } + + public value(Arg0: &Coin): u64 { B0: 0: MoveLoc[0](Arg0: &Coin) @@ -15,6 +17,7 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: ReadRef 5: Ret + } public deposit(Arg0: &mut Coin, Arg1: Coin) { L0: loc2: &Coin @@ -44,6 +47,7 @@ B0: 19: Unpack[0](Coin) 20: StLoc[7](loc5: u64) 21: Ret + } } @@ -52,13 +56,17 @@ task 1 'print-bytecode'. lines 33-46: 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 dac26494f683b1..e0e945b77e58c7 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 @@ -5,10 +5,13 @@ task 0 'print-bytecode'. lines 1-9: module 1.m { + + entry foo() { L0: loc0: u64 B0: 0: Ret + } } 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 97170bbb489dc9..cf1ea23753d14b 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,6 +5,8 @@ task 0 'print-bytecode'. lines 1-13: module e.Expressions { + + binary_add() { L0: loc0: u64 L1: loc1: u64 @@ -19,5 +21,6 @@ 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 84c506ba50a861..cf5b2fa6429a60 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-13: module 1.m { + + entry foo() { L0: loc0: u64 L1: loc1: &u64 @@ -16,6 +18,7 @@ B0: 4: MoveLoc[1](loc1: &u64) 5: Pop 6: Ret + } } @@ -24,6 +27,8 @@ task 1 'print-bytecode'. lines 15-28: module 2.m { + + entry foo() { L0: loc0: u64 L1: loc1: &u64 @@ -36,6 +41,7 @@ B0: 4: ImmBorrowLoc[1](loc1: &u64) 5: StLoc[2](loc2: &u64) 6: Ret + } } @@ -46,6 +52,8 @@ struct T { u: u64 } + + f(Arg0: &T) { B0: 0: MoveLoc[0](Arg0: &T) @@ -54,6 +62,7 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: Pop 5: Ret + } g(Arg0: &mut T) { B0: @@ -63,6 +72,7 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: Pop 5: Ret + } public h(Arg0: &mut T) { B0: @@ -72,6 +82,7 @@ B0: 3: MoveLoc[1](loc0: &mut u64) 4: Pop 5: Ret + } } @@ -82,6 +93,8 @@ struct T { u: Ty0 } + + f(Arg0: &T) { B0: 0: MoveLoc[0](Arg0: &T) @@ -90,6 +103,7 @@ B0: 3: MoveLoc[1](loc0: &u64) 4: Pop 5: Ret + } g(Arg0: &mut T) { B0: @@ -99,6 +113,7 @@ B0: 3: MoveLoc[1](loc0: &u128) 4: Pop 5: Ret + } } 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 9532158c006a64..bc883934a76a0f 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-12: module 1.m { + + entry foo() { L0: loc0: u64 L1: loc1: &mut u64 @@ -17,6 +19,7 @@ B0: 5: MoveLoc[1](loc1: &mut u64) 6: WriteRef 7: Ret + } } @@ -27,6 +30,8 @@ struct FooCoin { value: u64 } + + public borrow_mut_field(Arg0: &mut FooCoin) { B0: 0: MoveLoc[0](Arg0: &mut FooCoin) @@ -35,6 +40,7 @@ B0: 3: MoveLoc[1](loc0: &mut u64) 4: Pop 5: Ret + } } @@ -45,6 +51,8 @@ struct FooCoin { value: u64 } + + public borrow_mut_field(Arg0: &mut FooCoin
) { B0: 0: MoveLoc[0](Arg0: &mut FooCoin
) @@ -53,5 +61,6 @@ 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/builtins/borrow_global.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp new file mode 100644 index 00000000000000..5def7c42c12222 --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp @@ -0,0 +1,30 @@ +processed 4 tasks + +task 0 'print-bytecode'. lines 1-14: +// Move bytecode v7 +module 1d6.M { +use 0000000000000000000000000000000000000000000000000000000000000001::signer; + + +struct T has key { + b: bool +} + + + +f(Arg0: signer) { +B0: + 0: ImmBorrowLoc[0](Arg0: signer) + 1: Call signer::address_of(&signer): address + 2: ImmBorrowGlobal[0](T) + 3: StLoc[1](loc0: &T) + 4: Ret + +} +} + +task 2 'print-bytecode'. lines 21-33: +Error: Missing struct definition for T + +task 3 'print-bytecode'. lines 35-46: +Error: Missing struct definition for T diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp new file mode 100644 index 00000000000000..a5867ce1aecebe --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp @@ -0,0 +1,30 @@ +processed 4 tasks + +task 0 'print-bytecode'. lines 1-14: +// Move bytecode v7 +module 1d6.M { +use 0000000000000000000000000000000000000000000000000000000000000001::signer; + + +struct T has key { + b: bool +} + + + +f(Arg0: signer) { +B0: + 0: ImmBorrowLoc[0](Arg0: signer) + 1: Call signer::address_of(&signer): address + 2: MutBorrowGlobal[0](T) + 3: StLoc[1](loc0: &mut T) + 4: Ret + +} +} + +task 2 'print-bytecode'. lines 21-33: +Error: Missing struct definition for T + +task 3 'print-bytecode'. lines 35-46: +Error: Missing struct definition for T diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp new file mode 100644 index 00000000000000..2a789ee1189664 --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp @@ -0,0 +1,27 @@ +processed 4 tasks + +task 0 'print-bytecode'. lines 1-11: +// Move bytecode v7 +module 5d5.M { +struct T has key { + b: bool +} + + + +f() { +L0: loc0: bool +B0: + 0: LdU64(4) + 1: Exists[0](T) + 2: StLoc[0](loc0: bool) + 3: Ret + +} +} + +task 2 'print-bytecode'. lines 18-27: +Error: Missing struct definition for T + +task 3 'print-bytecode'. lines 29-37: +Error: Missing struct definition for T diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp new file mode 100644 index 00000000000000..31aea2e67aae30 --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp @@ -0,0 +1,33 @@ +processed 4 tasks + +task 0 'print-bytecode'. lines 1-16: +// Move bytecode v7 +module 2d6.M { +struct T has key { + b: bool +} + + + +public new(): T { +B0: + 0: LdTrue + 1: Pack[0](T) + 2: Ret + +} +f(Arg0: signer) { +B0: + 0: ImmBorrowLoc[0](Arg0: signer) + 1: Call new(): T + 2: MoveTo[0](T) + 3: Ret + +} +} + +task 2 'print-bytecode'. lines 29-39: +Error: Missing struct definition for T + +task 3 'print-bytecode'. lines 41-49: +Error: Missing struct definition for T 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 ec636e764af20a..054c46169f6ebd 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-33: module 1.m { + + entry foo() { L0: loc0: vector L1: loc1: &vector @@ -13,12 +15,12 @@ L3: loc3: u64 L4: loc4: &u64 L5: loc5: &mut u64 B0: - 0: VecPack(2, 0) + 0: VecPack(1, 0) 1: StLoc[0](loc0: vector) 2: ImmBorrowLoc[0](loc0: vector) 3: StLoc[1](loc1: &vector) 4: CopyLoc[1](loc1: &vector) - 5: VecLen(2) + 5: VecLen(1) 6: StLoc[3](loc3: u64) 7: MoveLoc[1](loc1: &vector) 8: Pop @@ -26,36 +28,37 @@ B0: 10: StLoc[2](loc2: &mut vector) 11: CopyLoc[2](loc2: &mut vector) 12: LdU64(0) - 13: VecPushBack(2) + 13: VecPushBack(1) 14: CopyLoc[2](loc2: &mut vector) 15: LdU64(1) - 16: VecPushBack(2) + 16: VecPushBack(1) 17: CopyLoc[2](loc2: &mut vector) 18: LdU64(0) - 19: VecImmBorrow(2) + 19: VecImmBorrow(1) 20: StLoc[4](loc4: &u64) 21: MoveLoc[4](loc4: &u64) 22: Pop 23: CopyLoc[2](loc2: &mut vector) 24: LdU64(1) - 25: VecMutBorrow(2) + 25: VecMutBorrow(1) 26: StLoc[5](loc5: &mut u64) 27: MoveLoc[5](loc5: &mut u64) 28: Pop 29: CopyLoc[2](loc2: &mut vector) 30: LdU64(0) 31: LdU64(1) - 32: VecSwap(2) + 32: VecSwap(1) 33: CopyLoc[2](loc2: &mut vector) - 34: VecPopBack(2) + 34: VecPopBack(1) 35: Pop 36: CopyLoc[2](loc2: &mut vector) - 37: VecPopBack(2) + 37: VecPopBack(1) 38: Pop 39: MoveLoc[2](loc2: &mut vector) 40: Pop 41: MoveLoc[0](loc0: vector) - 42: VecUnpack(2, 0) + 42: VecUnpack(1, 0) 43: Ret + } } 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 9244d56a3d488b..5c02c5ed49fb6a 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-13: module 1.m { + + entry foo() { L0: loc0: u64 L1: loc1: u64 @@ -23,5 +25,6 @@ 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/pack.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/expressions/pack.exp index de02fcd4acf8bb..94e70515d3a39b 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 @@ -7,11 +7,14 @@ struct T { u: u64 } + + f(): T { B0: 0: LdU64(0) 1: Pack[0](T) 2: Ret + } } 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 8d57922ac0d1f7..0775b4ac1e415a 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 @@ -7,11 +7,14 @@ struct T { b: bool } + + new(): T { B0: 0: LdTrue 1: Pack[0](T) 2: Ret + } f() { L0: loc0: T @@ -23,6 +26,7 @@ B0: 3: Unpack[0](T) 4: StLoc[1](loc1: bool) 5: Ret + } } 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 beb16ac890e0bb..900e583e465e79 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-10: module 1.m { + + entry foo() { L0: loc0: u64 B0: @@ -20,5 +22,6 @@ B1: 8: Abort B2: 9: Ret + } } 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 new file mode 100644 index 00000000000000..405466b11b0fdc --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.exp @@ -0,0 +1,107 @@ +processed 1 task + +task 0 'print-bytecode'. lines 1-71: +// Move bytecode v7 +module 3d8.M { + + +enum T has drop { + X { }, + Y { f: u64 } +} + +f(): T { +B0: + 0: PackVariant(VariantHandleIndex(0)) + 1: Ret + +} +f1(): T { +L0: loc0: T +L1: loc1: u64 +B0: + 0: LdU64(0) + 1: PackVariant(VariantHandleIndex(1)) + 2: StLoc[0](loc0: T) + 3: MoveLoc[0](loc0: T) + 4: UnpackVariant(VariantHandleIndex(1)) + 5: StLoc[1](loc1: u64) + 6: PackVariant(VariantHandleIndex(0)) + 7: Ret + +} +f2(): T { +L0: loc0: T +L1: loc1: u64 +B0: + 0: LdU64(0) + 1: PackVariant(VariantHandleIndex(1)) + 2: StLoc[0](loc0: T) + 3: ImmBorrowLoc[0](loc0: T) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: LdU64(1) + 6: Ret +B2: + 7: MoveLoc[0](loc0: T) + 8: UnpackVariant(VariantHandleIndex(1)) + 9: StLoc[1](loc1: u64) + 10: MoveLoc[1](loc1: u64) + 11: Ret +Jump tables: +[0]: variant_switch T { + Variant0 => jump 5 + Variant1 => jump 7 + } +} +f3(): T { +L0: loc0: T +L1: loc1: u64 +L2: loc2: &u64 +B0: + 0: LdU64(0) + 1: PackVariant(VariantHandleIndex(1)) + 2: StLoc[0](loc0: T) + 3: ImmBorrowLoc[0](loc0: T) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: LdU64(1) + 6: Ret +B2: + 7: ImmBorrowLoc[0](loc0: T) + 8: UnpackVariantImmRef(VariantHandleIndex(1)) + 9: StLoc[2](loc2: &u64) + 10: LdU64(0) + 11: Ret +Jump tables: +[0]: variant_switch T { + Variant0 => jump 5 + Variant1 => jump 7 + } +} +f4(): T { +L0: loc0: T +L1: loc1: u64 +L2: loc2: &mut u64 +B0: + 0: LdU64(0) + 1: PackVariant(VariantHandleIndex(1)) + 2: StLoc[0](loc0: T) + 3: ImmBorrowLoc[0](loc0: T) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: LdU64(1) + 6: Ret +B2: + 7: MutBorrowLoc[0](loc0: T) + 8: UnpackVariantMutRef(VariantHandleIndex(1)) + 9: StLoc[2](loc2: &mut u64) + 10: LdU64(0) + 11: Ret +Jump tables: +[0]: variant_switch T { + Variant0 => jump 5 + Variant1 => jump 7 + } +} +} diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.mvir new file mode 100644 index 00000000000000..b5b94fb4dc2857 --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/bytecode-generation/statements/enums.mvir @@ -0,0 +1,71 @@ +//# print-bytecode +module 0x3d8.M { + enum T has drop { + X { }, + Y { f: u64 }, + } + + f(): Self.T { + label b0: + return T.X { }; + } + + f1(): Self.T { + let x: Self.T; + let f: u64; + label b0: + x = T.Y { f: 0 }; + T.Y { f } = move(x); + return T.X { }; + } + + f2(): Self.T { + let x: Self.T; + let f: u64; + label b0: + x = T.Y { f: 0 }; + variant_switch T (&x) { + X : b1, + Y : b2, + }; + label b1: + return 1; + label b2: + T.Y { f } = move(x); + return move(f); + } + + f3(): Self.T { + let x: Self.T; + let f: u64; + let g: &u64; + label b0: + x = T.Y { f: 0 }; + variant_switch T (&x) { + X : b1, + Y : b2, + }; + label b1: + return 1; + label b2: + &T.Y { f: g } = &x; + return 0; + } + + f4(): Self.T { + let x: Self.T; + let f: u64; + let g: &mut u64; + label b0: + x = T.Y { f: 0 }; + variant_switch T (&x) { + X : b1, + Y : b2, + }; + label b1: + return 1; + label b2: + &mut T.Y { f: g } = &mut x; + return 0; + } +} 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 7e2bd210c237a9..4211ebb9e60c4d 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 @@ -5,9 +5,12 @@ task 0 'print-bytecode'. lines 1-8: module 1.m { + + entry foo() { B0: 0: Branch(0) + } } @@ -16,11 +19,14 @@ task 1 'print-bytecode'. lines 10-19: module 2.m { + + entry foo() { B0: 0: Branch(1) B1: 1: Branch(0) + } } 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 b8a5eaa52e1f83..7f285c05a9e123 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-24: module 1.m { + + entry foo() { L0: loc0: u64 B0: @@ -24,6 +26,7 @@ B3: 10: Branch(11) B4: 11: Ret + } } @@ -32,6 +35,8 @@ task 1 'print-bytecode'. lines 26-45: module 2.m { + + entry foo() { L0: loc0: u64 B0: @@ -48,6 +53,7 @@ B2: 8: StLoc[0](loc0: u64) B3: 9: Ret + } } @@ -56,6 +62,8 @@ task 2 'print-bytecode'. lines 47-65: module 3.m { + + entry foo() { L0: loc0: u64 B0: @@ -81,6 +89,7 @@ B4: 15: StLoc[0](loc0: u64) B5: 16: Ret + } } @@ -89,6 +98,8 @@ task 3 'print-bytecode'. lines 67-82: module 4.m { + + entry foo() { L0: loc0: u64 B0: @@ -106,5 +117,6 @@ B2: 9: Ret B3: 10: Ret + } } 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 8044824dc787db..f842c279967b71 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 @@ -5,6 +5,8 @@ task 0 'print-bytecode'. lines 1-20: module 1.m { + + entry foo() { L0: loc0: u64 B0: @@ -23,6 +25,7 @@ B2: 10: Branch(2) B3: 11: Ret + } } @@ -31,6 +34,8 @@ task 1 'print-bytecode'. lines 22-36: module 2.m { + + entry foo() { L0: loc0: u64 B0: @@ -45,6 +50,7 @@ B3: 5: Branch(2) B4: 6: Ret + } } @@ -53,6 +59,8 @@ task 2 'print-bytecode'. lines 38-48: module 3.m { + + entry foo() { B0: 0: LdTrue @@ -61,6 +69,7 @@ B1: 2: Branch(3) B2: 3: Ret + } } @@ -69,6 +78,8 @@ task 3 'print-bytecode'. lines 50-63: module 4.m { + + entry foo() { B0: 0: Branch(2) @@ -80,5 +91,6 @@ B3: 3: Branch(0) B4: 4: Ret + } } 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 72bc6b6525567e..af6632ccece65f 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 @@ -5,9 +5,12 @@ task 0 'print-bytecode'. lines 1-8: module 1.m { + + entry foo() { B0: 0: Ret + } } @@ -16,9 +19,12 @@ task 1 'print-bytecode'. lines 10-18: module 2.m { + + entry foo() { B0: 0: Ret + } } @@ -27,9 +33,12 @@ task 2 'print-bytecode'. lines 20-26: module 3.m { + + entry foo() { B0: 0: Ret + } } @@ -38,9 +47,12 @@ task 3 'print-bytecode'. lines 28-35: module 4.m { + + entry foo() { B0: 0: Ret + } } @@ -52,8 +64,11 @@ task 5 'print-bytecode'. lines 48-58: module 6.m { + + entry foo() { B0: 0: Ret + } } 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 72bc6b6525567e..af6632ccece65f 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 @@ -5,9 +5,12 @@ task 0 'print-bytecode'. lines 1-8: module 1.m { + + entry foo() { B0: 0: Ret + } } @@ -16,9 +19,12 @@ task 1 'print-bytecode'. lines 10-18: module 2.m { + + entry foo() { B0: 0: Ret + } } @@ -27,9 +33,12 @@ task 2 'print-bytecode'. lines 20-26: module 3.m { + + entry foo() { B0: 0: Ret + } } @@ -38,9 +47,12 @@ task 3 'print-bytecode'. lines 28-35: module 4.m { + + entry foo() { B0: 0: Ret + } } @@ -52,8 +64,11 @@ task 5 'print-bytecode'. lines 48-58: module 6.m { + + entry foo() { B0: 0: Ret + } } diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.exp b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.exp new file mode 100644 index 00000000000000..356f8e6040c3b6 --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'print-bytecode'. lines 1-6: +Error: ParserError: Invalid Token: expected Tok::NameValue diff --git a/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.mvir b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.mvir new file mode 100644 index 00000000000000..a52c0b7ed3f17b --- /dev/null +++ b/external-crates/move/crates/move-ir-compiler-transactional-tests/tests/parsing/enums.mvir @@ -0,0 +1,6 @@ +//# print-bytecode +module 0x3d8.M { + enum T { V { } } + // Struct declarations need to be before enum declarations. + struct T { x: u64, } +} diff --git a/external-crates/move/crates/move-ir-compiler/src/unit_tests/cfg_tests.rs b/external-crates/move/crates/move-ir-compiler/src/unit_tests/cfg_tests.rs index 67a73a7f914ca1..40337f2a765dcb 100644 --- a/external-crates/move/crates/move-ir-compiler/src/unit_tests/cfg_tests.rs +++ b/external-crates/move/crates/move-ir-compiler/src/unit_tests/cfg_tests.rs @@ -4,7 +4,7 @@ use crate::unit_tests::testutils::compile_module_string; use move_abstract_interpreter::control_flow_graph::{ControlFlowGraph, VMControlFlowGraph}; -use move_binary_format::file_format::Bytecode; +use move_binary_format::file_format::{Bytecode, VariantJumpTable}; #[test] fn cfg_compile_script_ret() { @@ -14,8 +14,8 @@ fn cfg_compile_script_ret() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); cfg.display(); assert_eq!(cfg.blocks().len(), 1); assert_eq!(cfg.num_blocks(), 1); @@ -36,8 +36,8 @@ fn cfg_compile_script_let() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 1); assert_eq!(cfg.num_blocks(), 1); assert_eq!(cfg.reachable_from(0).len(), 1); @@ -60,8 +60,8 @@ fn cfg_compile_if() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); assert_eq!(cfg.reachable_from(0).len(), 4); @@ -87,8 +87,8 @@ fn cfg_compile_if_else() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); assert_eq!(cfg.reachable_from(0).len(), 4); @@ -110,8 +110,8 @@ fn cfg_compile_if_else_with_else_return() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); assert_eq!(cfg.reachable_from(0).len(), 4); @@ -141,8 +141,8 @@ fn cfg_compile_nested_if() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 7); assert_eq!(cfg.num_blocks(), 7); assert_eq!(cfg.reachable_from(8).len(), 3); @@ -164,8 +164,8 @@ fn cfg_compile_if_else_with_if_return() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); assert_eq!(cfg.reachable_from(0).len(), 4); @@ -187,8 +187,8 @@ fn cfg_compile_if_else_with_two_returns() { return; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); assert_eq!(cfg.reachable_from(0).len(), 3); @@ -213,8 +213,8 @@ fn cfg_compile_if_else_with_else_abort() { abort 0; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); cfg.display(); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); @@ -237,8 +237,8 @@ fn cfg_compile_if_else_with_if_abort() { abort 0; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); cfg.display(); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); @@ -261,8 +261,8 @@ fn cfg_compile_if_else_with_two_aborts() { abort 0; } } "; - let code = compile_module_with_single_function(text); - let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code); + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); cfg.display(); assert_eq!(cfg.blocks().len(), 4); assert_eq!(cfg.num_blocks(), 4); @@ -272,13 +272,179 @@ fn cfg_compile_if_else_with_two_aborts() { assert_eq!(cfg.reachable_from(8).len(), 1); } -fn compile_module_with_single_function(text: &str) -> Vec { +#[test] +fn cfg_compile_variant_switch_simple() { + let text = " + module 0x42.m { + enum X has drop { V1 { x: u64 }, V2 { } } + + entry foo(x: Self.X) { + let y: u64; + label bv: + variant_switch X (&x) { + V1 : b0, + V2 : b1, + }; + label b0: + return; + label b1: + return; + } + } + "; + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); + assert_eq!(cfg.blocks().len(), 3); + assert_eq!(cfg.num_blocks(), 3); + assert_eq!(cfg.reachable_from(0).len(), 3); +} + +#[test] +fn cfg_compile_variant_switch_simple_unconditional_jump() { + let text = " + module 0x42.m { + enum X has drop { V1 { x: u64 }, V2 { } } + + entry foo(x: Self.X) { + let y: u64; + label bv: + variant_switch X (&x) { + V1 : b0, + V2 : b1, + }; + // This block is unreachable because `variant_switch` is an unconditional jump. + label fallthrough: + return; + label b0: + return; + label b1: + return; + } + } + "; + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); + assert_eq!(cfg.blocks().len(), 4); + assert_eq!(cfg.num_blocks(), 4); + assert_eq!(cfg.reachable_from(0).len(), 3); +} + +#[test] +fn cfg_compile_variant_switch() { + let text = " + module 0x42.m { + enum X { V1 { x: u64 }, V2 { } } + + entry foo(x: Self.X) { + let y: u64; + label bv: + variant_switch X (&x) { + V1 : b0, + V2 : b4, + }; + label b0: + X.V1 { x: y } = move(x); + jump_if (move(y) > 42) b2; + label b1: + jump b3; + label b2: + y = 0; + jump b3; + label b3: + return; + label b4: + X.V2 {} = move(x); + jump b3; + } + } + "; + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); + assert_eq!(cfg.blocks().len(), 6); + assert_eq!(cfg.num_blocks(), 6); + assert_eq!(cfg.reachable_from(0).len(), 6); +} + +#[test] +fn cfg_compile_variant_switch_with_two_aborts() { + let text = " + module 0x42.m { + enum X { V1 { x: u64 }, V2 { } } + + entry foo(x: Self.X) { + let y: u64; + label bv: + variant_switch X (&x) { + V1 : b0, + V2 : b4, + }; + label b0: + X.V1 { x: y } = move(x); + jump_if (move(y) > 42) b3; + label b1: + jump b3; + label b2: // This block is not reachable -- so should have 6 blocks and 5 reachable + y = 0; + jump b3; + label b3: + return; + label b4: + X.V2 {} = move(x); + abort 0; + } + } + "; + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); + assert_eq!(cfg.blocks().len(), 6); + assert_eq!(cfg.num_blocks(), 6); + assert_eq!(cfg.reachable_from(0).len(), 5); +} + +#[test] +fn cfg_compile_variant_switch_with_return() { + let text = " + module 0x42.m { + enum X { V1 { x: u64 }, V2 { } } + + entry foo(x: Self.X) { + let y: u64; + label bv: + variant_switch X (&x) { + V1 : b0, + V2 : b4, + }; + // This block is unreachable since `variant_switch` is an unconditional jump. + // If `variant_switch` is a conditional jump, then this block is reachable, and would + // raise an unused value without drop error. But, since we guarantee exhaustiveness, we + // are guaranteed that we cannot fall through here and so this block is unreachable. + label fallthrough: + return; + label b0: + X.V1 { x: y } = move(x); + jump_if (move(y) > 42) b3; + label b1: + return; + label b2: // This block is not reachable -- so should have 6 blocks and 5 reachable + y = 0; + jump b3; + label b3: + return; + label b4: + X.V2 {} = move(x); + abort 0; + } + } + "; + let (code, jump_tables) = compile_module_with_single_function(text); + let cfg: VMControlFlowGraph = VMControlFlowGraph::new(&code, &jump_tables); + assert_eq!(cfg.blocks().len(), 7); + assert_eq!(cfg.num_blocks(), 7); + assert_eq!(cfg.reachable_from(0).len(), 5); +} + +fn compile_module_with_single_function(text: &str) -> (Vec, Vec) { let mut compiled_module = compile_module_string(text).unwrap(); - compiled_module - .function_defs - .pop() - .unwrap() - .code - .unwrap() - .code + let code_unit = compiled_module.function_defs.pop().unwrap().code.unwrap(); + (code_unit.code, code_unit.jump_tables) } 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 863811f82d7870..d8069ac15f85ea 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,9 +5,12 @@ task 0 'print-bytecode'. lines 1-7: module 42.M { + + entry foo() { B0: 0: Ret + } } @@ -16,8 +19,11 @@ task 1 'print-bytecode'. lines 9-13: module 42.M { + + entry foo() { B0: 0: Ret + } } 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 25a7527c2874a1..0df741d16e3dc6 100644 --- a/external-crates/move/crates/move-vm-integration-tests/Cargo.toml +++ b/external-crates/move/crates/move-vm-integration-tests/Cargo.toml @@ -28,6 +28,7 @@ move-vm-types.workspace = true move-vm-test-utils.workspace = true move-stdlib-natives.workspace = true move-stdlib.workspace = true +move-ir-to-bytecode.workspace = true [features] default = [] 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 new file mode 100644 index 00000000000000..9462ae21ad3700 --- /dev/null +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/compatibility_tests.rs @@ -0,0 +1,265 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::{ + compatibility::{Compatibility, InclusionCheck}, + file_format::AbilitySet, + normalized, +}; +use move_ir_to_bytecode::{compiler::compile_module, parser::parse_module}; + +fn compile(prog: &str) -> normalized::Module { + let prog = parse_module(prog).unwrap(); + let (compiled_module, _) = compile_module(prog, vec![]).unwrap(); + normalized::Module::new(&compiled_module) +} + +// Things to test for enum upgrades +// * [x] Variant removal (never) +// * [x] Variant rename (never) +// * [x] Variant reordering (never) +// * [x] Additional field in existing variant (never) +// * [x] Remove field from existing variant (never) +// * [x] Rename field in existing variant (never) +// * [x] Change type of existing field in variant (never) +// * [x] Add new variant at beginning (w/out disallow_new_variants) (never) +// * [x] Add new variant at end (w/out disallow_new_variants, equal and subset inclusions) +// - Allowed if `disallow_new_variants = false` or `InclusionCheck::Subset` +// * [x] Change abilities on type + +#[test] +fn test_enum_upgrade_variant_removal() { + let old = compile( + " + module 0x1.M { + enum E { V { }, L { } } + } + ", + ); + // Enum variant removal is not allowed + let new = compile( + " + module 0x1.M { + enum E { V { } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_variant_rename() { + let old = compile( + " + module 0x1.M { + enum E { V { } } + } + ", + ); + // Enum variant renaming is not allowed + let new = compile( + " + module 0x1.M { + enum E { L { } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_variant_reorder() { + let old = compile( + " + module 0x1.M { + enum E { V { }, L { } } + } + ", + ); + // Enum variant reordering is not allowed. + let new = compile( + " + module 0x1.M { + enum E { L { }, V { } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_variant_add_field() { + let old = compile( + " + module 0x1.M { + enum E { V { } } + } + ", + ); + // Adding a new field to an existing enum variant is not allowed + let new = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_variant_remove_field() { + let old = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + // Adding a new field to an existing enum variant is not allowed + let new = compile( + " + module 0x1.M { + enum E { V { } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_variant_rename_field() { + let old = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + // Renaming a field in an existing enum variant is not allowed + let new = compile( + " + module 0x1.M { + enum E { V { y: u64 } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_variant_change_field_type() { + let old = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + // Changing the type of an existing field in an enum variant is not allowed + let new = compile( + " + module 0x1.M { + enum E { V { x: bool } } + } + ", + ); + assert!(Compatibility::default().check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_add_variant_at_front() { + let old = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + // Adding a new variant at the front of the enum is not allowed (ever) + let new = compile( + " + module 0x1.M { + enum E { L { x: u64 }, V { x: u64 } } + } + ", + ); + let mut compat = Compatibility::default(); + assert!(compat.disallow_new_variants); + assert!(compat.check(&old, &new).is_err()); + compat.disallow_new_variants = false; + assert!(compat.check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_add_variant_at_end() { + let old = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + // Adding a new variant at the end of the enum is not allowed unless the + // `disallow_new_variants` flag is set to false. + let new = compile( + " + module 0x1.M { + enum E { V { x: u64 }, L { x: u64 }} + } + ", + ); + let mut compat = Compatibility::default(); + assert!(compat.disallow_new_variants); + 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 + // be updated at that time. + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} + +#[test] +fn test_enum_upgrade_add_store_ability() { + let old = compile( + " + module 0x1.M { + enum E { V { x: u64 } } + } + ", + ); + // Adding a new variant at the front of the enum is not allowed (ever) + let new = compile( + " + module 0x1.M { + enum E has store { V { x: u64 } } + } + ", + ); + let mut compat = Compatibility::default(); + assert!(compat.check(&old, &new).is_ok()); + compat.disallowed_new_abilities = AbilitySet::ALL; + assert!(compat.check(&old, &new).is_err()); + assert!(InclusionCheck::Equal.check(&old, &new).is_err()); + assert!(InclusionCheck::Subset.check(&old, &new).is_err()); +} 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 828b94d92357e7..29974b219d5f9f 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 @@ -9,12 +9,12 @@ use move_binary_format::{ errors::VMResult, file_format::{ AbilitySet, AddressIdentifierIndex, Bytecode, Bytecode::*, CodeUnit, CompiledModule, - Constant, ConstantPoolIndex, FieldDefinition, FunctionDefinition, FunctionHandle, - FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, - ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, - SignatureToken::*, StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, - StructDefinitionIndex, StructFieldInformation, StructHandle, StructHandleIndex, - StructTypeParameter, TypeSignature, + Constant, ConstantPoolIndex, DatatypeHandle, DatatypeHandleIndex, DatatypeTyParameter, + FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, + FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, ModuleHandle, + ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, SignatureToken::*, + StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, + StructDefinitionIndex, StructFieldInformation, TypeSignature, }, }; use move_core_types::{ @@ -346,7 +346,7 @@ fn make_module( func_type_params.clone() }; let struct_type_parameters = vec![ - StructTypeParameter { + DatatypeTyParameter { constraints: AbilitySet::EMPTY, is_phantom: false, }; @@ -391,14 +391,14 @@ fn make_module( name: IdentifierIndex(0), }], // struct definition - struct_handles: vec![StructHandle { + datatype_handles: vec![DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: AbilitySet::ALL, type_parameters: struct_type_parameters, }], struct_defs: vec![StructDefinition { - struct_handle: StructHandleIndex(0), + struct_handle: DatatypeHandleIndex(0), field_information: StructFieldInformation::Declared(vec![FieldDefinition { name: IdentifierIndex(2), signature: TypeSignature(U8), @@ -436,6 +436,7 @@ fn make_module( acquires_global_resources: vec![], code: Some(CodeUnit { locals: SignatureIndex(locals_idx as u16), + jump_tables: vec![], code, }), }, @@ -446,6 +447,7 @@ fn make_module( acquires_global_resources: vec![], code: Some(CodeUnit { locals: SignatureIndex(locals_idx as u16), + jump_tables: vec![], code: vec![ CopyLoc(0), LdU64(1), @@ -468,6 +470,7 @@ fn make_module( acquires_global_resources: vec![], code: Some(CodeUnit { locals: SignatureIndex(locals_idx as u16), + jump_tables: vec![], code: vec![Ret], }), }, @@ -505,6 +508,10 @@ fn make_module( friend_decls: vec![], field_instantiations: vec![], metadata: vec![], + enum_defs: vec![], + enum_def_instantiations: vec![], + variant_handles: vec![], + variant_instantiation_handles: vec![], }; // uncomment to see the module generated // println!("Module: {:#?}", module); @@ -719,7 +726,7 @@ fn vec_pack_gen_deep_it( for _ in 0..STRUCT_TY_PARAMS { ty_args.push(big_ty.clone()); } - big_ty = StructInstantiation(Box::new((StructHandleIndex(0), ty_args))); + big_ty = DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), ty_args))); } // @@ -876,7 +883,7 @@ fn deep_gen_call_it( for _ in 0..STRUCT_TY_PARAMS { ty_args.push(big_ty.clone()); } - big_ty = StructInstantiation(Box::new((StructHandleIndex(0), ty_args))); + big_ty = DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), ty_args))); } // @@ -1011,7 +1018,7 @@ fn deep_rec_gen_call( for _ in 0..STRUCT_TY_PARAMS { ty_args.push(big_ty.clone()); } - big_ty = StructInstantiation(Box::new((StructHandleIndex(0), ty_args))); + big_ty = DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), ty_args))); } // 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 b3ad29ac66e811..17b696cce8febc 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 @@ -43,6 +43,7 @@ fn merge_borrow_states_infinite_loop() { acquires_global_resources: vec![], code: Some(CodeUnit { locals: SignatureIndex(1), + jump_tables: vec![], code: vec![ LdU64(0), StLoc(0), // { 0 => 0 } 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 e4ffef47d7fe90..ee323c7afd1dfe 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 @@ -34,6 +34,7 @@ fn leak_with_abort() { acquires_global_resources: vec![], code: Some(CodeUnit { locals: SignatureIndex(1), + jump_tables: vec![], code: vec![ // leak LdU128(Box::new(0)), 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 905d21be796add..650e1a09066ea6 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 @@ -27,7 +27,7 @@ use move_vm_runtime::{move_vm::MoveVM, session::SerializedReturnValues}; use move_vm_test_utils::InMemoryStorage; use move_vm_types::{ gas::UnmeteredGasMeter, - loaded_data::runtime_types::{DepthFormula, StructType, Type}, + loaded_data::runtime_types::{CachedDatatype, DepthFormula, Type}, }; use std::{collections::BTreeMap, path::PathBuf, str::FromStr, sync::Arc, thread}; @@ -204,10 +204,10 @@ impl Adapter { .expect("Loading type should succeed") } - fn load_struct(&self, module_id: &ModuleId, struct_name: &IdentStr) -> Arc { + fn load_datatype(&self, module_id: &ModuleId, struct_name: &IdentStr) -> Arc { let session = self.vm.new_session(&self.store); session - .load_struct(module_id, struct_name) + .load_datatype(module_id, struct_name) .expect("Loading struct should succeed") .1 } @@ -608,14 +608,14 @@ fn test_depth() { ]; adapter.publish_modules(modules); // loads all structs sequentially - for (module_name, struct_name, expected_depth) in structs.iter() { + for (module_name, type_name, expected_depth) in structs.iter() { let computed_depth = &adapter - .load_struct( + .load_datatype( &ModuleId::new( DEFAULT_ACCOUNT, Identifier::new(module_name.to_string()).unwrap(), ), - ident_str!(struct_name), + ident_str!(type_name), ) .depth; assert_eq!(computed_depth, expected_depth); diff --git a/external-crates/move/crates/move-vm-integration-tests/src/tests/mod.rs b/external-crates/move/crates/move-vm-integration-tests/src/tests/mod.rs index c509534886fb41..32eb1f08e473fe 100644 --- a/external-crates/move/crates/move-vm-integration-tests/src/tests/mod.rs +++ b/external-crates/move/crates/move-vm-integration-tests/src/tests/mod.rs @@ -5,6 +5,7 @@ mod bad_entry_point_tests; mod bad_storage_tests; mod binary_format_version; +mod compatibility_tests; mod exec_func_effects_tests; mod function_arg_tests; mod instantiation_tests; 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 new file mode 100644 index 00000000000000..cc10f958ac8b68 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.exp @@ -0,0 +1,46 @@ +processed 2 tasks + +task 0 'print-bytecode'. lines 1-24: +// Move bytecode v7 +module 1.MonomorphicEnums { + + +enum EnumWithTwoVariants { + One { }, + Two { x: u64 } +} + +public f(Arg0: Ty0, Arg1: Ty0): Ty0 { +B0: + 0: MoveLoc[0](Arg0: Ty0) + 1: PackVariantGeneric(VariantInstantiationHandleIndex(0)) + 2: StLoc[2](loc0: EnumWithTwoVariants) + 3: ImmBorrowLoc[2](loc0: EnumWithTwoVariants) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: MoveLoc[2](loc0: EnumWithTwoVariants) + 6: UnpackVariantGeneric(VariantInstantiationHandleIndex(1)) + 7: MoveLoc[1](Arg1: Ty0) + 8: Ret +B2: + 9: MoveLoc[2](loc0: EnumWithTwoVariants) + 10: UnpackVariantGeneric(VariantInstantiationHandleIndex(0)) + 11: StLoc[3](loc1: Ty0) + 12: MoveLoc[3](loc1: Ty0) + 13: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 5 + Variant1 => jump 9 + } +} +} + +task 1 'publish'. lines 26-49: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonomorphicEnums'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..efef81018cc5e5 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/basic_poly_enum_type_mismatch.mvir @@ -0,0 +1,49 @@ +//# print-bytecode +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + public f(t: T, e: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return move(e); + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} + +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + public f(t: T, e: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return move(e); + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} 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 new file mode 100644 index 00000000000000..3e4fbcbdf6bc11 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.exp @@ -0,0 +1,46 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 1-24: +// Move bytecode v7 +module 1.MonomorphicEnums { + + +enum EnumWithTwoVariants { + One { }, + Two { x: Ty0 } +} + +public f(Arg0: Ty0, Arg1: Ty0): Ty0 { +B0: + 0: MoveLoc[0](Arg0: Ty0) + 1: PackVariantGeneric(VariantInstantiationHandleIndex(0)) + 2: StLoc[2](loc0: EnumWithTwoVariants) + 3: ImmBorrowLoc[2](loc0: EnumWithTwoVariants) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: MoveLoc[2](loc0: EnumWithTwoVariants) + 6: UnpackVariantGeneric(VariantInstantiationHandleIndex(1)) + 7: MoveLoc[1](Arg1: Ty0) + 8: Ret +B2: + 9: MoveLoc[2](loc0: EnumWithTwoVariants) + 10: UnpackVariantGeneric(VariantInstantiationHandleIndex(0)) + 11: StLoc[3](loc1: Ty0) + 12: LdU64(0) + 13: Abort +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 9 + Variant1 => jump 5 + } +} +} + +task 2 'run'. lines 51-61: +Error: Function execution failed with VMError: { + major_status: VARIANT_TAG_MISMATCH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..e5d310bd0260ad --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/enum_variant_mismatch.mvir @@ -0,0 +1,61 @@ +//# print-bytecode +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: T } + } + + public f(t: T, e: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b2, + Two : b1, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return move(e); + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + abort 0; + } +} + +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: T } + } + + public f(t: T, e: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b2, + Two : b1, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return move(e); + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + abort 0; + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: u64; + label b0: + x = MonomorphicEnums.f(42, 0); + assert(move(x) == 42, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..2b4b3651507e43 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.exp @@ -0,0 +1,46 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 1-33: +// Move bytecode v7 +module 1.MonomorphicEnums { + + +enum EnumWithOneVariant { + One { } +} +enum EnumWithTwoVariants { + One { }, + Two { x: u64 } +} +enum EnumWithTwoVariantsPlusAbilities has copy, drop, store, key { + One { }, + Two { x: u64 } +} + +public f(): u64 { +L0: loc0: EnumWithTwoVariants +L1: loc1: u64 +B0: + 0: LdU64(42) + 1: PackVariant(VariantHandleIndex(0)) + 2: StLoc[0](loc0: EnumWithTwoVariants) + 3: ImmBorrowLoc[0](loc0: EnumWithTwoVariants) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: MoveLoc[0](loc0: EnumWithTwoVariants) + 6: UnpackVariant(VariantHandleIndex(1)) + 7: LdU64(0) + 8: Ret +B2: + 9: MoveLoc[0](loc0: EnumWithTwoVariants) + 10: UnpackVariant(VariantHandleIndex(0)) + 11: StLoc[1](loc1: u64) + 12: MoveLoc[1](loc1: u64) + 13: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 5 + 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 new file mode 100644 index 00000000000000..5aaee4a507c7d9 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic.mvir @@ -0,0 +1,79 @@ +//# print-bytecode +module 0x1.MonomorphicEnums { + enum EnumWithOneVariant { + One { } + } + + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + enum EnumWithTwoVariantsPlusAbilities has drop, copy, store, key { + One { }, + Two { x: u64 } + } + + public f(): u64 { + let x: Self.EnumWithTwoVariants; + let y: u64; + label b0: + x = EnumWithTwoVariants.Two { x: 42 }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return 0; + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} + +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithOneVariant { + One { } + } + + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + enum EnumWithTwoVariantsPlusAbilities has drop, copy, store, key { + One { }, + Two { x: u64 } + } + + public f(): u64 { + let x: Self.EnumWithTwoVariants; + let y: u64; + label b0: + x = EnumWithTwoVariants.Two { x: 42 }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + return 0; + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: u64; + label b0: + x = MonomorphicEnums.f(); + assert(move(x) == 42, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..0e7dfb62bba368 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.exp @@ -0,0 +1,13 @@ +processed 2 tasks + +task 0 'publish'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::MonomorphicEnums'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::MonomorphicEnums, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} + +task 1 'run'. lines 25-35: +Error: Dependency not provided for 0000000000000000000000000000000000000000000000000000000000000001.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 new file mode 100644 index 00000000000000..5121fd928a18a2 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_fail_unpack.mvir @@ -0,0 +1,35 @@ +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + public f(): u64 { + let x: Self.EnumWithTwoVariants; + let y: u64; + label b0: + x = EnumWithTwoVariants.Two { x: 42 }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + return 0; + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: u64; + label b0: + x = MonomorphicEnums.f(); + assert(move(x) == 42, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..fbc8e985e9529b --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 26-36: +Error: Function execution failed with VMError: { + major_status: VARIANT_TAG_MISMATCH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..66c89f2c445cd0 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/enum_decl_monomorphic_mismatched_variants.mvir @@ -0,0 +1,36 @@ +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: u64 } + } + + public f(): u64 { + let x: Self.EnumWithTwoVariants; + let y: u64; + label b0: + x = EnumWithTwoVariants.Two { x: 42 }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + label b2: + EnumWithTwoVariants.One { } = move(x); + return 0; + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: u64; + label b0: + x = MonomorphicEnums.f(); + assert(move(x) == 42, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..be79c1e654eac4 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.exp @@ -0,0 +1,75 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 3-50: +// Move bytecode v7 +module 1.MonomorphicEnums { + + +enum EnumWithTwoVariants has drop { + One { x: u64 }, + Two { x: u64, y: u64 } +} + +public f(Arg0: u64): EnumWithTwoVariants { +B0: + 0: LdU64(0) + 1: StLoc[1](loc0: u64) + 2: MoveLoc[0](Arg0: u64) + 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) + 1: FreezeRef + 2: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 3: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) + 4: UnpackVariantMutRef(VariantHandleIndex(1)) + 5: StLoc[2](loc0: &mut u64) + 6: MoveLoc[1](Arg1: u64) + 7: MoveLoc[2](loc0: &mut u64) + 8: WriteRef + 9: Ret +B2: + 10: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) + 11: UnpackVariantMutRef(VariantHandleIndex(0)) + 12: StLoc[3](loc1: &mut u64) + 13: StLoc[2](loc0: &mut u64) + 14: MoveLoc[1](Arg1: u64) + 15: MoveLoc[2](loc0: &mut u64) + 16: WriteRef + 17: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 3 + Variant1 => jump 10 + } +} +public get(Arg0: &EnumWithTwoVariants): &u64 { +L0: loc1: &u64 +B0: + 0: CopyLoc[0](Arg0: &EnumWithTwoVariants) + 1: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 2: MoveLoc[0](Arg0: &EnumWithTwoVariants) + 3: UnpackVariantImmRef(VariantHandleIndex(1)) + 4: StLoc[1](loc0: &u64) + 5: MoveLoc[1](loc0: &u64) + 6: Ret +B2: + 7: MoveLoc[0](Arg0: &EnumWithTwoVariants) + 8: UnpackVariantImmRef(VariantHandleIndex(0)) + 9: StLoc[2](loc1: &u64) + 10: StLoc[1](loc0: &u64) + 11: MoveLoc[1](loc0: &u64) + 12: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 2 + 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 new file mode 100644 index 00000000000000..5adacaa2797304 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update.mvir @@ -0,0 +1,119 @@ +// Tests that mutable borrows from enum variants work correctly. + +//# print-bytecode +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: u64 }, + Two { x: u64, y: u64 } + } + + public f(t: u64): Self.EnumWithTwoVariants { + let l: u64; + label b0: + l = 0; + return EnumWithTwoVariants.Two { x: move(t), y: move(l) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, v: u64) { + let x: &mut u64; + let u: &mut u64; + label b0: + variant_switch EnumWithTwoVariants (freeze(copy(e))) { + One : b1, + Two : b2, + }; + label b1: + &mut EnumWithTwoVariants.One { x } = move(e); + *(move(x)) = move(v); + return; + label b2: + &mut EnumWithTwoVariants.Two { x, y: u } = move(e); + *(move(x)) = move(v); + return; + } + + public get(e: &Self.EnumWithTwoVariants): &u64 { + let x: &u64; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + &EnumWithTwoVariants.One { x } = move(e); + return move(x); + label b2: + &EnumWithTwoVariants.Two { x, y: u } = move(e); + return move(x); + } +} + +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: u64 }, + Two { x: u64, y: u64 } + } + + public f(t: u64): Self.EnumWithTwoVariants { + let l: u64; + label b0: + l = 0; + return EnumWithTwoVariants.Two { x: move(t), y: move(l) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, v: u64) { + let x: &mut u64; + let u: &mut u64; + label b0: + variant_switch EnumWithTwoVariants (freeze(copy(e))) { + One : b1, + Two : b2, + }; + label b1: + &mut EnumWithTwoVariants.One { x } = move(e); + *(move(x)) = move(v); + return; + label b2: + &mut EnumWithTwoVariants.Two { x, y: u } = move(e); + *(move(x)) = move(v); + return; + } + + public get(e: &Self.EnumWithTwoVariants): &u64 { + let x: &u64; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + &EnumWithTwoVariants.One { x } = move(e); + return move(x); + label b2: + &EnumWithTwoVariants.Two { x, y: u } = move(e); + return move(x); + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: MonomorphicEnums.EnumWithTwoVariants; + let y: &u64; + label b0: + x = MonomorphicEnums.f(42); + y = MonomorphicEnums.get(&x); + assert(*move(y) == 42, 100); + MonomorphicEnums.mutate(&mut x, 43); + y = MonomorphicEnums.get(&x); + assert(*move(y) == 43, 100); + MonomorphicEnums.mutate(&mut x, 10); + y = MonomorphicEnums.get(&x); + assert(*move(y) == 10, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..b04087db38e8a9 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.exp @@ -0,0 +1,47 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 3-34: +// Move bytecode v7 +module 1.MonomorphicEnums { + + +enum EnumWithTwoVariants has drop { + One { x: u64 }, + Two { x: u64, y: u64 } +} + +public f(Arg0: u64): EnumWithTwoVariants { +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) + 1: MoveLoc[2](Arg2: u64) + 2: PackVariant(VariantHandleIndex(1)) + 3: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) + 4: WriteRef + 5: Ret + +} +public is_variant_two(Arg0: &EnumWithTwoVariants): bool { +L0: loc1: &u64 +B0: + 0: CopyLoc[0](Arg0: &EnumWithTwoVariants) + 1: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 2: LdFalse + 3: Ret +B2: + 4: LdTrue + 5: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 2 + 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 new file mode 100644 index 00000000000000..8364394dee8a04 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/mono/mut_ref_update_variant.mvir @@ -0,0 +1,84 @@ +// Tests that if taking a mutable enum that the variant inside cane be mutated. + +//# print-bytecode +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: u64 }, + Two { x: u64, y: u64 } + } + + public f(t: u64): Self.EnumWithTwoVariants { + label b0: + return EnumWithTwoVariants.One { x: move(t) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, x: u64, y: u64) { + label b0: + *(move(e)) = EnumWithTwoVariants.Two { x: move(x), y: move(y) }; + return; + } + + public is_variant_two(e: &Self.EnumWithTwoVariants): bool { + let x: &u64; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + return false; + label b2: + return true; + } +} + +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: u64 }, + Two { x: u64, y: u64 } + } + + public f(t: u64): Self.EnumWithTwoVariants { + label b0: + return EnumWithTwoVariants.One { x: move(t) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, x: u64, y: u64) { + label b0: + *(move(e)) = EnumWithTwoVariants.Two { x: move(x), y: move(y) }; + return; + } + + public is_variant_two(e: &Self.EnumWithTwoVariants): bool { + let x: &u64; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + return false; + label b2: + return true; + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: MonomorphicEnums.EnumWithTwoVariants; + let y: bool; + label b0: + x = MonomorphicEnums.f(42); + y = MonomorphicEnums.is_variant_two(&x); + assert(!move(y), 100); + MonomorphicEnums.mutate(&mut x, 43, 42); + y = MonomorphicEnums.is_variant_two(&x); + assert(move(y), 101); + return; +} +} 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 new file mode 100644 index 00000000000000..2b5c1f0e3cc283 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.exp @@ -0,0 +1,38 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 1-24: +// Move bytecode v7 +module 1.MonomorphicEnums { + + +enum EnumWithTwoVariants { + One { }, + Two { x: Ty0 } +} + +public f(Arg0: Ty0): Ty0 { +L0: loc1: Ty0 +B0: + 0: MoveLoc[0](Arg0: Ty0) + 1: PackVariantGeneric(VariantInstantiationHandleIndex(0)) + 2: StLoc[1](loc0: EnumWithTwoVariants) + 3: ImmBorrowLoc[1](loc0: EnumWithTwoVariants) + 4: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 5: MoveLoc[1](loc0: EnumWithTwoVariants) + 6: UnpackVariantGeneric(VariantInstantiationHandleIndex(1)) + 7: LdU64(0) + 8: Abort +B2: + 9: MoveLoc[1](loc0: EnumWithTwoVariants) + 10: UnpackVariantGeneric(VariantInstantiationHandleIndex(0)) + 11: StLoc[2](loc1: Ty0) + 12: MoveLoc[2](loc1: Ty0) + 13: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 5 + 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 new file mode 100644 index 00000000000000..843c3296f08f1f --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/basic_poly_enum.mvir @@ -0,0 +1,61 @@ +//# print-bytecode +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: T } + } + + public f(t: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + abort 0; + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} + +//# publish +module 0x1.MonomorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: T } + } + + public f(t: T): T { + let x: Self.EnumWithTwoVariants; + let y: T; + label b0: + x = EnumWithTwoVariants.Two { x: move(t) }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.One { } = move(x); + abort 0; + label b2: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + } +} + +//# run +module 0x2.m { +import 0x1.MonomorphicEnums; +entry foo() { + let x: u64; + label b0: + x = MonomorphicEnums.f(42); + assert(move(x) == 42, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..2827b253d77b32 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 26-36: +Error: Function execution failed with VMError: { + major_status: VARIANT_TAG_MISMATCH, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..0a10ebb63b4bcf --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants.mvir @@ -0,0 +1,36 @@ +//# publish +module 0x1.PolymorphicEnums { + enum EnumWithTwoVariants { + One { }, + Two { x: T } + } + + public f(): u64 { + let x: Self.EnumWithTwoVariants; + let y: u64; + label b0: + x = EnumWithTwoVariants.Two { x: 42 }; + variant_switch EnumWithTwoVariants (&x) { + One : b1, + Two : b2, + }; + label b1: + EnumWithTwoVariants.Two { x: y } = move(x); + return move(y); + label b2: + EnumWithTwoVariants.One { } = move(x); + return 0; + } +} + +//# run +module 0x2.m { + import 0x1.PolymorphicEnums; + entry foo() { + let x: u64; + label b0: + x = PolymorphicEnums.f(); + assert(move(x) == 42, 100); + return; + } +} diff --git a/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants_types.exp b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/enum_decl_poly_mismatched_variants_types.exp new file mode 100644 index 00000000000000..e69de29bb2d1d6 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 new file mode 100644 index 00000000000000..89918a879ac744 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.exp @@ -0,0 +1,75 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 3-50: +// Move bytecode v7 +module 1.PolymorphicEnums { + + +enum EnumWithTwoVariants has drop { + One { x: Ty0 }, + Two { x: Ty0, y: u64 } +} + +public f(Arg0: Ty0): EnumWithTwoVariants { +B0: + 0: LdU64(0) + 1: StLoc[1](loc0: u64) + 2: MoveLoc[0](Arg0: Ty0) + 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) + 1: FreezeRef + 2: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 3: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) + 4: UnpackVariantGenericMutRef(VariantInstantiationHandleIndex(1)) + 5: StLoc[2](loc0: &mut Ty0) + 6: MoveLoc[1](Arg1: Ty0) + 7: MoveLoc[2](loc0: &mut Ty0) + 8: WriteRef + 9: Ret +B2: + 10: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) + 11: UnpackVariantGenericMutRef(VariantInstantiationHandleIndex(0)) + 12: StLoc[3](loc1: &mut u64) + 13: StLoc[2](loc0: &mut Ty0) + 14: MoveLoc[1](Arg1: Ty0) + 15: MoveLoc[2](loc0: &mut Ty0) + 16: WriteRef + 17: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 3 + Variant1 => jump 10 + } +} +public get(Arg0: &EnumWithTwoVariants): &Ty0 { +L0: loc1: &u64 +B0: + 0: CopyLoc[0](Arg0: &EnumWithTwoVariants) + 1: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 2: MoveLoc[0](Arg0: &EnumWithTwoVariants) + 3: UnpackVariantGenericImmRef(VariantInstantiationHandleIndex(1)) + 4: StLoc[1](loc0: &Ty0) + 5: MoveLoc[1](loc0: &Ty0) + 6: Ret +B2: + 7: MoveLoc[0](Arg0: &EnumWithTwoVariants) + 8: UnpackVariantGenericImmRef(VariantInstantiationHandleIndex(0)) + 9: StLoc[2](loc1: &u64) + 10: StLoc[1](loc0: &Ty0) + 11: MoveLoc[1](loc0: &Ty0) + 12: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 2 + 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 new file mode 100644 index 00000000000000..d33b90f9b86261 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update.mvir @@ -0,0 +1,119 @@ +// Tests that mutable borrows from enum variants work correctly. + +//# print-bytecode +module 0x1.PolymorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: T }, + Two { x: T, y: u64 } + } + + public f(t: T): Self.EnumWithTwoVariants { + let l: u64; + label b0: + l = 0; + return EnumWithTwoVariants.Two { x: move(t), y: move(l) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, v: T) { + let x: &mut T; + let u: &mut u64; + label b0: + variant_switch EnumWithTwoVariants (freeze(copy(e))) { + One : b1, + Two : b2, + }; + label b1: + &mut EnumWithTwoVariants.One { x } = move(e); + *(move(x)) = move(v); + return; + label b2: + &mut EnumWithTwoVariants.Two { x, y: u } = move(e); + *(move(x)) = move(v); + return; + } + + public get(e: &Self.EnumWithTwoVariants): &T { + let x: &T; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + &EnumWithTwoVariants.One { x } = move(e); + return move(x); + label b2: + &EnumWithTwoVariants.Two { x, y: u } = move(e); + return move(x); + } +} + +//# publish +module 0x1.PolymorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: T }, + Two { x: T, y: u64 } + } + + public f(t: T): Self.EnumWithTwoVariants { + let l: u64; + label b0: + l = 0; + return EnumWithTwoVariants.Two { x: move(t), y: move(l) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, v: T) { + let x: &mut T; + let u: &mut u64; + label b0: + variant_switch EnumWithTwoVariants (freeze(copy(e))) { + One : b1, + Two : b2, + }; + label b1: + &mut EnumWithTwoVariants.One { x } = move(e); + *(move(x)) = move(v); + return; + label b2: + &mut EnumWithTwoVariants.Two { x, y: u } = move(e); + *(move(x)) = move(v); + return; + } + + public get(e: &Self.EnumWithTwoVariants): &T { + let x: &T; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + &EnumWithTwoVariants.One { x } = move(e); + return move(x); + label b2: + &EnumWithTwoVariants.Two { x, y: u } = move(e); + return move(x); + } +} + +//# run +module 0x2.m { +import 0x1.PolymorphicEnums; +entry foo() { + let x: PolymorphicEnums.EnumWithTwoVariants; + let y: &u64; + label b0: + x = PolymorphicEnums.f(42); + y = PolymorphicEnums.get(&x); + assert(*move(y) == 42, 100); + PolymorphicEnums.mutate(&mut x, 43); + y = PolymorphicEnums.get(&x); + assert(*move(y) == 43, 100); + PolymorphicEnums.mutate(&mut x, 10); + y = PolymorphicEnums.get(&x); + assert(*move(y) == 10, 100); + return; +} +} 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 new file mode 100644 index 00000000000000..0b2ed965525f58 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.exp @@ -0,0 +1,47 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 3-34: +// Move bytecode v7 +module 1.PolymorphicEnums { + + +enum EnumWithTwoVariants has drop { + One { x: Ty0 }, + Two { x: Ty0, y: Ty0 } +} + +public f(Arg0: u64): EnumWithTwoVariants { +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) + 1: MoveLoc[2](Arg2: u64) + 2: PackVariantGeneric(VariantInstantiationHandleIndex(1)) + 3: MoveLoc[0](Arg0: &mut EnumWithTwoVariants) + 4: WriteRef + 5: Ret + +} +public is_variant_two(Arg0: &EnumWithTwoVariants): bool { +L0: loc1: &u64 +B0: + 0: CopyLoc[0](Arg0: &EnumWithTwoVariants) + 1: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 2: LdFalse + 3: Ret +B2: + 4: LdTrue + 5: Ret +Jump tables: +[0]: variant_switch EnumWithTwoVariants { + Variant0 => jump 2 + 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 new file mode 100644 index 00000000000000..60c48171b0ff6c --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/poly/poly_mut_ref_update_variant.mvir @@ -0,0 +1,84 @@ +// Tests that if taking a mutable enum that the variant inside cane be mutated. + +//# print-bytecode +module 0x1.PolymorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: T }, + Two { x: T, y: T } + } + + public f(t: u64): Self.EnumWithTwoVariants { + label b0: + return EnumWithTwoVariants.One { x: move(t) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, x: u64, y: u64) { + label b0: + *(move(e)) = EnumWithTwoVariants.Two { x: move(x), y: move(y) }; + return; + } + + public is_variant_two(e: &Self.EnumWithTwoVariants): bool { + let x: &u64; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + return false; + label b2: + return true; + } +} + +//# publish +module 0x1.PolymorphicEnums { + enum EnumWithTwoVariants has drop { + One { x: T }, + Two { x: T, y: T } + } + + public f(t: u64): Self.EnumWithTwoVariants { + label b0: + return EnumWithTwoVariants.One { x: move(t) }; + } + + public mutate(e: &mut Self.EnumWithTwoVariants, x: u64, y: u64) { + label b0: + *(move(e)) = EnumWithTwoVariants.Two { x: move(x), y: move(y) }; + return; + } + + public is_variant_two(e: &Self.EnumWithTwoVariants): bool { + let x: &u64; + let u: &u64; + label b0: + variant_switch EnumWithTwoVariants (copy(e)) { + One : b1, + Two : b2, + }; + label b1: + return false; + label b2: + return true; + } +} + +//# run +module 0x2.m { +import 0x1.PolymorphicEnums; +entry foo() { + let x: PolymorphicEnums.EnumWithTwoVariants; + let y: bool; + label b0: + x = PolymorphicEnums.f(42); + y = PolymorphicEnums.is_variant_two(&x); + assert(!move(y), 100); + PolymorphicEnums.mutate(&mut x, 43, 42); + y = PolymorphicEnums.is_variant_two(&x); + assert(move(y), 101); + return; +} +} 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 new file mode 100644 index 00000000000000..359b92e19c5e18 --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.exp @@ -0,0 +1,41 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 1-22: +// Move bytecode v7 +module 1.InfiniteSwith { + + +enum EnumWithOneVariant { + One { } +} + +public f(Arg0: EnumWithOneVariant) { +B0: + 0: ImmBorrowLoc[0](Arg0: EnumWithOneVariant) + 1: VariantSwitch(VariantJumpTableIndex(0)) +B1: + 2: Ret +Jump tables: +[0]: variant_switch EnumWithOneVariant { + Variant0 => jump 0 + } +} +public start(): EnumWithOneVariant { +L0: loc0: EnumWithOneVariant +B0: + 0: PackVariant(VariantHandleIndex(0)) + 1: StLoc[0](loc0: EnumWithOneVariant) + 2: MoveLoc[0](loc0: EnumWithOneVariant) + 3: Ret + +} +} + +task 2 'run'. lines 48-58: +Error: Function execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: 0x1::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 new file mode 100644 index 00000000000000..07ab9642c5d6fa --- /dev/null +++ b/external-crates/move/crates/move-vm-transactional-tests/tests/enums/variant_switch_loop.mvir @@ -0,0 +1,58 @@ +//# print-bytecode +module 0x1.InfiniteSwith { + enum EnumWithOneVariant { + One { } + } + + public f(x: Self.EnumWithOneVariant) { + label b0: + variant_switch EnumWithOneVariant (&x) { + One : b0, + }; + label end: + return; + } + + public start(): Self.EnumWithOneVariant { + let x: Self.EnumWithOneVariant; + label b0: + x = EnumWithOneVariant.One{}; + return move(x); + } +} + +//# publish +module 0x1.InfiniteSwith { + enum EnumWithOneVariant { + One { } + } + + public f(x: Self.EnumWithOneVariant) { + label b0: + variant_switch EnumWithOneVariant (&x) { + One : b0, + }; + label end: + return; + } + + public start(): Self.EnumWithOneVariant { + let x: Self.EnumWithOneVariant; + label b0: + x = EnumWithOneVariant.One{}; + return move(x); + } +} + + +//# run --gas-budget 10000 +module 0x2.m { +import 0x1.InfiniteSwith; +entry foo() { + let x: InfiniteSwith.EnumWithOneVariant; + label b0: + x = InfiniteSwith.start(); + InfiniteSwith.f(move(x)); + return; +} +} diff --git a/external-crates/move/crates/serializer-tests/tests/serializer_tests.proptest-regressions b/external-crates/move/crates/serializer-tests/tests/serializer_tests.proptest-regressions index 988ff09ce66d82..f6425d5c032626 100644 --- a/external-crates/move/crates/serializer-tests/tests/serializer_tests.proptest-regressions +++ b/external-crates/move/crates/serializer-tests/tests/serializer_tests.proptest-regressions @@ -4,6 +4,9 @@ # # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. -cc 3d00be1cbcb9f344e7bce080015d7a755f6e69acd37dbde62e449732af226fe4 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, flags: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit), TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } -cc 7b1bb969b87bfcdbb0f635eb46212f8437d21bcd1ba754de84d66bb552e6aec2 # shrinks to module = CompiledModule { module_handles: [], struct_handles: [], function_handles: [], type_signatures: [], function_signatures: [], locals_signatures: [], string_pool: [], byte_array_pool: [], address_pool: [0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000], struct_defs: [], field_defs: [], function_defs: [] } -cc 4118fc247fb7d48382876de931d47a8999a6e42658bbecc93afff9245ade141b # shrinks to module = CompiledModule { module_handles: [], struct_handles: [], function_handles: [], type_signatures: [], function_signatures: [], locals_signatures: [], string_pool: [], byte_array_pool: [], address_pool: [], struct_defs: [], field_defs: [FieldDefinition { struct_: StructHandleIndex(0), name: IdentifierIndex(0), signature: TypeSignatureIndex(0) }], function_defs: [] } +cc 3d00be1cbcb9f344e7bce080015d7a755f6e69acd37dbde62e449732af226fe4 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, flags: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit), TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } +cc 7b1bb969b87bfcdbb0f635eb46212f8437d21bcd1ba754de84d66bb552e6aec2 # shrinks to module = CompiledModule { module_handles: [], datatype_handles: [], function_handles: [], type_signatures: [], function_signatures: [], locals_signatures: [], string_pool: [], byte_array_pool: [], address_pool: [0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000], struct_defs: [], field_defs: [], function_defs: [] } +cc 4118fc247fb7d48382876de931d47a8999a6e42658bbecc93afff9245ade141b # shrinks to module = CompiledModule { module_handles: [], datatype_handles: [], function_handles: [], type_signatures: [], function_signatures: [], locals_signatures: [], string_pool: [], byte_array_pool: [], address_pool: [], struct_defs: [], field_defs: [FieldDefinition { struct_: DatatypeHandleIndex(0), name: IdentifierIndex(0), signature: TypeSignatureIndex(0) }], function_defs: [] } +cc 490fad0a017a0d8eab0f86ee58d7bbe6722b0ba64d0684580e9950a0a38aff9f # shrinks to module = CompiledModule { version: 7, self_module_handle_idx: ModuleHandleIndex(0), module_handles: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }], datatype_handles: [DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(2), abilities: [], type_parameters: [] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), abilities: [], type_parameters: [] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: [], type_parameters: [] }], function_handles: [FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(3), parameters: SignatureIndex(0), return_: SignatureIndex(1), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(2), parameters: SignatureIndex(3), return_: SignatureIndex(4), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), parameters: SignatureIndex(6), return_: SignatureIndex(1), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), parameters: SignatureIndex(1), return_: SignatureIndex(8), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), parameters: SignatureIndex(10), return_: SignatureIndex(11), type_parameters: [] }], field_handles: [], friend_decls: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(1) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(2) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(3) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(4) }], struct_def_instantiations: [], function_instantiations: [], field_instantiations: [], signatures: [Signature([Vector(U64), U256, U16]), Signature([]), Signature([Signer, U32, U32]), Signature([Reference(U32), MutableReference(U64), U16]), Signature([Address, Reference(U64)]), Signature([Address, Reference(U256)]), Signature([U16, U128, U256]), Signature([MutableReference(U32)]), Signature([Struct(DatatypeHandleIndex(1)), Signer]), Signature([U256, Reference(U16), U64]), Signature([Bool, Reference(Struct(DatatypeHandleIndex(1)))]), Signature([Reference(U128)]), Signature([U16])], identifiers: [Identifier("A"), Identifier("A0"), Identifier("A1"), Identifier("Aa"), Identifier("a")], address_identifiers: [0000000000000000000000000000000000000000000000000000000000000000], constant_pool: [], metadata: [], struct_defs: [StructDefinition { struct_handle: DatatypeHandleIndex(0), field_information: Native }, StructDefinition { struct_handle: DatatypeHandleIndex(1), field_information: Native }, StructDefinition { struct_handle: DatatypeHandleIndex(2), field_information: Native }], function_defs: [FunctionDefinition { function: FunctionHandleIndex(0), visibility: Private, is_entry: true, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(2), code: [CopyLoc(2), MoveTo(StructDefinitionIndex(2)), BrTrue(0), ImmBorrowLoc(0), MutBorrowLoc(1), Unpack(0), MutBorrowGlobal(StructDefinitionIndex(1)), FreezeRef, Pack(1), MutBorrowLoc(2), MutBorrowGlobal(StructDefinitionIndex(1)), StLoc(2), MoveFrom(StructDefinitionIndex(1)), BrFalse(10)], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(1), visibility: Friend, is_entry: false, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(5), code: [CopyLoc(0), MutBorrowLoc(1), ImmBorrowLoc(1), MoveLoc(1), BrFalse(1), BrFalse(2), MutBorrowGlobal(StructDefinitionIndex(2)), MoveFrom(StructDefinitionIndex(0)), BrTrue(3), MutBorrowGlobal(StructDefinitionIndex(2))], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(2), visibility: Friend, is_entry: true, acquires_global_resources: [StructDefinitionIndex(1)], code: Some(CodeUnit { locals: SignatureIndex(7), code: [Exists(StructDefinitionIndex(0)), Call(0), Call(1), MutBorrowGlobal(StructDefinitionIndex(1)), MoveTo(StructDefinitionIndex(0)), ImmBorrowGlobal(StructDefinitionIndex(1)), StLoc(0), MoveLoc(0), LdU16(32190), Call(1), Ret, VariantSwitch(VariantJumpTableIndex(6)), Call(0), Lt, ImmBorrowGlobal(StructDefinitionIndex(2)), Branch(10), Call(0), MoveFrom(StructDefinitionIndex(0)), MutBorrowLoc(0), MoveTo(StructDefinitionIndex(0)), Unpack(0), MutBorrowLoc(0), Branch(0), MoveFrom(StructDefinitionIndex(2)), ImmBorrowLoc(0)], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(3), visibility: Private, is_entry: false, acquires_global_resources: [StructDefinitionIndex(1)], code: Some(CodeUnit { locals: SignatureIndex(9), code: [MoveFrom(StructDefinitionIndex(1)), Exists(StructDefinitionIndex(1)), MutBorrowGlobal(StructDefinitionIndex(2)), BrTrue(1), MutBorrowGlobal(StructDefinitionIndex(0)), Branch(3), CopyLoc(0), BrFalse(2), Exists(StructDefinitionIndex(1)), Call(1), MoveTo(StructDefinitionIndex(0)), VariantSwitch(VariantJumpTableIndex(0)), MoveFrom(StructDefinitionIndex(1)), ImmBorrowLoc(0), MoveTo(StructDefinitionIndex(1)), VariantSwitch(VariantJumpTableIndex(1)), CopyLoc(1), BrFalse(4), MutBorrowGlobal(StructDefinitionIndex(2)), BrTrue(11), Branch(7), ImmBorrowGlobal(StructDefinitionIndex(0)), MoveFrom(StructDefinitionIndex(2)), MoveTo(StructDefinitionIndex(2))], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(4), visibility: Friend, is_entry: true, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(12), code: [MutBorrowLoc(0), VariantSwitch(VariantJumpTableIndex(1)), MutBorrowGlobal(StructDefinitionIndex(0)), MoveLoc(0), MutBorrowGlobal(StructDefinitionIndex(1)), Call(3), ImmBorrowGlobal(StructDefinitionIndex(1)), StLoc(0), MoveLoc(0), Pack(2), Pack(2), MutBorrowLoc(0), ImmBorrowLoc(0), CopyLoc(0), MoveLoc(0)], jump_tables: [] }) }], enum_defs: [], enum_def_instantiations: [] } +cc 83d70dd923cb051c380fd60030ce45a55ff65825b64d550f8cd2a8cf1df5bb74 # shrinks to module = CompiledModule { version: 7, self_module_handle_idx: ModuleHandleIndex(0), module_handles: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }], datatype_handles: [DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), abilities: [], type_parameters: [DatatypeTyParameter { constraints: [Copy, ], is_phantom: true }, DatatypeTyParameter { constraints: [], is_phantom: true }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(3), abilities: [Copy, Drop, Store, ], type_parameters: [DatatypeTyParameter { constraints: [Copy, Drop, ], is_phantom: true }, DatatypeTyParameter { constraints: [], is_phantom: false }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: [Drop, ], type_parameters: [DatatypeTyParameter { constraints: [Drop, Store, ], is_phantom: false }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(6), abilities: [Drop, Store, ], type_parameters: [DatatypeTyParameter { constraints: [Copy, Drop, ], is_phantom: false }, DatatypeTyParameter { constraints: [Drop, ], is_phantom: false }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(7), abilities: [Copy, Drop, ], type_parameters: [DatatypeTyParameter { constraints: [Copy, ], is_phantom: false }, DatatypeTyParameter { constraints: [Copy, ], is_phantom: false }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(9), abilities: [Copy, Store, ], type_parameters: [DatatypeTyParameter { constraints: [], is_phantom: true }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), abilities: [], type_parameters: [] }], function_handles: [FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(9), parameters: SignatureIndex(2), return_: SignatureIndex(3), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(7), parameters: SignatureIndex(7), return_: SignatureIndex(8), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(5), parameters: SignatureIndex(1), return_: SignatureIndex(9), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(2), parameters: SignatureIndex(11), return_: SignatureIndex(12), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(6), parameters: SignatureIndex(13), return_: SignatureIndex(1), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), parameters: SignatureIndex(15), return_: SignatureIndex(16), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), parameters: SignatureIndex(1), return_: SignatureIndex(18), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), parameters: SignatureIndex(19), return_: SignatureIndex(20), type_parameters: [] }], field_handles: [], friend_decls: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(5) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(9) }], struct_def_instantiations: [StructDefInstantiation { def: StructDefinitionIndex(0), type_parameters: SignatureIndex(4) }], function_instantiations: [], field_instantiations: [], signatures: [Signature([U8, Reference(U64), Signer]), Signature([]), Signature([Reference(U8)]), Signature([Reference(U256), Reference(U128)]), Signature([U64, U64]), Signature([U64, Signer]), Signature([Vector(U256), U32]), Signature([StructInstantiation(DatatypeHandleIndex(3), [U64, Signer])]), Signature([U256]), Signature([U64]), Signature([U32, U256]), Signature([Vector(StructInstantiation(DatatypeHandleIndex(2), [U64])), Vector(StructInstantiation(DatatypeHandleIndex(0), [U64, U64]))]), Signature([U128, U8]), Signature([MutableReference(U32), U16, StructInstantiation(DatatypeHandleIndex(5), [U64])]), Signature([StructInstantiation(DatatypeHandleIndex(3), [U64, Signer]), Reference(Signer)]), Signature([Vector(U32), U8]), Signature([Address]), Signature([U256, MutableReference(Bool)]), Signature([U32]), Signature([Signer, Reference(StructInstantiation(DatatypeHandleIndex(5), [U64]))]), Signature([U16, Vector(U128)]), Signature([U64, U8])], identifiers: [Identifier("A"), Identifier("A0"), Identifier("AA"), Identifier("A_"), Identifier("Aa"), Identifier("a"), Identifier("a0"), Identifier("aa"), Identifier("ab"), Identifier("b")], address_identifiers: [0000000000000000000000000000000000000000000000000000000000000000], constant_pool: [], metadata: [], struct_defs: [StructDefinition { struct_handle: DatatypeHandleIndex(0), field_information: Native }], function_defs: [FunctionDefinition { function: FunctionHandleIndex(0), visibility: Public, is_entry: true, acquires_global_resources: [StructDefinitionIndex(0)], code: Some(CodeUnit { locals: SignatureIndex(6), code: [CopyLoc(0), VariantSwitch(VariantJumpTableIndex(0)), BrTrue(0), Branch(0), BrFalse(1), BrFalse(2), Branch(4), Branch(5), MoveFromGeneric(StructDefInstantiationIndex(0)), UnpackVariantGenericMutRef(EnumDefInstantiationIndex(0), 165), BrFalse(1), MoveToGeneric(StructDefInstantiationIndex(0)), UnpackGeneric(0), Sub, BrTrue(13), UnpackGeneric(0), Call(0), MoveToGeneric(StructDefInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ExistsGeneric(StructDefInstantiationIndex(0)), ImmBorrowLoc(1), BrTrue(20), MutBorrowLoc(0)], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(2), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(4), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(5), jump_table: [(0, 0), (1, 0), (2, 0)] }] }) }, FunctionDefinition { function: FunctionHandleIndex(1), visibility: Public, is_entry: true, acquires_global_resources: [StructDefinitionIndex(0)], code: Some(CodeUnit { locals: SignatureIndex(1), code: [MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ExistsGeneric(StructDefInstantiationIndex(0)), PackGeneric(0), LdU8(13)], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(5), jump_table: [(0, 0), (1, 0), (2, 0)] }] }) }, FunctionDefinition { function: FunctionHandleIndex(2), visibility: Friend, is_entry: false, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(10), code: [MoveFromGeneric(StructDefInstantiationIndex(0)), Gt, MutBorrowLoc(0), Call(1), ImmBorrowLoc(0), Branch(3), CopyLoc(0), ExistsGeneric(StructDefInstantiationIndex(0)), Branch(0), MoveLoc(1), UnpackVariantGeneric(EnumDefInstantiationIndex(1), 150), MoveFromGeneric(StructDefInstantiationIndex(0)), VecPushBack(8)], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(5), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [(0, 0)] }] }) }, FunctionDefinition { function: FunctionHandleIndex(3), visibility: Private, is_entry: false, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(1), code: [ExistsGeneric(StructDefInstantiationIndex(0)), UnpackGeneric(0), Le, MoveToGeneric(StructDefInstantiationIndex(0)), VariantSwitch(VariantJumpTableIndex(7)), Call(1), ExistsGeneric(StructDefInstantiationIndex(0)), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), PackGeneric(0), ExistsGeneric(StructDefInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), Or, Branch(10), ExistsGeneric(StructDefInstantiationIndex(0))], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(4), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(4), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(4), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(0), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(5), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(3), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(4), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(5), jump_table: [(0, 0), (1, 0), (2, 0)] }] }) }, FunctionDefinition { function: FunctionHandleIndex(4), visibility: Friend, is_entry: false, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(14), code: [UnpackGeneric(0), Call(4), MutBorrowLoc(0), VariantSwitch(VariantJumpTableIndex(5)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), Call(3), ImmBorrowLoc(0), MoveToGeneric(StructDefInstantiationIndex(0)), VariantSwitch(VariantJumpTableIndex(3)), ImmBorrowLoc(1)], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(5), jump_table: [(0, 0), (1, 0), (2, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(3), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(3), jump_table: [(0, 0)] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [(0, 0)] }] }) }, FunctionDefinition { function: FunctionHandleIndex(5), visibility: Friend, is_entry: false, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(17), code: [Call(0), BrFalse(0), ImmBorrowLoc(0), StLoc(1), ImmBorrowLoc(0), LdU8(60), BrTrue(3), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ImmBorrowLoc(1), Call(2), MutBorrowLoc(1), VecSwap(9), MoveLoc(0), MutBorrowLoc(0), Branch(13)], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(6), visibility: Friend, is_entry: false, acquires_global_resources: [StructDefinitionIndex(0)], code: Some(CodeUnit { locals: SignatureIndex(8), code: [MoveFromGeneric(StructDefInstantiationIndex(0)), MoveLoc(0), VecPushBack(9), ExistsGeneric(StructDefInstantiationIndex(0))], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(7), visibility: Public, is_entry: true, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(21), code: [MoveLoc(0), PackGeneric(0), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), MutBorrowLoc(0), MutBorrowLoc(0), LdU64(13240554763673404448), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MoveFromGeneric(StructDefInstantiationIndex(0)), StLoc(0), PackGeneric(0), UnpackGeneric(0), Branch(6), MoveLoc(0), ImmBorrowLoc(1), MutBorrowLoc(1)], jump_tables: [] }) }], enum_defs: [EnumDefinition { enum_handle: DatatypeHandleIndex(1), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(0), variant_name: IdentifierIndex(6), fields: [FieldDefinition { name: IdentifierIndex(6), signature: TypeSignature(U256) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(6), signature: TypeSignature(U32) }, FieldDefinition { name: IdentifierIndex(0), signature: TypeSignature(U128) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(2), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(1), variant_name: IdentifierIndex(0), fields: [FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(Signer) }, FieldDefinition { name: IdentifierIndex(6), signature: TypeSignature(U256) }, FieldDefinition { name: IdentifierIndex(0), signature: TypeSignature(U16) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(3), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(2), variant_name: IdentifierIndex(7), fields: [FieldDefinition { name: IdentifierIndex(9), signature: TypeSignature(U32) }, FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(U8) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(4), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(3), variant_name: IdentifierIndex(2), fields: [] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(5), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(1), fields: [FieldDefinition { name: IdentifierIndex(6), signature: TypeSignature(U64) }, FieldDefinition { name: IdentifierIndex(2), signature: TypeSignature(U128) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(9), fields: [] }, VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(7), fields: [FieldDefinition { name: IdentifierIndex(8), signature: TypeSignature(U16) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(U128) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(6), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(5), variant_name: IdentifierIndex(5), fields: [FieldDefinition { name: IdentifierIndex(8), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(8), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(U16) }, FieldDefinition { name: IdentifierIndex(0), signature: TypeSignature(StructInstantiation(DatatypeHandleIndex(2), [U64])) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(5), variant_name: IdentifierIndex(3), fields: [FieldDefinition { name: IdentifierIndex(3), signature: TypeSignature(U16) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(5), variant_name: IdentifierIndex(0), fields: [FieldDefinition { name: IdentifierIndex(9), signature: TypeSignature(Bool) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(U128) }] }] }], enum_def_instantiations: [EnumDefInstantiation { def: EnumDefinitionIndex(2), type_parameters: SignatureIndex(5) }, EnumDefInstantiation { def: EnumDefinitionIndex(1), type_parameters: SignatureIndex(9) }] } +cc 5f7de53bc7d15f416129324e594ee5e6e16d974ba1706c0e9a1355de515d986e # shrinks to module = CompiledModule { version: 7, self_module_handle_idx: ModuleHandleIndex(0), module_handles: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }], datatype_handles: [DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), abilities: [], type_parameters: [DatatypeTyParameter { constraints: [Drop, Store, ], is_phantom: true }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(1), abilities: [Copy, Store, ], type_parameters: [DatatypeTyParameter { constraints: [Copy, Store, ], is_phantom: true }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(11), abilities: [Copy, Drop, Store, ], type_parameters: [DatatypeTyParameter { constraints: [Store, ], is_phantom: false }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(9), abilities: [Store, ], type_parameters: [DatatypeTyParameter { constraints: [Copy, Drop, ], is_phantom: true }, DatatypeTyParameter { constraints: [Store, ], is_phantom: true }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), abilities: [Copy, ], type_parameters: [DatatypeTyParameter { constraints: [Copy, Drop, ], is_phantom: true }] }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(8), abilities: [Copy, Drop, Store, ], type_parameters: [] }], function_handles: [FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(5), parameters: SignatureIndex(0), return_: SignatureIndex(1), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), parameters: SignatureIndex(4), return_: SignatureIndex(5), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), parameters: SignatureIndex(7), return_: SignatureIndex(8), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(12), parameters: SignatureIndex(10), return_: SignatureIndex(11), type_parameters: [] }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(9), parameters: SignatureIndex(9), return_: SignatureIndex(13), type_parameters: [] }], field_handles: [FieldHandle { owner: StructDefinitionIndex(0), field: 1 }, FieldHandle { owner: StructDefinitionIndex(0), field: 0 }, FieldHandle { owner: StructDefinitionIndex(0), field: 2 }], friend_decls: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(1) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(2) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(3) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(4) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(6) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(8) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(10) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(11) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(12) }], struct_def_instantiations: [StructDefInstantiation { def: StructDefinitionIndex(0), type_parameters: SignatureIndex(2) }], function_instantiations: [], field_instantiations: [FieldInstantiation { handle: FieldHandleIndex(0), type_parameters: SignatureIndex(2) }, FieldInstantiation { handle: FieldHandleIndex(1), type_parameters: SignatureIndex(2) }, FieldInstantiation { handle: FieldHandleIndex(2), type_parameters: SignatureIndex(2) }], signatures: [Signature([U64, U16]), Signature([MutableReference(Bool)]), Signature([U64]), Signature([Reference(U256), Signer]), Signature([Reference(U128)]), Signature([Reference(U256), Reference(U128)]), Signature([Bool, U128]), Signature([Address, Vector(Signer), Vector(Address)]), Signature([Signer, Reference(U64)]), Signature([]), Signature([MutableReference(U256), U8, U128]), Signature([U128]), Signature([MutableReference(U64), Reference(U8)]), Signature([Bool]), Signature([MutableReference(U256)])], identifiers: [Identifier("A"), Identifier("A0"), Identifier("Aa"), Identifier("Ab"), Identifier("Ac"), Identifier("a"), Identifier("a0"), Identifier("a1"), Identifier("aA"), Identifier("aB"), Identifier("a_"), Identifier("aa"), Identifier("ab")], address_identifiers: [0000000000000000000000000000000000000000000000000000000000000000], constant_pool: [], metadata: [], struct_defs: [StructDefinition { struct_handle: DatatypeHandleIndex(0), field_information: Declared([FieldDefinition { name: IdentifierIndex(6), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(3), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(1), signature: TypeSignature(Signer) }]) }], function_defs: [FunctionDefinition { function: FunctionHandleIndex(0), visibility: Private, is_entry: true, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(3), code: [MoveToGeneric(StructDefInstantiationIndex(0)), MoveFromGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), Call(0), StLoc(0), MoveToGeneric(StructDefInstantiationIndex(0)), Branch(5), LdU256(27150304169822942040448621739271915450334201897421424980465722457989341478899), ExistsGeneric(StructDefInstantiationIndex(0)), VecPushBack(2), MutBorrowFieldGeneric(FieldInstantiationIndex(0)), UnpackVariantMutRef(EnumDefinitionIndex(4), 4), ExistsGeneric(StructDefInstantiationIndex(0)), StLoc(1), MutBorrowFieldGeneric(FieldInstantiationIndex(1)), ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), MutBorrowFieldGeneric(FieldInstantiationIndex(1)), VariantSwitch(VariantJumpTableIndex(0))], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(0), jump_table: [0, 0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(4), jump_table: [0, 0, 0, 0] }] }) }, FunctionDefinition { function: FunctionHandleIndex(1), visibility: Private, is_entry: true, acquires_global_resources: [StructDefinitionIndex(0)], code: Some(CodeUnit { locals: SignatureIndex(6), code: [MutBorrowLoc(1), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), Branch(1), ExistsGeneric(StructDefInstantiationIndex(0)), MoveLoc(1), StLoc(1), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), VecPushBack(2), StLoc(0), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MutBorrowFieldGeneric(FieldInstantiationIndex(1)), UnpackGeneric(0), VecMutBorrow(2), CopyLoc(0), CopyLoc(1), Call(1), MoveFromGeneric(StructDefInstantiationIndex(0)), Branch(10), Mul, UnpackGeneric(0), ImmBorrowFieldGeneric(FieldInstantiationIndex(1)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ImmBorrowFieldGeneric(FieldInstantiationIndex(1)), BrFalse(1)], jump_tables: [] }) }, FunctionDefinition { function: FunctionHandleIndex(2), visibility: Friend, is_entry: false, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(9), code: [ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), Branch(0), Not, MutBorrowFieldGeneric(FieldInstantiationIndex(0)), BrTrue(1), VariantSwitch(VariantJumpTableIndex(0)), ExistsGeneric(StructDefInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MoveFromGeneric(StructDefInstantiationIndex(0)), BrTrue(2), PackGeneric(0), ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), MutBorrowFieldGeneric(FieldInstantiationIndex(2)), LdFalse, ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), MoveFromGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0))], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(0), jump_table: [0, 0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [0] }] }) }, FunctionDefinition { function: FunctionHandleIndex(3), visibility: Friend, is_entry: true, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(12), code: [ImmBorrowFieldGeneric(FieldInstantiationIndex(2)), BrFalse(0), Branch(0), MoveFromGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), VecSwap(2), ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), StLoc(0), MoveLoc(0), BrFalse(3), PackGeneric(0), StLoc(0), MutBorrowFieldGeneric(FieldInstantiationIndex(1)), MutBorrowFieldGeneric(FieldInstantiationIndex(2)), ImmBorrowLoc(0), MoveLoc(1), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), CopyLoc(1)], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(3), jump_table: [0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(2), jump_table: [0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(0), jump_table: [0, 0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(1), jump_table: [0] }, VariantJumpTable { head_enum: EnumDefinitionIndex(0), jump_table: [0, 0] }] }) }, FunctionDefinition { function: FunctionHandleIndex(4), visibility: Public, is_entry: false, acquires_global_resources: [StructDefinitionIndex(0)], code: Some(CodeUnit { locals: SignatureIndex(14), code: [VecPushBack(2), MoveToGeneric(StructDefInstantiationIndex(0)), CopyLoc(0), Branch(1), Branch(3), BrTrue(1), Call(3), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ImmBorrowFieldGeneric(FieldInstantiationIndex(1)), MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), ImmBorrowFieldGeneric(FieldInstantiationIndex(1)), MutBorrowLoc(0), BrTrue(9), CopyLoc(0), PackGeneric(0), ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), MoveToGeneric(StructDefInstantiationIndex(0)), UnpackGeneric(0), BrFalse(1), MoveToGeneric(StructDefInstantiationIndex(0)), ImmBorrowFieldGeneric(FieldInstantiationIndex(1)), MutBorrowFieldGeneric(FieldInstantiationIndex(2)), ExistsGeneric(StructDefInstantiationIndex(0)), ImmBorrowLoc(0), MoveToGeneric(StructDefInstantiationIndex(0)), Call(2)], jump_tables: [VariantJumpTable { head_enum: EnumDefinitionIndex(0), jump_table: [0, 0] }] }) }], enum_defs: [EnumDefinition { enum_handle: DatatypeHandleIndex(1), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(0), variant_name: IdentifierIndex(4), fields: [FieldDefinition { name: IdentifierIndex(10), signature: TypeSignature(U32) }, FieldDefinition { name: IdentifierIndex(4), signature: TypeSignature(Address) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(0), variant_name: IdentifierIndex(7), fields: [FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(U8) }, FieldDefinition { name: IdentifierIndex(4), signature: TypeSignature(U128) }, FieldDefinition { name: IdentifierIndex(12), signature: TypeSignature(U128) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(2), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(1), variant_name: IdentifierIndex(7), fields: [] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(3), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(2), variant_name: IdentifierIndex(7), fields: [FieldDefinition { name: IdentifierIndex(10), signature: TypeSignature(U64) }, FieldDefinition { name: IdentifierIndex(6), signature: TypeSignature(U64) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(4), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(3), variant_name: IdentifierIndex(9), fields: [FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(StructInstantiation(DatatypeHandleIndex(1), [U64])) }, FieldDefinition { name: IdentifierIndex(8), signature: TypeSignature(U128) }, FieldDefinition { name: IdentifierIndex(0), signature: TypeSignature(U64) }, FieldDefinition { name: IdentifierIndex(4), signature: TypeSignature(U128) }] }] }, EnumDefinition { enum_handle: DatatypeHandleIndex(5), variants: [VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(2), fields: [FieldDefinition { name: IdentifierIndex(11), signature: TypeSignature(U256) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(Bool) }, FieldDefinition { name: IdentifierIndex(1), signature: TypeSignature(U256) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(7), fields: [FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(U128) }, FieldDefinition { name: IdentifierIndex(8), signature: TypeSignature(U8) }, FieldDefinition { name: IdentifierIndex(3), signature: TypeSignature(U256) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(8), fields: [FieldDefinition { name: IdentifierIndex(4), signature: TypeSignature(U256) }] }, VariantDefinition { enum_def: EnumDefinitionIndex(4), variant_name: IdentifierIndex(3), fields: [FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(U32) }, FieldDefinition { name: IdentifierIndex(12), signature: TypeSignature(Bool) }] }] }], enum_def_instantiations: [] }