diff --git a/third_party/move/move-compiler-v2/src/bytecode_generator.rs b/third_party/move/move-compiler-v2/src/bytecode_generator.rs index 19d571863998a..e6be8ca0e80c5 100644 --- a/third_party/move/move-compiler-v2/src/bytecode_generator.rs +++ b/third_party/move/move-compiler-v2/src/bytecode_generator.rs @@ -2,6 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 +use crate::{experiments::Experiment, Options}; use codespan_reporting::diagnostic::Severity; use ethnum::U256; use itertools::Itertools; @@ -324,6 +325,14 @@ impl<'env> Generator<'env> { let loc = env.get_node_loc(id); env.diag(severity, &loc, msg.as_ref()) } + + fn check_if_lambdas_enabled(&self) -> bool { + let options = self + .env() + .get_extension::() + .expect("Options is available"); + options.experiment_on(Experiment::LAMBDA_VALUES) + } } // ====================================================================================== @@ -480,14 +489,23 @@ impl<'env> Generator<'env> { self.emit_with(*id, |attr| Bytecode::SpecBlock(attr, spec)); }, // TODO(LAMBDA) - ExpData::Lambda(id, _, _, _, _) => self.error( + ExpData::Lambda(id, _, _, _, _) => + self.error( *id, - "Function-typed values not yet supported except as parameters to calls to inline functions", + if self.check_if_lambdas_enabled() { + "Function-typed values not yet implemented except as parameters to calls to inline functions" + } else { + "Function-typed values not yet supported except as parameters to calls to inline functions" + } ), // TODO(LAMBDA) ExpData::Invoke(id, _exp, _) => self.error( *id, - "Calls to function values other than inline function parameters not yet supported", + if self.check_if_lambdas_enabled() { + "Calls to function values other than inline function parameters not yet implemented" + } else { + "Calls to function values other than inline function parameters not yet supported" + } ), ExpData::Quant(id, _, _, _, _, _) => { self.internal_error(*id, "unsupported specification construct") @@ -564,10 +582,16 @@ impl<'env> Generator<'env> { Constant::Bool(false) } }, + // TODO(LAMBDA) Value::Function(_mid, _fid) => { self.error( id, - "Function-typed values not yet supported except as parameters to calls to inline functions"); + if self.check_if_lambdas_enabled() { + "Function-typed values not yet implemented except as parameters to calls to inline functions" + } else { + "Function-typed values not yet supported except as parameters to calls to inline functions" + } + ); Constant::Bool(false) }, } @@ -794,7 +818,11 @@ impl<'env> Generator<'env> { // TODO(LAMBDA) Operation::EarlyBind => self.error( id, - "Function-typed values not yet supported except as parameters to calls to inline functions", + if self.check_if_lambdas_enabled() { + "Function-typed values not yet implemented except as parameters to calls to inline functions" + } else { + "Function-typed values not yet supported except as parameters to calls to inline functions" + }, ), Operation::TestVariants(mid, sid, variants) => { self.gen_test_variants(targets, id, mid.qualified(*sid), variants, args) diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs index d16593bac2da0..f3f661ba11f30 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs @@ -739,7 +739,7 @@ impl<'a> ExpRewriterFunctions for LambdaLifter<'a> { env.error( &loc, // TODO(LAMBDA) - "Lambdas expressions with `store` ability currently may only be a simple call to an existing `public` function. This lambda expression requires defining a `public` helper function, which is not yet supported." + "The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call." ); return None; }; diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs index ce120a5ca1170..96b2904f042a9 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs @@ -372,7 +372,7 @@ impl ModuleGenerator { ctx.error( loc, format!( - "Unexpected type: {}", + "Unimplemented type: {}", ty.display(&ctx.env.get_type_display_ctx()) ), ); diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp new file mode 100644 index 0000000000000..ff76888fa7377 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp @@ -0,0 +1,66 @@ + +Diagnostics: +warning: Unused parameter `f`. Consider removing or prefixing with an underscore: `_f` + ┌─ tests/checking/inlining/function_name_shadowing.move:20:28 + │ +20 │ public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + │ ^ + +warning: Unused parameter `g`. Consider removing or prefixing with an underscore: `_g` + ┌─ tests/checking/inlining/function_name_shadowing.move:20:45 + │ +20 │ public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + │ ^ + +warning: Unused parameter `i`. Consider removing or prefixing with an underscore: `_i` + ┌─ tests/checking/inlining/function_name_shadowing.move:20:57 + │ +20 │ public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + │ ^ + +// -- Model dump before bytecode pipeline +module 0x42::OtherModule { + public fun g(a: u64,b: u64): u64 { + Add(a, b) + } + public fun h(a: u64,b: u64): u64 { + Add(Mul(2, a), b) + } +} // end 0x42::OtherModule +module 0x42::Test { + use 0x42::OtherModule::{g}; // resolved as: 0x42::OtherModule + public fun f(a: u64,b: u64): u64 { + Mul(a, b) + } + public inline fun quux(f: |(u64, u64)|u64,g: |u64|u64,i: |u8|u8,a: u64,b: u64): u64 { + Mul(Mul(Test::f(a, b), OtherModule::g(a, b)), OtherModule::h(a, b)) + } + public fun test_shadowing(): u64 { + Mul(Mul(Test::f(10, 2), OtherModule::g(10, 2)), OtherModule::h(10, 2)) + } +} // end 0x42::Test + +// -- Sourcified model before bytecode pipeline +module 0x42::OtherModule { + public fun g(a: u64, b: u64): u64 { + a + b + } + public fun h(a: u64, b: u64): u64 { + 2 * a + b + } +} +module 0x42::Test { + use 0x42::OtherModule; + public fun f(a: u64, b: u64): u64 { + a * b + } + public inline fun quux(f: |(u64, u64)|u64, g: |u64|u64, i: |u8|u8, a: u64, b: u64): u64 { + f(a, b) * OtherModule::g(a, b) * OtherModule::h(a, b) + } + public fun test_shadowing(): u64 { + f(10, 2) * OtherModule::g(10, 2) * OtherModule::h(10, 2) + } +} + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.move b/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.move new file mode 100644 index 0000000000000..e527c426c7eef --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.move @@ -0,0 +1,30 @@ +//# publish +module 0x42::OtherModule { + public fun g(a: u64, b: u64): u64 { + a + b + } + + public fun h(a: u64, b: u64): u64 { + 2 * a + b + } +} + +//# publish +module 0x42::Test { + use 0x42::OtherModule::g; + + public fun f(a: u64, b: u64): u64 { + a * b + } + + public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + use 0x42::OtherModule::h; + f(a, b) * g(a, b) * h(a, b) + } + + public fun test_shadowing(): u64 { + quux(|a, b| a - b, |a| a + 2, |b| 255u8-b, 10, 2) + } +} + +//# run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/lambda.exp b/third_party/move/move-compiler-v2/tests/checking/typing/lambda.exp index 51ad60912dcd3..ec2b425961e52 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/lambda.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/lambda.exp @@ -48,11 +48,3 @@ error: tuple type `()` is not allowed as a type argument (type was inferred) │ ^ │ = required by instantiating type parameter `T` of function `foreach` - -error: function type `|u64|u64` is not allowed as a field type - ┌─ tests/checking/typing/lambda.move:81:12 - │ -81 │ f: |u64|u64, // expected lambda not allowed - │ ^^^^^^^^ - │ - = required by declaration of field `f` diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/lambda_typed.exp b/third_party/move/move-compiler-v2/tests/checking/typing/lambda_typed.exp index b3c6fa59c5fb7..e12ab89c8a728 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/lambda_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/lambda_typed.exp @@ -35,11 +35,3 @@ error: cannot pass `|&u64|u64 with copy+store` to a function which expects argum │ 73 │ foreach(&v, |e: &u64| { sum = sum + *e; *e }) // expected to have wrong result type of lambda │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: function type `|u64|u64` is not allowed as a field type - ┌─ tests/checking/typing/lambda_typed.move:81:12 - │ -81 │ f: |u64|u64, // expected lambda not allowed - │ ^^^^^^^^ - │ - = required by declaration of field `f` diff --git a/third_party/move/move-compiler-v2/tests/lambda/inline-parity/subtype_args.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/inline-parity/subtype_args.lambda.exp index 13fdcad48d3be..9db6927c3bd50 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/inline-parity/subtype_args.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/inline-parity/subtype_args.lambda.exp @@ -532,13 +532,13 @@ module 0x8675309::M { Diagnostics: -error: Calls to function values other than inline function parameters not yet supported +error: Calls to function values other than inline function parameters not yet implemented ┌─ tests/lambda/inline-parity/subtype_args.move:24:9 │ 24 │ f(&mut 0, &mut 0); │ ^^^^^^^^^^^^^^^^^ -error: Calls to function values other than inline function parameters not yet supported +error: Calls to function values other than inline function parameters not yet implemented ┌─ tests/lambda/inline-parity/subtype_args.move:25:9 │ 25 │ f(&0, &mut 0); diff --git a/third_party/move/move-compiler-v2/tests/lambda/lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/lambda.exp index 7328ae7924537..a21a059fa0d53 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/lambda.exp @@ -48,11 +48,3 @@ error: tuple type `()` is not allowed as a type argument (type was inferred) │ ^ │ = required by instantiating type parameter `T` of function `foreach` - -error: function type `|u64|u64` is not allowed as a field type - ┌─ tests/lambda/lambda.move:81:12 - │ -81 │ f: |u64|u64, // expected lambda not allowed - │ ^^^^^^^^ - │ - = required by declaration of field `f` diff --git a/third_party/move/move-compiler-v2/tests/lambda/lambda.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/lambda.lambda.exp index 7328ae7924537..a21a059fa0d53 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/lambda.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/lambda.lambda.exp @@ -48,11 +48,3 @@ error: tuple type `()` is not allowed as a type argument (type was inferred) │ ^ │ = required by instantiating type parameter `T` of function `foreach` - -error: function type `|u64|u64` is not allowed as a field type - ┌─ tests/lambda/lambda.move:81:12 - │ -81 │ f: |u64|u64, // expected lambda not allowed - │ ^^^^^^^^ - │ - = required by declaration of field `f` diff --git a/third_party/move/move-compiler-v2/tests/lambda/lambda4.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/lambda4.lambda.exp index f374630d851fb..07f8e32499a97 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/lambda4.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/lambda4.lambda.exp @@ -177,7 +177,7 @@ public fun M::fun_result_lambda_not_allowed(): |u64| { Diagnostics: -error: Unexpected type: |u64| +error: Unimplemented type: |u64| ┌─ tests/lambda/lambda4.move:89:16 │ 89 │ public fun fun_result_lambda_not_allowed(): |u64| { // expected lambda not allowed diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.exp new file mode 100644 index 0000000000000..c3015376ea32d --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.exp @@ -0,0 +1,781 @@ + +Diagnostics: +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:59:17 + │ +59 │ move |x| base_fun(a, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:61:17 + │ +61 │ move |x| base_fun2(x, a) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:63:17 + │ +63 │ move |x| copy_fun(a_copy, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:65:17 + │ +65 │ move |x| copy_fun2(x, a_copy) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:67:17 + │ +67 │ move |x| store_fun(a_store, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:69:17 + │ +69 │ move |x| store_fun2(x, a_store) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:71:17 + │ +71 │ move |x| both_fun(a_both, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:73:17 + │ +73 │ move |x| both_fun2(x, a_both) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:75:17 + │ +75 │ move |x| x * 2 + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:88:17 + │ +88 │ move |x| base_fun(a, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:90:17 + │ +90 │ move |x| base_fun2(x, a) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:92:17 + │ +92 │ move |x| copy_fun(a_copy, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:94:17 + │ +94 │ move |x| copy_fun2(x, a_copy) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:96:17 + │ +96 │ move |x| store_fun(a_store, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:98:17 + │ +98 │ move |x| store_fun2(x, a_store) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:100:17 + │ +100 │ move |x| both_fun(a_both, x) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:102:17 + │ +102 │ move |x| both_fun2(x, a_both) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:104:17 + │ +104 │ move |x| x * 2 with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:104:32 + │ +104 │ move |x| x * 2 with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:119:17 + │ +119 │ move |x| base_fun(a, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:119:41 + │ +119 │ move |x| base_fun(a, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:121:17 + │ +121 │ move |x| base_fun2(x, a) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:121:42 + │ +121 │ move |x| base_fun2(x, a) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:123:17 + │ +123 │ move |x| copy_fun(a_copy, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:123:46 + │ +123 │ move |x| copy_fun(a_copy, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:125:17 + │ +125 │ move |x| copy_fun2(x, a_copy) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:125:47 + │ +125 │ move |x| copy_fun2(x, a_copy) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:127:17 + │ +127 │ move |x| store_fun(a_store, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:127:48 + │ +127 │ move |x| store_fun(a_store, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:129:17 + │ +129 │ move |x| store_fun2(x, a_store) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:129:49 + │ +129 │ move |x| store_fun2(x, a_store) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:131:17 + │ +131 │ move |x| both_fun(a_both, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:131:46 + │ +131 │ move |x| both_fun(a_both, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:133:17 + │ +133 │ move |x| both_fun2(x, a_both) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:133:47 + │ +133 │ move |x| both_fun2(x, a_both) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:135:17 + │ +135 │ move |x| x * 2 with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:135:32 + │ +135 │ move |x| x * 2 with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:140:65 + │ +140 │ public fun return_function_copy(key: u64, x: u64): |u64|u64 with copy { + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:148:17 + │ +148 │ move |x| base_fun(a, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:148:41 + │ +148 │ move |x| base_fun(a, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:150:17 + │ +150 │ move |x| base_fun2(x, a) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:150:42 + │ +150 │ move |x| base_fun2(x, a) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:152:17 + │ +152 │ move |x| copy_fun(a_copy, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:152:46 + │ +152 │ move |x| copy_fun(a_copy, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:154:17 + │ +154 │ move |x| copy_fun2(x, a_copy) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:154:47 + │ +154 │ move |x| copy_fun2(x, a_copy) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:156:17 + │ +156 │ move |x| store_fun(a_store, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:156:48 + │ +156 │ move |x| store_fun(a_store, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:158:17 + │ +158 │ move |x| store_fun2(x, a_store) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:158:49 + │ +158 │ move |x| store_fun2(x, a_store) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:160:17 + │ +160 │ move |x| both_fun(a_both, x) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:160:46 + │ +160 │ move |x| both_fun(a_both, x) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:162:17 + │ +162 │ move |x| both_fun2(x, a_both) with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:162:47 + │ +162 │ move |x| both_fun2(x, a_both) with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:164:17 + │ +164 │ move |x| x * 2 with copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:164:32 + │ +164 │ move |x| x * 2 with copy + │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:178:17 + │ +178 │ move |x| base_fun(a, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:178:41 + │ +178 │ move |x| base_fun(a, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:180:17 + │ +180 │ move |x| base_fun2(x, a) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:180:42 + │ +180 │ move |x| base_fun2(x, a) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:182:17 + │ +182 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:182:46 + │ +182 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:184:17 + │ +184 │ move |x| copy_fun2(x, a_copy) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:184:47 + │ +184 │ move |x| copy_fun2(x, a_copy) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:186:17 + │ +186 │ move |x| store_fun(a_store, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:186:48 + │ +186 │ move |x| store_fun(a_store, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:188:17 + │ +188 │ move |x| store_fun2(x, a_store) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:188:49 + │ +188 │ move |x| store_fun2(x, a_store) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:190:17 + │ +190 │ move |x| both_fun(a_both, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:190:46 + │ +190 │ move |x| both_fun(a_both, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:192:17 + │ +192 │ move |x| both_fun2(x, a_both) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:192:47 + │ +192 │ move |x| both_fun2(x, a_both) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:194:17 + │ +194 │ move |x| x * 2 with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:194:32 + │ +194 │ move |x| x * 2 with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:199:66 + │ +199 │ public fun return_function_store(key: u64, x: u64): |u64|u64 with store { + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:207:17 + │ +207 │ move |x| base_fun(a, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:207:41 + │ +207 │ move |x| base_fun(a, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:209:17 + │ +209 │ move |x| base_fun2(x, a) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:209:42 + │ +209 │ move |x| base_fun2(x, a) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:211:17 + │ +211 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:211:46 + │ +211 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:213:17 + │ +213 │ move |x| copy_fun2(x, a_copy) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:213:47 + │ +213 │ move |x| copy_fun2(x, a_copy) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:215:17 + │ +215 │ move |x| store_fun(a_store, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:215:48 + │ +215 │ move |x| store_fun(a_store, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:217:17 + │ +217 │ move |x| store_fun2(x, a_store) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:217:49 + │ +217 │ move |x| store_fun2(x, a_store) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:219:17 + │ +219 │ move |x| both_fun(a_both, x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:219:46 + │ +219 │ move |x| both_fun(a_both, x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:221:17 + │ +221 │ move |x| both_fun2(x, a_both) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:221:47 + │ +221 │ move |x| both_fun2(x, a_both) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:223:17 + │ +223 │ move |x| x * 2 with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:223:32 + │ +223 │ move |x| x * 2 with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:238:17 + │ +238 │ move |x| base_fun(a, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:238:41 + │ +238 │ move |x| base_fun(a, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:240:17 + │ +240 │ move |x| base_fun2(x, a) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:240:42 + │ +240 │ move |x| base_fun2(x, a) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:242:17 + │ +242 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:242:46 + │ +242 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:244:17 + │ +244 │ move |x| copy_fun2(x, a_copy) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:244:47 + │ +244 │ move |x| copy_fun2(x, a_copy) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:246:17 + │ +246 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:246:48 + │ +246 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:248:17 + │ +248 │ move |x| store_fun2(x, a_store) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:248:49 + │ +248 │ move |x| store_fun2(x, a_store) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:250:17 + │ +250 │ move |x| both_fun(a_both, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:250:46 + │ +250 │ move |x| both_fun(a_both, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:252:17 + │ +252 │ move |x| both_fun2(x, a_both) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:252:47 + │ +252 │ move |x| both_fun2(x, a_both) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:254:17 + │ +254 │ move |x| x * 2 with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:254:32 + │ +254 │ move |x| x * 2 with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:259:65 + │ +259 │ public fun return_function_both(key: u64, x: u64): |u64|u64 with store+copy { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:267:17 + │ +267 │ move |x| base_fun(a, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:267:41 + │ +267 │ move |x| base_fun(a, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:269:17 + │ +269 │ move |x| base_fun2(x, a) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:269:42 + │ +269 │ move |x| base_fun2(x, a) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:271:17 + │ +271 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:271:46 + │ +271 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:273:17 + │ +273 │ move |x| copy_fun2(x, a_copy) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:273:47 + │ +273 │ move |x| copy_fun2(x, a_copy) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:275:17 + │ +275 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:275:48 + │ +275 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:277:17 + │ +277 │ move |x| store_fun2(x, a_store) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:277:49 + │ +277 │ move |x| store_fun2(x, a_store) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:279:17 + │ +279 │ move |x| both_fun(a_both, x) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:279:46 + │ +279 │ move |x| both_fun(a_both, x) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:281:17 + │ +281 │ move |x| both_fun2(x, a_both) with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:281:47 + │ +281 │ move |x| both_fun2(x, a_both) with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:283:17 + │ +283 │ move |x| x * 2 with store+copy + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/closure_args.move:283:32 + │ +283 │ move |x| x * 2 with store+copy + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.lambda.exp new file mode 100644 index 0000000000000..4eb52de9bb606 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.lambda.exp @@ -0,0 +1,5456 @@ +// -- Model dump before env processor pipeline: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor unused checks: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor type parameter check: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor check recursive struct definition: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor check cyclic type instantiation: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor unused struct params check: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor access and use check before inlining: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor inlining: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor access and use check after inlining: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor acquires check: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with copy, drop + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + { + let x: u64 = 3; + move|x: u64| mod1::base_fun(a, x) with drop, store + } + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + +// -- Model dump after env processor simplifier: +module 0x42::mod1 { + struct S { + x: u64, + } + struct Sboth { + x: u64, + } + struct Scopy { + x: u64, + } + struct Sstore { + x: u64, + } + public fun base_fun(a: S,b: u64): u64 { + Mul(select mod1::S.x(a), b) + } + public fun base_fun2(a: u64,b: S): u64 { + Mul(a, select mod1::S.x(b)) + } + public fun both_fun(a: Sboth,b: u64): u64 { + Mul(select mod1::Sboth.x(a), b) + } + public fun both_fun2(a: u64,b: Sboth): u64 { + Mul(a, select mod1::Sboth.x(b)) + } + public fun copy_fun(a: Scopy,b: u64): u64 { + Mul(select mod1::Scopy.x(a), b) + } + public fun copy_fun2(a: u64,b: Scopy): u64 { + Mul(a, select mod1::Scopy.x(b)) + } + public fun return_function_base(key: u64,x: u64): |u64|u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_both(key: u64,x: u64): |u64|u64 with copy+drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_copy(key: u64,x: u64): |u64|u64 with copy+drop { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) with copy, drop + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun return_function_store(key: u64,x: u64): |u64|u64 with drop+store { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + f + } + } + } + } + } + } + public fun store_fun(a: Sstore,b: u64): u64 { + Mul(select mod1::Sstore.x(a), b) + } + public fun store_fun2(a: u64,b: Sstore): u64 { + Mul(a, select mod1::Sstore.x(b)) + } + public fun use_function_base(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) + } else { + move|x: u64| Mul(x, 2) + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_both(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) with copy, drop, store + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop, store + } else { + move|x: u64| Mul(x, 2) with copy, drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_copy(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) with copy, drop + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with copy, drop + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with copy, drop + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with copy, drop + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with copy, drop + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with copy, drop + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with copy, drop + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with copy, drop + } else { + move|x: u64| Mul(x, 2) with copy, drop + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } + public fun use_function_store(key: u64,x: u64): u64 { + { + let a: S = pack mod1::S(2); + { + let a_copy: Scopy = pack mod1::Scopy(2); + { + let a_store: Sstore = pack mod1::Sstore(2); + { + let a_both: Sboth = pack mod1::Sboth(2); + { + let f: |u64|u64 with copy+drop+store = if Eq(key, 0) { + move|x: u64| mod1::base_fun(a, x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| mod1::base_fun2(x, a) with drop, store + } else { + if Eq(key, 2) { + move|x: u64| mod1::copy_fun(a_copy, x) with drop, store + } else { + if Eq(key, 3) { + move|x: u64| mod1::copy_fun2(x, a_copy) with drop, store + } else { + if Eq(key, 4) { + move|x: u64| mod1::store_fun(a_store, x) with drop, store + } else { + if Eq(key, 5) { + move|x: u64| mod1::store_fun2(x, a_store) with drop, store + } else { + if Eq(key, 6) { + move|x: u64| mod1::both_fun(a_both, x) with drop, store + } else { + if Eq(key, 7) { + move|x: u64| mod1::both_fun2(x, a_both) with drop, store + } else { + move|x: u64| Mul(x, 2) with drop, store + } + } + } + } + } + } + } + }; + (f)(x) + } + } + } + } + } + } +} // end 0x42::mod1 + + + +Diagnostics: +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:58:21 + │ +58 │ let x = 3; + │ ^ + +warning: Unused parameter `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:80:47 + │ +80 │ public fun return_function_base(key: u64, x: u64): |u64|u64 { + │ ^ + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:87:21 + │ +87 │ let x = 3; + │ ^ + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:118:21 + │ +118 │ let x = 3; + │ ^ + +error: Lambda captures free variables with types that do not have some declared abilities: copy + ┌─ tests/lambda/storable/closure_args.move:119:17 + │ +119 │ move |x| base_fun(a, x) with copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + +error: Lambda captures free variables with types that do not have some declared abilities: copy + ┌─ tests/lambda/storable/closure_args.move:127:17 + │ +127 │ move |x| store_fun(a_store, x) with copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + +warning: Unused parameter `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:140:47 + │ +140 │ public fun return_function_copy(key: u64, x: u64): |u64|u64 with copy { + │ ^ + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:147:21 + │ +147 │ let x = 3; + │ ^ + +error: Lambda captures free variables with types that do not have some declared abilities: copy + ┌─ tests/lambda/storable/closure_args.move:148:17 + │ +148 │ move |x| base_fun(a, x) with copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + +error: Lambda captures free variables with types that do not have some declared abilities: copy + ┌─ tests/lambda/storable/closure_args.move:156:17 + │ +156 │ move |x| store_fun(a_store, x) with copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:177:21 + │ +177 │ let x = 3; + │ ^ + +error: Lambda captures free variables with types that do not have some declared abilities: store + ┌─ tests/lambda/storable/closure_args.move:178:17 + │ +178 │ move |x| base_fun(a, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:178:17 + │ +178 │ move |x| base_fun(a, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:180:17 + │ +180 │ move |x| base_fun2(x, a) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Lambda captures free variables with types that do not have some declared abilities: store + ┌─ tests/lambda/storable/closure_args.move:182:17 + │ +182 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:182:17 + │ +182 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:184:17 + │ +184 │ move |x| copy_fun2(x, a_copy) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:188:17 + │ +188 │ move |x| store_fun2(x, a_store) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:192:17 + │ +192 │ move |x| both_fun2(x, a_both) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:194:17 + │ +194 │ move |x| x * 2 with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused parameter `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:199:48 + │ +199 │ public fun return_function_store(key: u64, x: u64): |u64|u64 with store { + │ ^ + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:206:21 + │ +206 │ let x = 3; + │ ^ + +error: Lambda captures free variables with types that do not have some declared abilities: store + ┌─ tests/lambda/storable/closure_args.move:207:17 + │ +207 │ move |x| base_fun(a, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:207:17 + │ +207 │ move |x| base_fun(a, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:209:17 + │ +209 │ move |x| base_fun2(x, a) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Lambda captures free variables with types that do not have some declared abilities: store + ┌─ tests/lambda/storable/closure_args.move:211:17 + │ +211 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:211:17 + │ +211 │ move |x| copy_fun(a_copy, x) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:213:17 + │ +213 │ move |x| copy_fun2(x, a_copy) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:217:17 + │ +217 │ move |x| store_fun2(x, a_store) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:221:17 + │ +221 │ move |x| both_fun2(x, a_both) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:223:17 + │ +223 │ move |x| x * 2 with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:237:21 + │ +237 │ let x = 3; + │ ^ + +error: Lambda captures free variables with types that do not have some declared abilities: copy + store + ┌─ tests/lambda/storable/closure_args.move:238:17 + │ +238 │ move |x| base_fun(a, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:238:17 + │ +238 │ move |x| base_fun(a, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:240:17 + │ +240 │ move |x| base_fun2(x, a) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Lambda captures free variables with types that do not have some declared abilities: store + ┌─ tests/lambda/storable/closure_args.move:242:17 + │ +242 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:242:17 + │ +242 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:244:17 + │ +244 │ move |x| copy_fun2(x, a_copy) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Lambda captures free variables with types that do not have some declared abilities: copy + ┌─ tests/lambda/storable/closure_args.move:246:17 + │ +246 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:246:17 + │ +246 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:248:17 + │ +248 │ move |x| store_fun2(x, a_store) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:252:17 + │ +252 │ move |x| both_fun2(x, a_both) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:254:17 + │ +254 │ move |x| x * 2 with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused parameter `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:259:47 + │ +259 │ public fun return_function_both(key: u64, x: u64): |u64|u64 with store+copy { + │ ^ + +warning: Unused local variable `x`. Consider removing or prefixing with an underscore: `_x` + ┌─ tests/lambda/storable/closure_args.move:266:21 + │ +266 │ let x = 3; + │ ^ + +error: Lambda captures free variables with types that do not have some declared abilities: copy + store + ┌─ tests/lambda/storable/closure_args.move:267:17 + │ +267 │ move |x| base_fun(a, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:267:17 + │ +267 │ move |x| base_fun(a, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:269:17 + │ +269 │ move |x| base_fun2(x, a) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Lambda captures free variables with types that do not have some declared abilities: store + ┌─ tests/lambda/storable/closure_args.move:271:17 + │ +271 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: store + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:271:17 + │ +271 │ move |x| copy_fun(a_copy, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:273:17 + │ +273 │ move |x| copy_fun2(x, a_copy) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Lambda captures free variables with types that do not have some declared abilities: copy + ┌─ tests/lambda/storable/closure_args.move:275:17 + │ +275 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Captured free value is missing abilities: copy + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:275:17 + │ +275 │ move |x| store_fun(a_store, x) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:277:17 + │ +277 │ move |x| store_fun2(x, a_store) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:281:17 + │ +281 │ move |x| both_fun2(x, a_both) with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/closure_args.move:283:17 + │ +283 │ move |x| x * 2 with store+copy + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.move b/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.move new file mode 100644 index 0000000000000..375f07e6700cb --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/closure_args.move @@ -0,0 +1,287 @@ +module 0x42::mod1 { + struct S has drop { + x: u64 + } + + struct Scopy has copy, drop { + x: u64 + } + + struct Sstore has store, drop { + x: u64 + } + + struct Sboth has store, copy, drop { + x: u64 + } + + public fun base_fun(a: S, b: u64) : u64 { + a.x * b + } + + public fun base_fun2(a: u64, b: S) : u64 { + a * b.x + } + + public fun copy_fun(a: Scopy, b: u64) : u64 { + a.x * b + } + + public fun copy_fun2(a: u64, b: Scopy) : u64 { + a * b.x + } + + public fun store_fun(a: Sstore, b: u64) : u64 { + a.x * b + } + + public fun store_fun2(a: u64, b: Sstore) : u64 { + a * b.x + } + + public fun both_fun(a: Sboth, b: u64) : u64 { + a.x * b + } + + public fun both_fun2(a: u64, b: Sboth) : u64 { + a * b.x + } + + // just drop + public fun use_function_base(key: u64, x: u64): u64 { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) + } else if (key == 1) { + move |x| base_fun2(x, a) + } else if (key == 2) { + move |x| copy_fun(a_copy, x) + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) + } else if (key == 4) { + move |x| store_fun(a_store, x) + } else if (key == 5) { + move |x| store_fun2(x, a_store) + } else if (key == 6) { + move |x| both_fun(a_both, x) + } else if (key == 7) { + move |x| both_fun2(x, a_both) + } else { + move |x| x * 2 + }; + f(x) + } + + public fun return_function_base(key: u64, x: u64): |u64|u64 { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) + } else if (key == 1) { + move |x| base_fun2(x, a) + } else if (key == 2) { + move |x| copy_fun(a_copy, x) + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) + } else if (key == 4) { + move |x| store_fun(a_store, x) + } else if (key == 5) { + move |x| store_fun2(x, a_store) + } else if (key == 6) { + move |x| both_fun(a_both, x) + } else if (key == 7) { + move |x| both_fun2(x, a_both) + } else { + move |x| x * 2 with copy + }; + f + } + + + // copy + public fun use_function_copy(key: u64, x: u64): u64 { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) with copy + } else if (key == 1) { + move |x| base_fun2(x, a) with copy + } else if (key == 2) { + move |x| copy_fun(a_copy, x) with copy + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) with copy + } else if (key == 4) { + move |x| store_fun(a_store, x) with copy + } else if (key == 5) { + move |x| store_fun2(x, a_store) with copy + } else if (key == 6) { + move |x| both_fun(a_both, x) with copy + } else if (key == 7) { + move |x| both_fun2(x, a_both) with copy + } else { + move |x| x * 2 with copy + }; + f(x) + } + + public fun return_function_copy(key: u64, x: u64): |u64|u64 with copy { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) with copy + } else if (key == 1) { + move |x| base_fun2(x, a) with copy + } else if (key == 2) { + move |x| copy_fun(a_copy, x) with copy + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) with copy + } else if (key == 4) { + move |x| store_fun(a_store, x) with copy + } else if (key == 5) { + move |x| store_fun2(x, a_store) with copy + } else if (key == 6) { + move |x| both_fun(a_both, x) with copy + } else if (key == 7) { + move |x| both_fun2(x, a_both) with copy + } else { + move |x| x * 2 with copy + }; + f + } + + // store + public fun use_function_store(key: u64, x: u64): u64 { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) with store + } else if (key == 1) { + move |x| base_fun2(x, a) with store + } else if (key == 2) { + move |x| copy_fun(a_copy, x) with store + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) with store + } else if (key == 4) { + move |x| store_fun(a_store, x) with store + } else if (key == 5) { + move |x| store_fun2(x, a_store) with store + } else if (key == 6) { + move |x| both_fun(a_both, x) with store + } else if (key == 7) { + move |x| both_fun2(x, a_both) with store + } else { + move |x| x * 2 with store + }; + f(x) + } + + public fun return_function_store(key: u64, x: u64): |u64|u64 with store { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) with store + } else if (key == 1) { + move |x| base_fun2(x, a) with store + } else if (key == 2) { + move |x| copy_fun(a_copy, x) with store + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) with store + } else if (key == 4) { + move |x| store_fun(a_store, x) with store + } else if (key == 5) { + move |x| store_fun2(x, a_store) with store + } else if (key == 6) { + move |x| both_fun(a_both, x) with store + } else if (key == 7) { + move |x| both_fun2(x, a_both) with store + } else { + move |x| x * 2 with store + }; + f + } + + + // both = store+copy + public fun use_function_both(key: u64, x: u64): u64 { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) with store+copy + } else if (key == 1) { + move |x| base_fun2(x, a) with store+copy + } else if (key == 2) { + move |x| copy_fun(a_copy, x) with store+copy + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) with store+copy + } else if (key == 4) { + move |x| store_fun(a_store, x) with store+copy + } else if (key == 5) { + move |x| store_fun2(x, a_store) with store+copy + } else if (key == 6) { + move |x| both_fun(a_both, x) with store+copy + } else if (key == 7) { + move |x| both_fun2(x, a_both) with store+copy + } else { + move |x| x * 2 with store+copy + }; + f(x) + } + + public fun return_function_both(key: u64, x: u64): |u64|u64 with store+copy { + let a = S { x: 2 }; + let a_copy = Scopy { x: 2 }; + let a_store = Sstore { x: 2 }; + let a_both = Sboth { x: 2 }; + let f = + if (key == 0) { + let x = 3; + move |x| base_fun(a, x) with store+copy + } else if (key == 1) { + move |x| base_fun2(x, a) with store+copy + } else if (key == 2) { + move |x| copy_fun(a_copy, x) with store+copy + } else if (key == 3) { + move |x| copy_fun2(x, a_copy) with store+copy + } else if (key == 4) { + move |x| store_fun(a_store, x) with store+copy + } else if (key == 5) { + move |x| store_fun2(x, a_store) with store+copy + } else if (key == 6) { + move |x| both_fun(a_both, x) with store+copy + } else if (key == 7) { + move |x| both_fun2(x, a_both) with store+copy + } else { + move |x| x * 2 with store+copy + }; + f + } +} diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.exp index bee6d7e4e76c2..059c9197682da 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.exp @@ -15,25 +15,25 @@ error: unsupported language construct error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:49:17 │ -49 │ move |y| mod3::multiply(y, x) +49 │ move |y| mod3::multiply(x, y) │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:51:17 │ -51 │ move |x| multiply3(x, 3, 2) +51 │ move |x| multiply3(3, 2, x) │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:53:17 │ -53 │ move |x| mod3::multiply(x, 7) +53 │ move |x| mod3::multiply(7, x) │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:55:17 │ -55 │ move |x| multiply3(4, x, 2) +55 │ move |x| { multiply3(4, 2, x) } │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct @@ -45,19 +45,19 @@ error: unsupported language construct error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:61:17 │ -61 │ move |z| multiply3(x, y, z) +61 │ move |z| multiply3(x + 1, y, z) │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:64:17 │ -64 │ move |x| alt_multiply(x, z) with copy +64 │ move |x| alt_multiply(z, x) with copy │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:64:45 │ -64 │ move |x| alt_multiply(x, z) with copy +64 │ move |x| alt_multiply(z, x) with copy │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions error: unsupported language construct @@ -75,19 +75,19 @@ error: unsupported language construct error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:67:17 │ -67 │ move |x| g(x, 11) +67 │ move |x| g(11, x) │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:69:25 │ -69 │ let h = move |x| mod3::multiply(x, 12) with copy; +69 │ let h = move |x| mod3::multiply(12, x) with copy; │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:69:56 │ -69 │ let h = move |x| mod3::multiply(x, 12) with copy; +69 │ let h = move |x| mod3::multiply(12, x) with copy; │ ^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions error: unsupported language construct @@ -105,7 +105,7 @@ error: unsupported language construct error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:72:25 │ -72 │ let i = move |x| multiply3(2, x, 2); +72 │ let i = move |x| multiply3(2, 2, x); │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct @@ -123,5 +123,5 @@ error: unsupported language construct error: unsupported language construct ┌─ tests/lambda/storable/doable_func.move:76:17 │ -76 │ move |x| i(x, 15) +76 │ move |x| i(15, x) │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.lambda.exp index e39fd4deaeb18..f43754aae1268 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.lambda.exp @@ -47,17 +47,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -67,31 +67,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -100,7 +100,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -214,17 +214,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -234,31 +234,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -267,7 +267,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -381,17 +381,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -401,31 +401,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -434,7 +434,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -548,17 +548,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -568,31 +568,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -601,7 +601,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -715,17 +715,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -735,31 +735,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -768,7 +768,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -882,17 +882,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -902,31 +902,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -935,7 +935,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -1049,17 +1049,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -1069,31 +1069,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -1102,7 +1102,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -1216,17 +1216,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -1236,31 +1236,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -1269,7 +1269,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -1383,17 +1383,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -1403,31 +1403,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -1436,7 +1436,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -1550,17 +1550,17 @@ module 0x42::test { if Eq(key, 4) { { let x: u64 = 6; - move|y: u64| mod3::multiply(y, x) + move|y: u64| mod3::multiply(x, y) } } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) @@ -1570,31 +1570,31 @@ module 0x42::test { let x: u64 = 2; { let y: u64 = 5; - move|z: u64| test::multiply3(x, y, z) + move|z: u64| test::multiply3(Add(x, 1), y, z) } } } else { if Eq(key, 10) { { let z: u64 = 11; - move|x: u64| mod4::alt_multiply(x, z) with copy, drop + move|x: u64| mod4::alt_multiply(z, x) with copy, drop } } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -1603,7 +1603,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -1712,41 +1712,41 @@ module 0x42::test { move|y: u64| mod4::alt_multiply(5, y) } else { if Eq(key, 4) { - move|y: u64| mod3::multiply(y, 6) + move|y: u64| mod3::multiply(6, y) } else { if Eq(key, 5) { - move|x: u64| test::multiply3(x, 3, 2) + move|x: u64| test::multiply3(3, 2, x) } else { if Eq(key, 6) { - move|x: u64| mod3::multiply(x, 7) + move|x: u64| mod3::multiply(7, x) } else { if Eq(key, 7) { - move|x: u64| test::multiply3(4, x, 2) + move|x: u64| test::multiply3(4, 2, x) } else { if Eq(key, 8) { move|x: u64| test::multiply3(3, 3, x) } else { if Eq(key, 9) { - move|z: u64| test::multiply3(2, 5, z) + move|z: u64| test::multiply3(3, 5, z) } else { if Eq(key, 10) { - move|x: u64| mod4::alt_multiply(x, 11) with copy, drop + move|x: u64| mod4::alt_multiply(11, x) with copy, drop } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = move|(x: u64, y: u64): (u64, u64)| mod3::multiply(x, y) with copy, drop; - move|x: u64| (g)(x, 11) + move|x: u64| (g)(11, x) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(x, 12) with copy, drop; + let h: |u64|u64 with copy+store = move|x: u64| mod3::multiply(12, x) with copy, drop; move|x: u64| (h)(x) with copy, drop } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, x, 2); + let i: |u64|u64 with copy+store = move|x: u64| test::multiply3(2, 2, x); move|z: u64| (i)(z) } } else { @@ -1755,7 +1755,7 @@ module 0x42::test { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) }; - move|x: u64| (i)(x, 15) + move|x: u64| (i)(15, x) } } } @@ -1858,47 +1858,47 @@ module 0x42::test { earlybind(mod4::alt_multiply, 5) } else { if Eq(key, 4) { - test::choose_function1$lambda$1 + earlybind(mod3::multiply, 6) } else { if Eq(key, 5) { - test::choose_function1$lambda$2 + earlybind(test::multiply3, 3, 2) } else { if Eq(key, 6) { - test::choose_function1$lambda$3 + earlybind(mod3::multiply, 7) } else { if Eq(key, 7) { - test::choose_function1$lambda$4 + earlybind(test::multiply3, 4, 2) } else { if Eq(key, 8) { earlybind(test::multiply3, 3, 3) } else { if Eq(key, 9) { - earlybind(test::multiply3, 2, 5) + earlybind(test::multiply3, 3, 5) } else { if Eq(key, 10) { - test::choose_function1$lambda$5 + earlybind(mod4::alt_multiply, 11) } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = mod3::multiply; - earlybind(test::choose_function1$lambda$6, g) + earlybind(g, 11) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = test::choose_function1$lambda$7; + let h: |u64|u64 with copy+store = earlybind(mod3::multiply, 12); h } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = test::choose_function1$lambda$8; + let i: |u64|u64 with copy+store = earlybind(test::multiply3, 2, 2); i } } else { { - let i: |(u64, u64)|u64 with copy+store = test::choose_function1$lambda$9; - earlybind(test::choose_function1$lambda$10, i) + let i: |(u64, u64)|u64 with copy+store = test::choose_function1$lambda$1; + earlybind(i, 15) } } } @@ -1954,39 +1954,12 @@ module 0x42::test { } } } - private fun choose_function1$lambda$1(y: u64): u64 { - mod3::multiply(y, 6) - } - private fun choose_function1$lambda$2(x: u64): u64 { - test::multiply3(x, 3, 2) - } - private fun choose_function1$lambda$3(x: u64): u64 { - mod3::multiply(x, 7) - } - private fun choose_function1$lambda$4(x: u64): u64 { - test::multiply3(4, x, 2) - } - private fun choose_function1$lambda$5(x: u64): u64 { - mod4::alt_multiply(x, 11) - } - private fun choose_function1$lambda$6(g: |(u64, u64)|u64 with copy+store,x: u64): u64 { - (g)(x, 11) - } - private fun choose_function1$lambda$7(x: u64): u64 { - mod3::multiply(x, 12) - } - private fun choose_function1$lambda$8(x: u64): u64 { - test::multiply3(2, x, 2) - } - private fun choose_function1$lambda$9(x: u64,y: u64): u64 { + private fun choose_function1$lambda$1(x: u64,y: u64): u64 { { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) } } - private fun choose_function1$lambda$10(i: |(u64, u64)|u64 with copy+store,x: u64): u64 { - (i)(x, 15) - } } // end 0x42::test @@ -2034,47 +2007,47 @@ module 0x42::test { earlybind(mod4::alt_multiply, 5) } else { if Eq(key, 4) { - test::choose_function1$lambda$1 + earlybind(mod3::multiply, 6) } else { if Eq(key, 5) { - test::choose_function1$lambda$2 + earlybind(test::multiply3, 3, 2) } else { if Eq(key, 6) { - test::choose_function1$lambda$3 + earlybind(mod3::multiply, 7) } else { if Eq(key, 7) { - test::choose_function1$lambda$4 + earlybind(test::multiply3, 4, 2) } else { if Eq(key, 8) { earlybind(test::multiply3, 3, 3) } else { if Eq(key, 9) { - earlybind(test::multiply3, 2, 5) + earlybind(test::multiply3, 3, 5) } else { if Eq(key, 10) { - test::choose_function1$lambda$5 + earlybind(mod4::alt_multiply, 11) } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = mod3::multiply; - earlybind(test::choose_function1$lambda$6, g) + earlybind(g, 11) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = test::choose_function1$lambda$7; + let h: |u64|u64 with copy+store = earlybind(mod3::multiply, 12); h } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = test::choose_function1$lambda$8; + let i: |u64|u64 with copy+store = earlybind(test::multiply3, 2, 2); i } } else { { - let i: |(u64, u64)|u64 with copy+store = test::choose_function1$lambda$9; - earlybind(test::choose_function1$lambda$10, i) + let i: |(u64, u64)|u64 with copy+store = test::choose_function1$lambda$1; + earlybind(i, 15) } } } @@ -2130,39 +2103,12 @@ module 0x42::test { } } } - private fun choose_function1$lambda$1(y: u64): u64 { - mod3::multiply(y, 6) - } - private fun choose_function1$lambda$2(x: u64): u64 { - test::multiply3(x, 3, 2) - } - private fun choose_function1$lambda$3(x: u64): u64 { - mod3::multiply(x, 7) - } - private fun choose_function1$lambda$4(x: u64): u64 { - test::multiply3(4, x, 2) - } - private fun choose_function1$lambda$5(x: u64): u64 { - mod4::alt_multiply(x, 11) - } - private fun choose_function1$lambda$6(g: |(u64, u64)|u64 with copy+store,x: u64): u64 { - (g)(x, 11) - } - private fun choose_function1$lambda$7(x: u64): u64 { - mod3::multiply(x, 12) - } - private fun choose_function1$lambda$8(x: u64): u64 { - test::multiply3(2, x, 2) - } - private fun choose_function1$lambda$9(x: u64,y: u64): u64 { + private fun choose_function1$lambda$1(x: u64,y: u64): u64 { { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) } } - private fun choose_function1$lambda$10(i: |(u64, u64)|u64 with copy+store,x: u64): u64 { - (i)(x, 15) - } } // end 0x42::test @@ -2210,47 +2156,47 @@ module 0x42::test { earlybind(mod4::alt_multiply, 5) } else { if Eq(key, 4) { - test::choose_function1$lambda$1 + earlybind(mod3::multiply, 6) } else { if Eq(key, 5) { - test::choose_function1$lambda$2 + earlybind(test::multiply3, 3, 2) } else { if Eq(key, 6) { - test::choose_function1$lambda$3 + earlybind(mod3::multiply, 7) } else { if Eq(key, 7) { - test::choose_function1$lambda$4 + earlybind(test::multiply3, 4, 2) } else { if Eq(key, 8) { earlybind(test::multiply3, 3, 3) } else { if Eq(key, 9) { - earlybind(test::multiply3, 2, 5) + earlybind(test::multiply3, 3, 5) } else { if Eq(key, 10) { - test::choose_function1$lambda$5 + earlybind(mod4::alt_multiply, 11) } else { if Eq(key, 11) { { let g: |(u64, u64)|u64 with copy+store = mod3::multiply; - earlybind(test::choose_function1$lambda$6, g) + earlybind(g, 11) } } else { if Eq(key, 12) { { - let h: |u64|u64 with copy+store = test::choose_function1$lambda$7; + let h: |u64|u64 with copy+store = earlybind(mod3::multiply, 12); h } } else { if Eq(key, 14) { { - let i: |u64|u64 with copy+store = test::choose_function1$lambda$8; + let i: |u64|u64 with copy+store = earlybind(test::multiply3, 2, 2); i } } else { { - let i: |(u64, u64)|u64 with copy+store = test::choose_function1$lambda$9; - earlybind(test::choose_function1$lambda$10, i) + let i: |(u64, u64)|u64 with copy+store = test::choose_function1$lambda$1; + earlybind(i, 15) } } } @@ -2306,159 +2252,120 @@ module 0x42::test { } } } - private fun choose_function1$lambda$1(y: u64): u64 { - mod3::multiply(y, 6) - } - private fun choose_function1$lambda$2(x: u64): u64 { - test::multiply3(x, 3, 2) - } - private fun choose_function1$lambda$3(x: u64): u64 { - mod3::multiply(x, 7) - } - private fun choose_function1$lambda$4(x: u64): u64 { - test::multiply3(4, x, 2) - } - private fun choose_function1$lambda$5(x: u64): u64 { - mod4::alt_multiply(x, 11) - } - private fun choose_function1$lambda$6(g: |(u64, u64)|u64 with copy+store,x: u64): u64 { - (g)(x, 11) - } - private fun choose_function1$lambda$7(x: u64): u64 { - mod3::multiply(x, 12) - } - private fun choose_function1$lambda$8(x: u64): u64 { - test::multiply3(2, x, 2) - } - private fun choose_function1$lambda$9(x: u64,y: u64): u64 { + private fun choose_function1$lambda$1(x: u64,y: u64): u64 { { let q: u64 = Sub(y, 1); mod3::multiply(x, Add(q, 1)) } } - private fun choose_function1$lambda$10(i: |(u64, u64)|u64 with copy+store,x: u64): u64 { - (i)(x, 15) - } } // end 0x42::test Diagnostics: -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:39:17 │ 39 │ mod2::double │ ^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:41:17 │ 41 │ mod1::triple │ ^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:43:17 │ 43 │ move |x| mod3::multiply(4, x) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:46:17 │ 46 │ move |y| alt_multiply(x, y) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:49:17 │ -49 │ move |y| mod3::multiply(y, x) +49 │ move |y| mod3::multiply(x, y) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:51:17 │ -51 │ move |x| multiply3(x, 3, 2) +51 │ move |x| multiply3(3, 2, x) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:53:17 │ -53 │ move |x| mod3::multiply(x, 7) +53 │ move |x| mod3::multiply(7, x) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:55:17 │ -55 │ move |x| multiply3(4, x, 2) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +55 │ move |x| { multiply3(4, 2, x) } + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:57:17 │ 57 │ move |x| multiply3(3, 3, x) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:61:17 │ -61 │ move |z| multiply3(x, y, z) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +61 │ move |z| multiply3(x + 1, y, z) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:64:17 │ -64 │ move |x| alt_multiply(x, z) with copy +64 │ move |x| alt_multiply(z, x) with copy │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:66:37 │ 66 │ let g = move |x, y| mod3::multiply(x, y) with copy+drop; │ ^^^^^^^^^^^^^^^^^^^^ -error: Calls to function values other than inline function parameters not yet supported - ┌─ tests/lambda/storable/doable_func.move:67:26 - │ -67 │ move |x| g(x, 11) - │ ^^^^^^^^ - -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:67:17 │ -67 │ move |x| g(x, 11) +67 │ move |x| g(11, x) │ ^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:69:25 │ -69 │ let h = move |x| mod3::multiply(x, 12) with copy; +69 │ let h = move |x| mod3::multiply(12, x) with copy; │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:72:25 │ -72 │ let i = move |x| multiply3(2, x, 2); +72 │ let i = move |x| multiply3(2, 2, x); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:75:25 │ 75 │ let i = move |x, y| { let q = y - 1; 0x42::mod3::multiply(x, q + 1) }; │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Calls to function values other than inline function parameters not yet supported - ┌─ tests/lambda/storable/doable_func.move:76:26 - │ -76 │ move |x| i(x, 15) - │ ^^^^^^^^ - -error: Function-typed values not yet supported except as parameters to calls to inline functions +error: Function-typed values not yet implemented except as parameters to calls to inline functions ┌─ tests/lambda/storable/doable_func.move:76:17 │ -76 │ move |x| i(x, 15) +76 │ move |x| i(15, x) │ ^^^^^^^^^^^^^^^^^ -error: Calls to function values other than inline function parameters not yet supported +error: Calls to function values other than inline function parameters not yet implemented ┌─ tests/lambda/storable/doable_func.move:78:9 │ 78 │ f(x) diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.move b/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.move index e53e9c9d3dc45..11035738ea530 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.move +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/doable_func.move @@ -46,34 +46,34 @@ module 0x42::test { move |y| alt_multiply(x, y) } else if (key == 4) { let x = 6; - move |y| mod3::multiply(y, x) + move |y| mod3::multiply(x, y) } else if (key == 5) { - move |x| multiply3(x, 3, 2) + move |x| multiply3(3, 2, x) } else if (key == 6) { - move |x| mod3::multiply(x, 7) + move |x| mod3::multiply(7, x) } else if (key == 7) { - move |x| multiply3(4, x, 2) + move |x| { multiply3(4, 2, x) } } else if (key == 8) { move |x| multiply3(3, 3, x) } else if (key == 9) { let x = 2; let y = 5; - move |z| multiply3(x, y, z) + move |z| multiply3(x + 1, y, z) } else if (key == 10) { let z = 11; - move |x| alt_multiply(x, z) with copy + move |x| alt_multiply(z, x) with copy } else if (key == 11) { let g = move |x, y| mod3::multiply(x, y) with copy+drop; - move |x| g(x, 11) + move |x| g(11, x) } else if (key == 12) { - let h = move |x| mod3::multiply(x, 12) with copy; + let h = move |x| mod3::multiply(12, x) with copy; move |x| { h(x) } with copy + drop } else if (key == 14) { - let i = move |x| multiply3(2, x, 2); + let i = move |x| multiply3(2, 2, x); move |z| i(z) } else { let i = move |x, y| { let q = y - 1; 0x42::mod3::multiply(x, q + 1) }; - move |x| i(x, 15) + move |x| i(15, x) }; f(x) } diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_errors.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_errors.lambda.exp index 0cc07aff247e8..a3e43481806b2 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_errors.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_errors.lambda.exp @@ -1,23 +1,10 @@ Diagnostics: -error: function type `|u64|u64 with store` is not allowed as a field type - ┌─ tests/lambda/storable/registry_errors.move:9:12 - │ -9 │ f: |u64| u64 with store, - │ ^^^^^^^^^^^^^^^^^^^^ - │ - = required by declaration of field `f` - -error: function type `|u64|u64 with store` is not allowed as a type argument (type was inferred) - ┌─ tests/lambda/storable/registry_errors.move:22:21 - │ -13 │ enum Option { - │ - declaration of type parameter `T` - · -22 │ x = Option::Some(f.f) - │ ^^^^^^^^^^^^ +error: cannot return `Option<|u64|u64 with store>` from a function with result type `Option` + ┌─ tests/lambda/storable/registry_errors.move:25:9 │ - = required by instantiating type parameter `T` of struct `Option` +25 │ x + │ ^ error: expected `&mut Function` but found a value of type `|u64|u64 with store` ┌─ tests/lambda/storable/registry_errors.move:32:17 diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.exp index 9292304f56251..1d6d6c5bdef9b 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.exp @@ -1,43 +1,37 @@ Diagnostics: error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:10:22 - │ -10 │ f: |u64| u64 with store+copy, - │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + ┌─ tests/lambda/storable/registry_ok.move:6:36 + │ +6 │ struct FunctionValue(|u64| u64 with store+copy) has store, copy, drop; + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:29:84 + ┌─ tests/lambda/storable/registry_ok.move:32:84 │ -29 │ fun replace_or_add_function(v: &mut vector, k: u64, new_f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { +32 │ fun replace_or_add_function(v: &mut vector, k: u64, new_f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:29:119 + ┌─ tests/lambda/storable/registry_ok.move:32:119 │ -29 │ fun replace_or_add_function(v: &mut vector, k: u64, new_f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { +32 │ fun replace_or_add_function(v: &mut vector, k: u64, new_f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:53:47 + ┌─ tests/lambda/storable/registry_ok.move:56:47 │ -53 │ fun register(owner: &signer, f: |u64| u64 with store+copy, k: u64) acquires Registry { +56 │ fun register(owner: &signer, f: |u64| u64 with store+copy, k: u64) acquires Registry { │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:106:41 - │ -106 │ fun multiply_by_x(x: u64): |u64|u64 with store { - │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types - -error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:110:42 + ┌─ tests/lambda/storable/registry_ok.move:110:23 │ -110 │ fun multiply_by_x2(x: u64): |u64|u64 with store { - │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types +110 │ FunctionValue(move |y| multiply(x, y)) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression error: unsupported language construct - ┌─ tests/lambda/storable/registry_ok.move:111:9 + ┌─ tests/lambda/storable/registry_ok.move:114:23 │ -111 │ move |y| multiply(x, y) - │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression +114 │ FunctionValue(move |y| multiply(x, y)) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.lambda.exp index cfe0567301c9b..38be6559eeacd 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.lambda.exp @@ -1,42 +1,10 @@ Diagnostics: -error: function type `|u64|u64 with copy+store` is not allowed as a field type - ┌─ tests/lambda/storable/registry_ok.move:10:12 - │ -10 │ f: |u64| u64 with store+copy, - │ ^^^^^^^^^^^^^^^^^^^^^^^^^ - │ - = required by declaration of field `f` - -error: function type `|u64|u64 with copy+store` is not allowed as a type argument (type was inferred) - ┌─ tests/lambda/storable/registry_ok.move:23:21 - │ -14 │ enum Option { - │ - declaration of type parameter `T` - · -23 │ x = Option::Some(f.f) - │ ^^^^^^^^^^^^ - │ - = required by instantiating type parameter `T` of struct `Option` - -error: function type `|u64|u64 with copy+store` is not allowed as a type argument - ┌─ tests/lambda/storable/registry_ok.move:29:109 - │ -14 │ enum Option { - │ - declaration of type parameter `T` - · -29 │ fun replace_or_add_function(v: &mut vector, k: u64, new_f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { - │ ^^^^^^^^^^^^^^^^^^^^^^^^^ - │ - = required by instantiating type parameter `T` of struct `Option` - -error: function type `|u64|u64 with copy+store` is not allowed as a type argument (type was inferred) - ┌─ tests/lambda/storable/registry_ok.move:33:26 - │ -14 │ enum Option { - │ - declaration of type parameter `T` - · -33 │ result = Option::Some(f.f); - │ ^^^^^^^^^^^^ - │ - = required by instantiating type parameter `T` of struct `Option` +error: duplicate declaration, item, or annotation + ┌─ tests/lambda/storable/registry_ok.move:4:14 + │ +2 │ use std::signer; + │ ------ Alias previously defined here +3 │ use std::vector; +4 │ use std::signer; + │ ^^^^^^ Duplicate module alias 'signer'. Module aliases must be unique within a given namespace diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.move b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.move index 047415e26d4ef..bd0ec2f12cec9 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.move +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok.move @@ -1,24 +1,27 @@ module 0x42::test { + use std::signer; use std::vector; use std::signer; + struct FunctionValue(|u64| u64 with store+copy) has store, copy, drop; + struct Registry has key { - functions: vector + functions: vector } - struct Function has store { - f: |u64| u64 with store+copy, + struct FunctionEntry has store, copy { + f: FunctionValue, key: u64 } - enum Option { + enum Option has store, copy { None(), Some(T) } - fun get_function(v: &vector, k: u64): Option { + fun get_function(v: &vector, k: u64): Option { let x = Option::None; - vector::for_each_ref(v, |f: &Function| { + vector::for_each_ref(v, |f: &FunctionEntry| { if (f.key == k) { x = Option::Some(f.f) } @@ -70,7 +73,7 @@ module 0x42::test { match (get_function(®istry.functions, k)) { Some(func) => { let Function { f: f, key: key } = func; - Option::Some(f(x)) + Option::Some((f.0)(x)) }, _ => { Option::None @@ -103,12 +106,12 @@ module 0x42::test { x * y } - fun multiply_by_x(x: u64): |u64|u64 with store { - |y| multiply(x, y) + fun multiply_by_x(x: u64): FunctionValue { + FunctionValue(move |y| multiply(x, y)) } - fun multiply_by_x2(x: u64): |u64|u64 with store { - move |y| multiply(x, y) + fun multiply_by_x2(x: u64): FunctionValue { + FunctionValue(move |y| multiply(x, y)) } #[test(a = @0x42)] diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.exp new file mode 100644 index 0000000000000..6c7af59b023f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.exp @@ -0,0 +1,61 @@ + +Diagnostics: +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:5:36 + │ +5 │ struct FunctionValue(|u64| u64 with store+copy) has store, copy, drop; + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:12:22 + │ +12 │ f: |u64| u64 with store+copy, + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:21:75 + │ +21 │ fun get_function(v: &vector, k: u64): Option<|u64| u64 with store+copy> { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:31:85 + │ +31 │ fun replace_or_add_function(v: &mut vector, k: u64, f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:31:120 + │ +31 │ fun replace_or_add_function(v: &mut vector, k: u64, f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:52:47 + │ +52 │ fun register(owner: &signer, f: |u64| u64 with store+copy, k: u64) acquires Registry { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:91:42 + │ +91 │ fun multiply_by_x(x: u64): |u64| u64 with store+copy { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:92:9 + │ +92 │ move |y| multiply(x, y) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:95:43 + │ +95 │ fun multiply_by_x2(x: u64): |u64| u64 with store+copy { + │ ^^^^^^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/registry_ok2.move:96:9 + │ +96 │ move |y| multiply(x, y) + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.lambda.exp new file mode 100644 index 0000000000000..00cdf2ef8e2d2 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.lambda.exp @@ -0,0 +1,1909 @@ +// -- Model dump before env processor pipeline: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor unused checks: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor type parameter check: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor check recursive struct definition: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor check cyclic type instantiation: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor unused struct params check: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor access and use check before inlining: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_ref(v, |f: &FunctionEntry| if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + }); + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + vector::for_each_mut(v, |record: &mut FunctionEntry| if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + }); + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor inlining: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor access and use check after inlining: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor acquires check: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor simplifier: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + move|y: u64| test::multiply(x, y) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor lambda-lifting: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + earlybind(test::multiply, x) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + earlybind(test::multiply, x) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor specification checker: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + earlybind(test::multiply, x) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + earlybind(test::multiply, x) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor specification rewriter: +module 0x42::test { + use std::signer; + use std::vector; + struct FunctionEntry { + f: |u64|u64 with copy+store, + key: u64, + } + struct FunctionValue { + 0: |u64|u64 with copy+store, + } + enum Option { + None, + Some { + 0: T, + } + } + struct Registry { + functions: vector, + } + private fun double(x: u64): u64 { + Mul(x, 2) + } + private fun get_function(v: &vector,k: u64): Option<|u64|u64 with copy+store> { + { + let x: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &vector): (&vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(v)) { + { + let (f: &FunctionEntry): (&FunctionEntry) = Tuple(vector::borrow(v, i)); + if Eq(select test::FunctionEntry.key<&FunctionEntry>(f), k) { + x: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(select test::FunctionEntry.f<&FunctionEntry>(f)) + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + x + } + } + private fun invoke(addr: address,k: u64,x: u64): Option + acquires Registry(*) + { + if Not(exists(addr)) { + return pack test::Option::None() + } else { + Tuple() + }; + { + let registry: &Registry = BorrowGlobal(Immutable)(addr); + match (test::get_function(Borrow(Immutable)(select test::Registry.functions<&Registry>(registry)), k)) { + test::Option::Some<|u64|u64 with copy+store>{ 0: f } => { + pack test::Option::Some((f)(x)) + } + _: Option<|u64|u64 with copy+store> => { + pack test::Option::None() + } + } + + } + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + private fun multiply_by_x(x: u64): |u64|u64 with copy+store { + earlybind(test::multiply, x) + } + private fun multiply_by_x2(x: u64): |u64|u64 with copy+store { + earlybind(test::multiply, x) + } + private fun register(owner: &signer,f: |u64|u64 with copy+store,k: u64) + acquires Registry(*) + { + { + let addr: address = signer::address_of(owner); + if Not(exists(addr)) { + { + let new_registry: Registry = pack test::Registry(Vector()); + MoveTo(owner, new_registry); + Tuple() + } + } else { + Tuple() + }; + { + let registry: &mut Registry = BorrowGlobal(Mutable)(addr); + test::replace_or_add_function(Borrow(Mutable)(select test::Registry.functions<&mut Registry>(registry)), k, f); + Tuple() + } + } + } + private fun replace_or_add_function(v: &mut vector,k: u64,f: |u64|u64 with copy+store): Option<|u64|u64 with copy+store> { + { + let result: Option<|u64|u64 with copy+store> = pack test::Option::None<|u64|u64 with copy+store>(); + { + let (v: &mut vector): (&mut vector) = Tuple(v); + { + let i: u64 = 0; + loop { + if Lt(i, vector::length(Freeze(false)(v))) { + { + let (record: &mut FunctionEntry): (&mut FunctionEntry) = Tuple(vector::borrow_mut(v, i)); + if Eq(select test::FunctionEntry.key<&mut FunctionEntry>(record), k) { + { + let old_f: |u64|u64 with copy+store = select test::FunctionEntry.f<&mut FunctionEntry>(record); + select test::FunctionEntry.f<&mut FunctionEntry>(record) = f; + result: Option<|u64|u64 with copy+store> = pack test::Option::Some<|u64|u64 with copy+store>(old_f); + Tuple() + } + } else { + Tuple() + } + }; + i: u64 = Add(i, 1) + } else { + break + } + } + } + }; + match (result) { + test::Option::None<|u64|u64 with copy+store> => { + { + let new_record: FunctionEntry = pack test::FunctionEntry(f, k); + vector::push_back(v, new_record); + pack test::Option::None<|u64|u64 with copy+store>() + } + } + test::Option::Some<|u64|u64 with copy+store>{ 0: _ } => { + result + } + } + + } + } + private fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + + +Diagnostics: +error: Calls to function values other than inline function parameters not yet implemented + ┌─ tests/lambda/storable/registry_ok2.move:71:30 + │ +71 │ Option::Some(f(x)) + │ ^^^^ + +error: Function-typed values not yet implemented except as parameters to calls to inline functions + ┌─ tests/lambda/storable/registry_ok2.move:92:9 + │ +92 │ move |y| multiply(x, y) + │ ^^^^^^^^^^^^^^^^^^^^^^^ + +error: Function-typed values not yet implemented except as parameters to calls to inline functions + ┌─ tests/lambda/storable/registry_ok2.move:96:9 + │ +96 │ move |y| multiply(x, y) + │ ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.move b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.move new file mode 100644 index 0000000000000..fbfd16c17475d --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/registry_ok2.move @@ -0,0 +1,128 @@ +module 0x42::test { + use std::signer; + use std::vector; + + struct FunctionValue(|u64| u64 with store+copy) has store, copy, drop; + + struct Registry has key { + functions: vector + } + + struct FunctionEntry has store, copy, drop { + f: |u64| u64 with store+copy, + key: u64 + } + + enum Option has store, copy { + None(), + Some(T) + } + + fun get_function(v: &vector, k: u64): Option<|u64| u64 with store+copy> { + let x = Option::None; + vector::for_each_ref(v, |f: &FunctionEntry| { + if (f.key == k) { + x = Option::Some(f.f) + } + }); + x + } + + fun replace_or_add_function(v: &mut vector, k: u64, f: |u64| u64 with store+copy): Option<|u64| u64 with store+copy> { + let result = Option::None; + vector::for_each_mut(v, |record: &mut FunctionEntry| { + if (record.key == k) { + let old_f = record.f; + record.f = f; + result = Option::Some(old_f); + } + }); + match (result) { + Option::None => { + let new_record = FunctionEntry { f: f, key: k }; + vector::push_back(v, new_record); + Option::None + }, + Option::Some(_) => { + result + } + } + } + + fun register(owner: &signer, f: |u64| u64 with store+copy, k: u64) acquires Registry { + let addr = signer::address_of(owner); + if (!exists(addr)) { + let new_registry = Registry { + functions: vector[] + }; + move_to(owner, new_registry); + }; + let registry = borrow_global_mut(addr); + replace_or_add_function(&mut registry.functions, k, f); + } + + fun invoke(addr: address, k: u64, x: u64): Option acquires Registry { + if (!exists(addr)) { + return Option::None + }; + let registry = borrow_global(addr); + match (get_function(®istry.functions, k)) { + Option::Some(f) => { + Option::Some(f(x)) + }, + _ => { + Option::None + } + } + } + + fun double(x: u64):u64 { + x * 2 + } + + fun triple(x: u64):u64 { + x * 3 + } + + public fun multiply(x: u64, y: u64): u64 { + x * y + } + + fun multiply_by_x(x: u64): |u64| u64 with store+copy { + move |y| multiply(x, y) + } + + fun multiply_by_x2(x: u64): |u64| u64 with store+copy { + move |y| multiply(x, y) + } + + #[test(a = @0x42)] + fun test_registry1(a: signer) { + register(a, double, 2); + register(a, negate, 3); + register(a, multiply_by_x(4), 4); + register(a, multiply_by_x(5), 5); + register(a, multiply_by_x2(6), 6); + + match (invoke(a, 2, 10)) { + Some(x) => { assert!(x == 20); } + _ => assert!(false) + }; + match (invoke(a, 3, 11)) { + Some(x) => { assert!(x == 33); } + _ => assert!(false) + }; + match (invoke(a, 4, 2)) { + Some(x) => { assert!(x == 8); } + _ => assert!(false) + }; + match (invoke(a, 5, 3)) { + Some(x) => { assert!(x == 15); } + _ => assert!(false) + }; + match (invoke(a, 6, 3)) { + Some(x) => { assert!(x == 18); } + _ => assert!(false) + }; + } +} diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/return_func.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func.lambda.exp index 7dd9a43a5339c..b40e18997943d 100644 --- a/third_party/move/move-compiler-v2/tests/lambda/storable/return_func.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func.lambda.exp @@ -29,19 +29,3 @@ error: expected `|integer|_ with copy+store` but found a value of type `u64` │ 87 │ vector::push_back(&mut sum, h(6)); │ ^^^^ - -error: function type `|integer|_` is not allowed as a type argument (type was inferred) - ┌─ tests/lambda/storable/return_func.move:89:21 - │ -89 │ let funcs = vector[choose_function(0), choose_function(1), choose_function(2)]; - │ ^^^^^^ - │ - = required by instantiating vector type parameter - -error: function type `|u64|u64 with store` is not allowed as a type argument (type was inferred) - ┌─ tests/lambda/storable/return_func.move:89:21 - │ -89 │ let funcs = vector[choose_function(0), choose_function(1), choose_function(2)]; - │ ^^^^^^ - │ - = required by instantiating vector type parameter diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.exp new file mode 100644 index 0000000000000..dad5d051d6533 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.exp @@ -0,0 +1,187 @@ + +Diagnostics: +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:20:41 + │ +20 │ fun multiply_by_x(x: u64): |u64|u64 with store { + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:21:9 + │ +21 │ move |y| multiply(x, y) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:21:33 + │ +21 │ move |y| multiply(x, y) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:24:46 + │ +24 │ fun choose_function(key: u64) : |u64|u64 with store { + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:34:46 + │ +34 │ fun choose_function2(key: u64): |u64|u64 with store { + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:36:13 + │ +36 │ move |x| double(x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:36:32 + │ +36 │ move |x| double(x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:38:13 + │ +38 │ move |x| triple(x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:38:32 + │ +38 │ move |x| triple(x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:41:13 + │ +41 │ move |x| f(x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:41:27 + │ +41 │ move |x| f(x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:44:13 + │ +44 │ move |x| f(x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:44:27 + │ +44 │ move |x| f(x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:46:21 + │ +46 │ let f = move |y| multiply(6, y) with store; + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:46:45 + │ +46 │ let f = move |y| multiply(6, y) with store; + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:49:13 + │ +49 │ move |y| multiply(y, 7) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:49:37 + │ +49 │ move |y| multiply(y, 7) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:51:21 + │ +51 │ let f = move |y| multiply(6, y) with store; + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:51:45 + │ +51 │ let f = move |y| multiply(6, y) with store; + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:52:13 + │ +52 │ move |x| f(x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:52:27 + │ +52 │ move |x| f(x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:55:13 + │ +55 │ move |x| f(x) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:55:27 + │ +55 │ move |x| f(x) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:57:13 + │ +57 │ move |y| multiply3(y, 3, 4) with store + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:57:41 + │ +57 │ move |y| multiply3(y, 3, 4) with store + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:61:47 + │ +61 │ fun choose_function3(key: u64) : |u64|u64 with store { + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:63:21 + │ +63 │ let f = move |x| double(x) with store; + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:63:40 + │ +63 │ let f = move |x| double(x) with store; + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:66:21 + │ +66 │ let g = move |x| triple(x) with store; + │ ^^^^ Move 2.2 language construct is not enabled: Modifier on lambda expression + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:66:40 + │ +66 │ let g = move |x| triple(x) with store; + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Abilities on function expressions + +error: unsupported language construct + ┌─ tests/lambda/storable/return_func_ok.move:74:67 + │ +74 │ public fun test_functions(choose_function_arg: |u64|(|u64|u64 with store)) { + │ ^^^^^^^^^^ Move 2.2 language construct is not enabled: Ability constraints on function types diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.lambda.exp new file mode 100644 index 0000000000000..b37236d35a6fc --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.lambda.exp @@ -0,0 +1,1572 @@ +// -- Model dump before env processor pipeline: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor unused checks: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor type parameter check: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor check recursive struct definition: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor check cyclic type instantiation: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor unused struct params check: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor access and use check before inlining: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor inlining: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor access and use check after inlining: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor acquires check: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + { + let x: u64 = 3; + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(x)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(x)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, Vector(6, 9, 12, 10, 21, 24, 18, 33, 52)) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + +// -- Model dump after env processor simplifier: +module 0x42::test { + use std::vector; + private fun choose_function(key: u64): |u64|u64 with store { + if Eq(key, 0) { + test::double + } else { + if Eq(key, 1) { + test::triple + } else { + test::multiply_by_x(4) + } + } + } + private fun choose_function2(key: u64): |u64|u64 with store { + if Eq(key, 0) { + move|x: u64| test::double(x) with drop, store + } else { + if Eq(key, 1) { + move|x: u64| test::triple(x) with drop, store + } else { + if Eq(key, 2) { + { + let f: |u64|u64 with store = test::multiply_by_x(4); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 3) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 4) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + f + } + } else { + if Eq(key, 5) { + move|y: u64| test::multiply(y, 7) with drop, store + } else { + if Eq(key, 6) { + { + let f: |u64|u64 with copy+store = move|y: u64| test::multiply(6, y) with drop, store; + move|x: u64| (f)(x) with drop, store + } + } else { + if Eq(key, 7) { + { + let f: |u64|u64 with store = test::multiply_by_x(5); + move|x: u64| (f)(x) with drop, store + } + } else { + move|y: u64| test::multiply3(y, 3, 4) with drop, store + } + } + } + } + } + } + } + } + } + private fun choose_function3(key: u64): |u64|u64 with store { + if Eq(key, 0) { + { + let f: |u64|u64 with copy+store = move|x: u64| test::double(x) with drop, store; + f + } + } else { + if Eq(key, 1) { + { + let g: |u64|u64 with copy+store = move|x: u64| test::triple(x) with drop, store; + g + } + } else { + { + let h: |u64|u64 with store = test::multiply_by_x(4); + h + } + } + } + } + public fun double(x: u64): u64 { + Mul(x, 2) + } + public fun multiply(x: u64,y: u64): u64 { + Mul(x, y) + } + public fun multiply3(x: u64,y: u64,z: u64): u64 { + Mul(Mul(x, y), z) + } + private fun multiply_by_x(x: u64): |u64|u64 with store { + move|y: u64| test::multiply(x, y) with drop, store + } + public fun test_function_choosers() { + test::test_functions(test::choose_function); + test::test_functions(test::choose_function2); + test::test_functions(test::choose_function3); + Tuple() + } + public fun test_functions(choose_function_arg: |u64||u64|u64 with store) { + { + let sum: vector = Vector(); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(0))(3)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(1))(3)); + vector::push_back(Borrow(Mutable)(sum), ((choose_function_arg)(2))(3)); + { + let g: |u64|u64 with store = test::choose_function(1); + { + let h: |u64|u64 with store = test::choose_function(2); + { + let f: |u64|u64 with store = test::choose_function(0); + vector::push_back(Borrow(Mutable)(sum), (f)(5)); + vector::push_back(Borrow(Mutable)(sum), (g)(7)); + vector::push_back(Borrow(Mutable)(sum), (h)(6)); + { + let funcs: vector<|u64|u64 with store> = Vector<|u64|u64 with store>(test::choose_function(0), test::choose_function(1), test::choose_function(2)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 0)))(9)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 1)))(11)); + vector::push_back(Borrow(Mutable)(sum), (Deref(vector::borrow<|u64|u64>(Borrow(Immutable)(funcs), 2)))(13)); + if Eq>(sum, [Number(6), Number(9), Number(12), Number(10), Number(21), Number(24), Number(18), Number(33), Number(52)]) { + Tuple() + } else { + Abort(14566554180833181696) + } + } + } + } + } + } + } + public fun triple(x: u64): u64 { + Mul(x, 3) + } +} // end 0x42::test + + + +Diagnostics: +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/return_func_ok.move:49:13 + │ +49 │ move |y| multiply(y, 7) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: The body of a lambdas expression with `store` ability currently must be a simple call to an existing `public` function, with lambda params the same as the *final* arguments to the function call. + ┌─ tests/lambda/storable/return_func_ok.move:57:13 + │ +57 │ move |y| multiply3(y, 3, 4) with store + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.move b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.move new file mode 100644 index 0000000000000..7917652a778a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/lambda/storable/return_func_ok.move @@ -0,0 +1,106 @@ +module 0x42::test { + use std::vector; + + public fun double(x: u64): u64 { + x * 2 + } + + public fun triple(x: u64) : u64 { + x * 3 + } + + public fun multiply(x: u64, y: u64): u64 { + x * y + } + + public fun multiply3(x: u64, y: u64, z: u64): u64 { + x * y * z + } + + fun multiply_by_x(x: u64): |u64|u64 with store { + move |y| multiply(x, y) with store + } + + fun choose_function(key: u64) : |u64|u64 with store { + if (key == 0) { + double + } else if (key == 1) { + triple + } else { + multiply_by_x(4) + } + } + + fun choose_function2(key: u64): |u64|u64 with store { + if (key == 0) { + move |x| double(x) with store + } else if (key == 1) { + move |x| triple(x) with store + } else if (key == 2) { + let f = multiply_by_x(4); + move |x| f(x) with store + } else if (key == 3) { + let f = multiply_by_x(5); + move |x| f(x) with store + } else if (key == 4) { + let f = move |y| multiply(6, y) with store; + f + } else if (key == 5) { + move |y| multiply(y, 7) with store + } else if (key == 6) { + let f = move |y| multiply(6, y) with store; + move |x| f(x) with store + } else if (key == 7) { + let f = multiply_by_x(5); + move |x| f(x) with store + } else { + move |y| multiply3(y, 3, 4) with store + } + } + + fun choose_function3(key: u64) : |u64|u64 with store { + if (key == 0) { + let f = move |x| double(x) with store; + f + } else if (key == 1) { + let g = move |x| triple(x) with store; + g + } else { + let h = multiply_by_x(4); + h + } + } + + public fun test_functions(choose_function_arg: |u64|(|u64|u64 with store)) { + let sum = vector[]; + let x = 3; + // Note that currently we can only resolve a local var as a + // function value in a call if (1) there is no existing function with that name, + // or (2) the function name is in parentheses, to distinguish from an + // old-fashioned function call. + vector::push_back(&mut sum, (choose_function_arg(0))(x)); + vector::push_back(&mut sum, choose_function_arg(1)(x)); + vector::push_back(&mut sum, (choose_function_arg(2))(x)); + + let g = choose_function(1); + let h = choose_function(2); + let f = choose_function(0); + + vector::push_back(&mut sum, f(5)); + vector::push_back(&mut sum, g(7)); + vector::push_back(&mut sum, h(6)); + + let funcs = vector[choose_function(0), choose_function(1), choose_function(2)]; + vector::push_back(&mut sum, (funcs[0])(9)); + vector::push_back(&mut sum, (funcs[1])(11)); + vector::push_back(&mut sum, (funcs[2])(13)); + + assert!(sum == vector[6, 9, 12, 10, 21, 24, 18, 33, 52]) + } + + public fun test_function_choosers() { + test_functions(choose_function); + test_functions(choose_function2); + test_functions(choose_function3); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp new file mode 100644 index 0000000000000..e2453ef24dad5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp @@ -0,0 +1,27 @@ +comparison between v1 and v2 failed: += processed 3 tasks += ++ task 1 'publish'. lines 12-28: ++ warning: Unused parameter `f`. Consider removing or prefixing with an underscore: `_f` ++ ┌─ TEMPFILE1:18:28 ++ │ ++ 18 │ public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { ++ │ ^ ++ ++ warning: Unused parameter `g`. Consider removing or prefixing with an underscore: `_g` ++ ┌─ TEMPFILE1:18:45 ++ │ ++ 18 │ public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { ++ │ ^ ++ ++ warning: Unused parameter `i`. Consider removing or prefixing with an underscore: `_i` ++ ┌─ TEMPFILE1:18:57 ++ │ ++ 18 │ public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { ++ │ ^ ++ ++ ++ += task 2 'run'. lines 30-30: += return values: 5280 += diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.move b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.move new file mode 100644 index 0000000000000..e527c426c7eef --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.move @@ -0,0 +1,30 @@ +//# publish +module 0x42::OtherModule { + public fun g(a: u64, b: u64): u64 { + a + b + } + + public fun h(a: u64, b: u64): u64 { + 2 * a + b + } +} + +//# publish +module 0x42::Test { + use 0x42::OtherModule::g; + + public fun f(a: u64, b: u64): u64 { + a * b + } + + public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + use 0x42::OtherModule::h; + f(a, b) * g(a, b) * h(a, b) + } + + public fun test_shadowing(): u64 { + quux(|a, b| a - b, |a| a + 2, |b| 255u8-b, 10, 2) + } +} + +//# run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler/tests/move_check/inlining/function_name_shadowing.move b/third_party/move/move-compiler/tests/move_check/inlining/function_name_shadowing.move new file mode 100644 index 0000000000000..e527c426c7eef --- /dev/null +++ b/third_party/move/move-compiler/tests/move_check/inlining/function_name_shadowing.move @@ -0,0 +1,30 @@ +//# publish +module 0x42::OtherModule { + public fun g(a: u64, b: u64): u64 { + a + b + } + + public fun h(a: u64, b: u64): u64 { + 2 * a + b + } +} + +//# publish +module 0x42::Test { + use 0x42::OtherModule::g; + + public fun f(a: u64, b: u64): u64 { + a * b + } + + public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + use 0x42::OtherModule::h; + f(a, b) * g(a, b) * h(a, b) + } + + public fun test_shadowing(): u64 { + quux(|a, b| a - b, |a| a + 2, |b| 255u8-b, 10, 2) + } +} + +//# run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler/transactional-tests/tests/inlining/function_name_shadowing.exp b/third_party/move/move-compiler/transactional-tests/tests/inlining/function_name_shadowing.exp new file mode 100644 index 0000000000000..2463a580a0079 --- /dev/null +++ b/third_party/move/move-compiler/transactional-tests/tests/inlining/function_name_shadowing.exp @@ -0,0 +1,4 @@ +processed 3 tasks + +task 2 'run'. lines 30-30: +return values: 5280 diff --git a/third_party/move/move-compiler/transactional-tests/tests/inlining/function_name_shadowing.move b/third_party/move/move-compiler/transactional-tests/tests/inlining/function_name_shadowing.move new file mode 100644 index 0000000000000..e527c426c7eef --- /dev/null +++ b/third_party/move/move-compiler/transactional-tests/tests/inlining/function_name_shadowing.move @@ -0,0 +1,30 @@ +//# publish +module 0x42::OtherModule { + public fun g(a: u64, b: u64): u64 { + a + b + } + + public fun h(a: u64, b: u64): u64 { + 2 * a + b + } +} + +//# publish +module 0x42::Test { + use 0x42::OtherModule::g; + + public fun f(a: u64, b: u64): u64 { + a * b + } + + public inline fun quux(f:|u64, u64|u64, g:|u64|u64, i:|u8|u8, a: u64, b: u64): u64 { + use 0x42::OtherModule::h; + f(a, b) * g(a, b) * h(a, b) + } + + public fun test_shadowing(): u64 { + quux(|a, b| a - b, |a| a + 2, |b| 255u8-b, 10, 2) + } +} + +//# run 0x42::Test::test_shadowing diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index 485bd3c273a96..1d2c5c74d106a 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -164,9 +164,6 @@ pub enum Constraint { /// a pseudo constraint which never fails, but used to generate a default for /// inference. WithDefault(Type), - /// The type must not be function because it is used as the type of some field or - /// as a type argument. - NoFunction, } /// Scope of ability checking. @@ -409,10 +406,7 @@ impl Constraint { /// for internal constraints which would be mostly confusing to users. pub fn hidden(&self) -> bool { use Constraint::*; - matches!( - self, - NoPhantom | NoReference | NoTuple | NoFunction | WithDefault(..) - ) + matches!(self, NoPhantom | NoReference | NoTuple | WithDefault(..)) } /// Returns true if this context is accumulating. When adding a new constraint @@ -430,7 +424,6 @@ impl Constraint { | Constraint::NoPhantom | Constraint::NoTuple | Constraint::NoReference - | Constraint::NoFunction ) } @@ -449,10 +442,7 @@ impl Constraint { /// the same type. pub fn report_only_once(&self) -> bool { use Constraint::*; - matches!( - self, - HasAbilities(..) | NoReference | NoFunction | NoPhantom | NoTuple - ) + matches!(self, HasAbilities(..) | NoReference | NoPhantom | NoTuple) } /// Joins the two constraints. If they are incompatible, produces a type unification error. @@ -539,7 +529,6 @@ impl Constraint { )) } }, - (Constraint::NoFunction, Constraint::NoFunction) => Ok(true), (Constraint::NoReference, Constraint::NoReference) => Ok(true), (Constraint::NoTuple, Constraint::NoTuple) => Ok(true), (Constraint::NoPhantom, Constraint::NoPhantom) => Ok(true), @@ -590,14 +579,10 @@ impl Constraint { } /// Returns the constraints which need to be satisfied to instantiate the given type - /// parameter. This creates NoReference, NoFunction, NoTuple, NoPhantom unless the type + /// parameter. This creates NoReference, NoTuple, NoPhantom unless the type /// parameter is phantom, and HasAbilities if any abilities need to be met. pub fn for_type_parameter(param: &TypeParameter) -> Vec { - let mut result = vec![ - Constraint::NoReference, - Constraint::NoTuple, - Constraint::NoFunction, // TODO(LAMBDA) - remove when implement LAMBDA_AS_TYPE_PARAMETERS - ]; + let mut result = vec![Constraint::NoReference, Constraint::NoTuple]; let TypeParameter( _, TypeParameterKind { @@ -624,7 +609,6 @@ impl Constraint { Constraint::NoPhantom, Constraint::NoReference, Constraint::NoTuple, - Constraint::NoFunction, // TODO(LAMBDA) - remove when we implement LAMBDA_IN_VECTORS ] } @@ -635,7 +619,6 @@ impl Constraint { Constraint::NoPhantom, Constraint::NoTuple, Constraint::NoReference, - Constraint::NoFunction, ]; let abilities = if struct_abilities.has_ability(Ability::Key) { struct_abilities.remove(Ability::Key).add(Ability::Store) @@ -705,7 +688,6 @@ impl Constraint { ) }, Constraint::NoReference => "no-ref".to_string(), - Constraint::NoFunction => "no-func".to_string(), Constraint::NoTuple => "no-tuple".to_string(), Constraint::NoPhantom => "no-phantom".to_string(), Constraint::HasAbilities(required_abilities, _) => { @@ -1925,13 +1907,6 @@ impl Substitution { Ok(()) } }, - (Constraint::NoFunction, ty) => { - if ty.is_function() { - constraint_unsatisfied_error() - } else { - Ok(()) - } - }, (Constraint::NoTuple, ty) => { if ty.is_tuple() { constraint_unsatisfied_error() @@ -3175,13 +3150,6 @@ impl TypeUnificationError { item_name() ) }, - Constraint::NoFunction => { - format!( - "function type `{}` is not allowed {}", - ty.display(display_context), - item_name() - ) - }, Constraint::NoPhantom => { format!( "phantom type `{}` can only be used as an argument for another phantom type parameter", diff --git a/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs b/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs index 0b58373ba8267..8a921e15b66be 100644 --- a/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs +++ b/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs @@ -592,7 +592,7 @@ pub fn boogie_value(env: &GlobalEnv, _options: &BoogieOptions, val: &Value) -> S .collect_vec(), ), Value::Tuple(vec) => format!("<>", vec), - Value::Function(mid, fid) => format!("", mid, fid), // TODO(LAMBDA) + Value::Function(mid, fid) => format!("", mid, fid), // TODO(LAMBDA) } } diff --git a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs index b674d30b855b9..d3157c01a7161 100644 --- a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs +++ b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs @@ -270,8 +270,12 @@ impl<'env> SpecTranslator<'env> { // so we don't need to translate it. return; } - if let Type::Tuple(..) | Type::Fun(..) = fun.result_type { - self.error(&fun.loc, "function or tuple result type not yet supported"); + if let Type::Tuple(..) = fun.result_type { + self.error(&fun.loc, "tuple result type not yet supported"); + return; + } + if let Type::Fun(..) = fun.result_type { + self.error(&fun.loc, "function result type not yet supported"); // TODO(LAMBDA) return; } let qid = module_env.get_id().qualified(id); @@ -684,6 +688,7 @@ impl<'env> SpecTranslator<'env> { }, ExpData::Invoke(node_id, ..) => { self.error(&self.env.get_node_loc(*node_id), "Invoke not yet supported"); + // TODO(LAMBDA) }, ExpData::Lambda(node_id, ..) => self.error( &self.env.get_node_loc(*node_id), @@ -1020,8 +1025,7 @@ impl<'env> SpecTranslator<'env> { self.env.error( &self.env.get_node_loc(node_id), &format!( - "bug: operation {} is not supported \ - in the current context", + "bug: operation {} is not supported in the current context", oper.display(self.env, node_id) ), );