diff --git a/external-crates/move/crates/move-compiler/src/typing/core.rs b/external-crates/move/crates/move-compiler/src/typing/core.rs index c4a40b5f5e3bc..5e591db5bd8fc 100644 --- a/external-crates/move/crates/move-compiler/src/typing/core.rs +++ b/external-crates/move/crates/move-compiler/src/typing/core.rs @@ -1727,15 +1727,14 @@ fn check_function_visibility( pub enum PublicForTesting { /// The function is entry, so it can be called in unit tests Entry(Loc), - // TODO we should allow calling init in unit tests, but this would need Sui bytecode verifier - // support. Or we would need to name dodge init in unit tests - // SuiInit(Loc), + /// We allow calling init in unit tests in Sui mode + SuiInit, } pub fn public_testing_visibility( env: &CompilationEnv, - _package: Option, - _callee_name: &FunctionName, + package: Option, + callee_name: &FunctionName, callee_entry: Option, ) -> Option { // is_testing && (is_entry || is_sui_init) @@ -1743,9 +1742,10 @@ pub fn public_testing_visibility( return None; } - // TODO support sui init functions - // let flavor = env.package_config(package).flavor; - // flavor == Flavor::Sui && callee_name.value() == INIT_FUNCTION_NAME + let is_sui_mode = env.package_config(package).flavor == crate::editions::Flavor::Sui; + if is_sui_mode && callee_name.value() == crate::sui_mode::INIT_FUNCTION_NAME { + return Some(PublicForTesting::SuiInit); + } callee_entry.map(PublicForTesting::Entry) } @@ -1781,6 +1781,16 @@ fn report_visibility_error_( ); (entry_loc, entry_msg) } + PublicForTesting::SuiInit => { + let entry_msg = format!( + "'{}' functions can be called in tests, \ + but only from testing contexts, e.g. '#[{}]' or '#[{}]'", + crate::sui_mode::INIT_FUNCTION_NAME, + TestingAttribute::TEST, + TestingAttribute::TEST_ONLY, + ); + (Loc::invalid(), entry_msg) + } }; diag.add_secondary_label((test_loc, test_msg)) } diff --git a/external-crates/move/crates/move-compiler/src/typing/translate.rs b/external-crates/move/crates/move-compiler/src/typing/translate.rs index eae837f12f774..8eaf77a864d13 100644 --- a/external-crates/move/crates/move-compiler/src/typing/translate.rs +++ b/external-crates/move/crates/move-compiler/src/typing/translate.rs @@ -303,6 +303,7 @@ fn function(context: &mut Context, name: FunctionName, f: N::Function) -> T::Fun let compiled_visibility = match public_testing_visibility(context.env, context.current_package, &name, entry) { Some(PublicForTesting::Entry(loc)) => Visibility::Public(loc), + Some(PublicForTesting::SuiInit) => Visibility::Public(Loc::invalid()), None => visibility, }; function_signature(context, macro_, &signature); diff --git a/external-crates/move/crates/move-compiler/tests/sui_mode/init/cross_module_init_function.move b/external-crates/move/crates/move-compiler/tests/sui_mode/init/cross_module_init_function.move new file mode 100644 index 0000000000000..d3247f553ddb9 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/sui_mode/init/cross_module_init_function.move @@ -0,0 +1,17 @@ +// check that fun `init` can be used cross module in sui-mode +module 0x1::M { + fun init(_ctx: &mut sui::tx_context::TxContext) { } +} + +module 0x1::Tests { + #[test] + fun tester() { + use 0x1::M; + let ctx = sui::tx_context::TxContext {}; + M::init(&ctx); + } +} + +module sui::tx_context { + struct TxContext has drop {} +}