Repository: aptos-labs/aptos-core (language: python)

Issue:
[Bug][compiler-v2] Tests running for "move-unit-test" package are not using compiler v2
# 🐛 Bug

If we go to `third_party/move/tools/move-unit-test` and run: `MVC_V2=1 MVC_BLOCK_V1=1 cargo test`, we see that it panics with "V1 compiler not expected".

But the `scripts/move_pr.sh` runs these tests with `MVC_V2=1` (i.e., the equivalent `MOVE_COMPILER_V2=true`); we also have baseline files `*.v2_exp` added with the expectation that these outputs are from running compiler v2. However, all of these actually are just running compiler v1, giving us a false sense of testing.

## To reproduce

See steps above.

## Expected Behavior

We should be running the tests under `third_party/move/tools/move-unit-test` with compiler v2 when `MVC_V2=1`.


Discussion / hints:
cc @rahxephon89 @brmataptos: in case this was an already known issue.
> cc @rahxephon89 @brmataptos: in case this was an already known issue.

Good catch @vineethk! We should use `plan_builder_v2` when V2 flag is turned on. cc @brmataptos 


Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 41f1d2707b060..884b2bbcc892e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11789,8 +11789,11 @@ dependencies = [
  "move-bytecode-utils",
  "move-command-line-common",
  "move-compiler",
+ "move-compiler-v2",
  "move-core-types",
  "move-ir-types",
+ "move-model",
+ "move-package",
  "move-resource-viewer",
  "move-stdlib",
  "move-symbol-pool",


Test patch:
diff --git a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/function_info.md b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/function_info.md
index b7f0a2482ac0a..2984cf918d4c0 100644
--- a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/function_info.md
+++ b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/function_info.md
@@ -147,7 +147,7 @@ Creates a new function info from names.
 
 
 
-<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="function_info.md#0x1_function_info_new_function_info_from_address">new_function_info_from_address</a>(module_address: <b>address</b>, module_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>, function_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>): <a href="function_info.md#0x1_function_info_FunctionInfo">function_info::FunctionInfo</a>
+<pre><code><b>public</b> <b>fun</b> <a href="function_info.md#0x1_function_info_new_function_info_from_address">new_function_info_from_address</a>(module_address: <b>address</b>, module_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>, function_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>): <a href="function_info.md#0x1_function_info_FunctionInfo">function_info::FunctionInfo</a>
 </code></pre>
 
 
@@ -156,7 +156,7 @@ Creates a new function info from names.
 <summary>Implementation</summary>
 
 
-<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="function_info.md#0x1_function_info_new_function_info_from_address">new_function_info_from_address</a>(
+<pre><code><b>public</b> <b>fun</b> <a href="function_info.md#0x1_function_info_new_function_info_from_address">new_function_info_from_address</a>(
     module_address: <b>address</b>,
     module_name: String,
     function_name: String,
@@ -363,7 +363,7 @@ if such module isn't accessed previously in the transaction.
 ### Function `new_function_info_from_address`
 
 
-<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="function_info.md#0x1_function_info_new_function_info_from_address">new_function_info_from_address</a>(module_address: <b>address</b>, module_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>, function_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>): <a href="function_info.md#0x1_function_info_FunctionInfo">function_info::FunctionInfo</a>
+<pre><code><b>public</b> <b>fun</b> <a href="function_info.md#0x1_function_info_new_function_info_from_address">new_function_info_from_address</a>(module_address: <b>address</b>, module_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>, function_name: <a href="../../../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_String">string::String</a>): <a href="function_info.md#0x1_function_info_FunctionInfo">function_info::FunctionInfo</a>
 </code></pre>
 
 
diff --git a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/stake.md b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/stake.md
index 6dbfe59be07b9..48feb9dd3a1c1 100644
--- a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/stake.md
+++ b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/stake.md
@@ -1752,7 +1752,7 @@ Owner capability does not exist at the provided account.
 
 <a id="0x1_stake_ERECONFIGURATION_IN_PROGRESS"></a>
 
-Validator set change temporarily disabled because of in-progress reconfiguration.
+Validator set change temporarily disabled because of in-progress reconfiguration. Please retry after 1 minute.
 
 
 <pre><code><b>const</b> <a href="stake.md#0x1_stake_ERECONFIGURATION_IN_PROGRESS">ERECONFIGURATION_IN_PROGRESS</a>: u64 = 20;
@@ -4566,6 +4566,39 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+<a id="0x1_stake_spec_validator_index_upper_bound"></a>
+
+
+<pre><code><b>fun</b> <a href="stake.md#0x1_stake_spec_validator_index_upper_bound">spec_validator_index_upper_bound</a>(): u64 {
+   len(<b>global</b>&lt;<a href="stake.md#0x1_stake_ValidatorPerformance">ValidatorPerformance</a>&gt;(@aptos_framework).validators)
+}
+</code></pre>
+
+
+
+
+<a id="0x1_stake_spec_has_stake_pool"></a>
+
+
+<pre><code><b>fun</b> <a href="stake.md#0x1_stake_spec_has_stake_pool">spec_has_stake_pool</a>(a: <b>address</b>): bool {
+   <b>exists</b>&lt;<a href="stake.md#0x1_stake_StakePool">StakePool</a>&gt;(a)
+}
+</code></pre>
+
+
+
+
+<a id="0x1_stake_spec_has_validator_config"></a>
+
+
+<pre><code><b>fun</b> <a href="stake.md#0x1_stake_spec_has_validator_config">spec_has_validator_config</a>(a: <b>address</b>): bool {
+   <b>exists</b>&lt;<a href="stake.md#0x1_stake_ValidatorConfig">ValidatorConfig</a>&gt;(a)
+}
+</code></pre>
+
+
+
+
 <a id="0x1_stake_spec_rewards_amount"></a>
 
 
@@ -5611,39 +5644,6 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
-<a id="0x1_stake_spec_validator_index_upper_bound"></a>
-
-
-<pre><code><b>fun</b> <a href="stake.md#0x1_stake_spec_validator_index_upper_bound">spec_validator_index_upper_bound</a>(): u64 {
-   len(<b>global</b>&lt;<a href="stake.md#0x1_stake_ValidatorPerformance">ValidatorPerformance</a>&gt;(@aptos_framework).validators)
-}
-</code></pre>
-
-
-
-
-<a id="0x1_stake_spec_has_stake_pool"></a>
-
-
-<pre><code><b>fun</b> <a href="stake.md#0x1_stake_spec_has_stake_pool">spec_has_stake_pool</a>(a: <b>address</b>): bool {
-   <b>exists</b>&lt;<a href="stake.md#0x1_stake_StakePool">StakePool</a>&gt;(a)
-}
-</code></pre>
-
-
-
-
-<a id="0x1_stake_spec_has_validator_config"></a>
-
-
-<pre><code><b>fun</b> <a href="stake.md#0x1_stake_spec_has_validator_config">spec_has_validator_config</a>(a: <b>address</b>): bool {
-   <b>exists</b>&lt;<a href="stake.md#0x1_stake_ValidatorConfig">ValidatorConfig</a>&gt;(a)
-}
-</code></pre>
-
-
-
 <a id="@Specification_1_update_stake_pool"></a>
 
 ### Function `update_stake_pool`
diff --git a/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/big_vector.md b/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/big_vector.md
index 2e7a9a100357c..c255994e67731 100644
--- a/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/big_vector.md
+++ b/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/big_vector.md
@@ -502,7 +502,7 @@ Aborts if <code>i</code> is out of bounds.
     <b>if</b> (self.end_index == i) {
         <b>return</b> last_val
     };
-    // because the lack of mem::swap, here we swap remove the requested value from the bucket
+    // because the lack of <a href="../../../move-stdlib/tests/compiler-v2-doc/mem.md#0x1_mem_swap">mem::swap</a>, here we swap remove the requested value from the bucket
     // and append the last_val <b>to</b> the bucket then swap the last bucket val back
     <b>let</b> bucket = <a href="table_with_length.md#0x1_table_with_length_borrow_mut">table_with_length::borrow_mut</a>(&<b>mut</b> self.buckets, i / self.bucket_size);
     <b>let</b> bucket_len = <a href="../../../move-stdlib/tests/compiler-v2-doc/vector.md#0x1_vector_length">vector::length</a>(bucket);
diff --git a/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/from_bcs.md b/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/from_bcs.md
index 5838c78fdd758..91d0e365bcf12 100644
--- a/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/from_bcs.md
+++ b/aptos-move/framework/aptos-stdlib/tests/compiler-v2-doc/from_bcs.md
@@ -5,7 +5,7 @@
 
 This module provides a number of functions to convert _primitive_ types from their representation in <code>std::bcs</code>
 to values. This is the opposite of <code><a href="../../../move-stdlib/tests/compiler-v2-doc/bcs.md#0x1_bcs_to_bytes">bcs::to_bytes</a></code>. Note that it is not safe to define a generic public <code>from_bytes</code>
-function because this can violate implicit struct invariants, therefore only primitive types are offerred. If
+function because this can violate implicit struct invariants, therefore only primitive types are offered. If
 a general conversion back-and-force is needed, consider the <code>aptos_std::Any</code> type which preserves invariants.
 
 Example:
diff --git a/aptos-move/framework/aptos-token-objects/tests/compiler-v2-doc/collection.md b/aptos-move/framework/aptos-token-objects/tests/compiler-v2-doc/collection.md
index 185c3beca8d08..bf3628a4f9afa 100644
--- a/aptos-move/framework/aptos-token-objects/tests/compiler-v2-doc/collection.md
+++ b/aptos-move/framework/aptos-token-objects/tests/compiler-v2-doc/collection.md
@@ -1722,7 +1722,6 @@ After changing the collection's name, to create tokens - only call functions tha
 <pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_set_description">set_description</a>(mutator_ref: &<a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a>, description: String) <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
     <b>assert</b>!(<a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_length">string::length</a>(&description) &lt;= <a href="collection.md#0x4_collection_MAX_DESCRIPTION_LENGTH">MAX_DESCRIPTION_LENGTH</a>, <a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/error.md#0x1_error_out_of_range">error::out_of_range</a>(<a href="collection.md#0x4_collection_EDESCRIPTION_TOO_LONG">EDESCRIPTION_TOO_LONG</a>));
     <b>let</b> <a href="collection.md#0x4_collection">collection</a> = <a href="collection.md#0x4_collection_borrow_mut">borrow_mut</a>(mutator_ref);
-    <a href="collection.md#0x4_collection">collection</a>.description = description;
     <b>if</b> (std::features::module_event_migration_enabled()) {
         <a href="../../../aptos-framework/tests/compiler-v2-doc/event.md#0x1_event_emit">event::emit</a>(<a href="collection.md#0x4_collection_Mutation">Mutation</a> {
             mutated_field_name: <a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_utf8">string::utf8</a>(b"description"),
@@ -1736,6 +1735,7 @@ After changing the collection's name, to create tokens - only call functions tha
             <a href="collection.md#0x4_collection_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_utf8">string::utf8</a>(b"description") },
         );
     };
+    <a href="collection.md#0x4_collection">collection</a>.description = description;
 }
 </code></pre>
 
@@ -1761,7 +1761,6 @@ After changing the collection's name, to create tokens - only call functions tha
 <pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_set_uri">set_uri</a>(mutator_ref: &<a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a>, uri: String) <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
     <b>assert</b>!(<a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_length">string::length</a>(&uri) &lt;= <a href="collection.md#0x4_collection_MAX_URI_LENGTH">MAX_URI_LENGTH</a>, <a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/error.md#0x1_error_out_of_range">error::out_of_range</a>(<a href="collection.md#0x4_collection_EURI_TOO_LONG">EURI_TOO_LONG</a>));
     <b>let</b> <a href="collection.md#0x4_collection">collection</a> = <a href="collection.md#0x4_collection_borrow_mut">borrow_mut</a>(mutator_ref);
-    <a href="collection.md#0x4_collection">collection</a>.uri = uri;
     <b>if</b> (std::features::module_event_migration_enabled()) {
         <a href="../../../aptos-framework/tests/compiler-v2-doc/event.md#0x1_event_emit">event::emit</a>(<a href="collection.md#0x4_collection_Mutation">Mutation</a> {
             mutated_field_name: <a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_utf8">string::utf8</a>(b"uri"),
@@ -1775,6 +1774,7 @@ After changing the collection's name, to create tokens - only call functions tha
             <a href="collection.md#0x4_collection_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../../aptos-framework/../aptos-stdlib/../move-stdlib/tests/compiler-v2-doc/string.md#0x1_string_utf8">string::utf8</a>(b"uri") },
         );
     };
+    <a href="collection.md#0x4_collection">collection</a>.uri = uri;
 }
 </code></pre>
 
diff --git a/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/bcs.md b/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/bcs.md
index 9bdcf7f45f7d3..0a73d39902341 100644
--- a/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/bcs.md
+++ b/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/bcs.md
@@ -11,11 +11,13 @@ details on BCS.
 
 -  [Function `to_bytes`](#0x1_bcs_to_bytes)
 -  [Function `serialized_size`](#0x1_bcs_serialized_size)
+-  [Function `constant_serialized_size`](#0x1_bcs_constant_serialized_size)
 -  [Specification](#@Specification_0)
     -  [Function `serialized_size`](#@Specification_0_serialized_size)
 
 
-<pre><code></code></pre>
+<pre><code><b>use</b> <a href="option.md#0x1_option">0x1::option</a>;
+</code></pre>
 
 
 
@@ -65,6 +67,38 @@ Aborts with <code>0x1c5</code> error code if there is a failure when calculating
 
 
 
+</details>
+
+<a id="0x1_bcs_constant_serialized_size"></a>
+
+## Function `constant_serialized_size`
+
+If the type has known constant (always the same, independent of instance) serialized size
+in BCS (Binary Canonical Serialization) format, returns it, otherwise returns None.
+Aborts with <code>0x1c5</code> error code if there is a failure when calculating serialized size.
+
+Note:
+For some types it might not be known they have constant size, and function might return None.
+For example, signer appears to have constant size, but it's size might change.
+If this function returned Some() for some type before - it is guaranteed to continue returning Some().
+On the other hand, if function has returned None for some type,
+it might change in the future to return Some() instead, if size becomes "known".
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="bcs.md#0x1_bcs_constant_serialized_size">constant_serialized_size</a>&lt;MoveValue&gt;(): <a href="option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>native</b> <b>public</b>(<b>friend</b>) <b>fun</b> <a href="bcs.md#0x1_bcs_constant_serialized_size">constant_serialized_size</a>&lt;MoveValue&gt;(): Option&lt;u64&gt;;
+</code></pre>
+
+
+
 </details>
 
 <a id="@Specification_0"></a>
diff --git a/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/overview.md b/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/overview.md
index 8eb0c67f05113..649873e8ab2f5 100644
--- a/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/overview.md
+++ b/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/overview.md
@@ -20,6 +20,7 @@ For on overview of the Move language, see the [Move Book][move-book].
 -  [`0x1::features`](features.md#0x1_features)
 -  [`0x1::fixed_point32`](fixed_point32.md#0x1_fixed_point32)
 -  [`0x1::hash`](hash.md#0x1_hash)
+-  [`0x1::mem`](mem.md#0x1_mem)
 -  [`0x1::option`](option.md#0x1_option)
 -  [`0x1::signer`](signer.md#0x1_signer)
 -  [`0x1::string`](string.md#0x1_string)
diff --git a/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/vector.md b/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/vector.md
index d5e6a7bfa2ecd..b56160dbaf27e 100644
--- a/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/vector.md
+++ b/aptos-move/framework/move-stdlib/tests/compiler-v2-doc/vector.md
@@ -24,6 +24,7 @@ the return on investment didn't seem worth it for these simple functions.
 -  [Function `pop_back`](#0x1_vector_pop_back)
 -  [Function `destroy_empty`](#0x1_vector_destroy_empty)
 -  [Function `swap`](#0x1_vector_swap)
+-  [Function `move_range`](#0x1_vector_move_range)
 -  [Function `singleton`](#0x1_vector_singleton)
 -  [Function `reverse`](#0x1_vector_reverse)
 -  [Function `reverse_slice`](#0x1_vector_reverse_slice)
@@ -340,6 +341,43 @@ Aborts if <code>i</code> or <code>j</code> is out of bounds.
 
 
 
+</details>
+
+<a id="0x1_vector_move_range"></a>
+
+## Function `move_range`
+
+Moves range of elements <code>[removal_position, removal_position + length)</code> from vector <code>from</code>,
+to vector <code><b>to</b></code>, inserting them starting at the <code>insert_position</code>.
+In the <code>from</code> vector, elements after the selected range are moved left to fill the hole
+(i.e. range is removed, while the order of the rest of the elements is kept)
+In the <code><b>to</b></code> vector, elements after the <code>insert_position</code> are moved to the right to make
+space for new elements (i.e. range is inserted, while the order of the rest of the
+elements is kept).
+Move prevents from having two mutable references to the same value, so <code>from</code> and <code><b>to</b></code>
+vectors are always distinct.
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="vector.md#0x1_vector_move_range">move_range</a>&lt;T&gt;(from: &<b>mut</b> <a href="vector.md#0x1_vector">vector</a>&lt;T&gt;, removal_position: u64, length: u64, <b>to</b>: &<b>mut</b> <a href="vector.md#0x1_vector">vector</a>&lt;T&gt;, insert_position: u64)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>native</b> <b>public</b>(<b>friend</b>) <b>fun</b> <a href="vector.md#0x1_vector_move_range">move_range</a>&lt;T&gt;(
+    from: &<b>mut</b> <a href="vector.md#0x1_vector">vector</a>&lt;T&gt;,
+    removal_position: u64,
+    length: u64,
+    <b>to</b>: &<b>mut</b> <a href="vector.md#0x1_vector">vector</a>&lt;T&gt;,
+    insert_position: u64
+);
+</code></pre>
+
+
+
 </details>
 
 <a id="0x1_vector_singleton"></a>
diff --git a/third_party/move/tools/move-unit-test/Cargo.toml b/third_party/move/tools/move-unit-test/Cargo.toml
index d45644fef2d80..c0e29367cb1a0 100644
--- a/third_party/move/tools/move-unit-test/Cargo.toml
+++ b/third_party/move/tools/move-unit-test/Cargo.toml
@@ -25,8 +25,11 @@ regex = { workspace = true }
 
 move-command-line-common = { path = "../../move-command-line-common" }
 move-compiler = { path = "../../move-compiler" }
+move-compiler-v2 = { path = "../../move-compiler-v2" }
 move-core-types = { path = "../../move-core/types" }
 move-ir-types = { path = "../../move-ir/types" }
+move-model = { path = "../../move-model" }
+move-package = { path = "../move-package" }
 move-resource-viewer = { path = "../move-resource-viewer" }
 move-stdlib = { path = "../../move-stdlib", features = ["testing"] }
 move-symbol-pool = { path = "../../move-symbol-pool" }
diff --git a/third_party/move/tools/move-unit-test/src/lib.rs b/third_party/move/tools/move-unit-test/src/lib.rs
index 4595059dcdd51..c2f34fb8f15b6 100644
--- a/third_party/move/tools/move-unit-test/src/lib.rs
+++ b/third_party/move/tools/move-unit-test/src/lib.rs
@@ -8,7 +8,9 @@ pub mod test_runner;
 
 use crate::test_runner::TestRunner;
 use clap::*;
-use move_command_line_common::files::verify_and_create_named_address_mapping;
+use move_command_line_common::{
+    env::get_move_compiler_v2_from_env, files::verify_and_create_named_address_mapping,
+};
 use move_compiler::{
     self,
     diagnostics::{self, codes::Severity},
@@ -16,7 +18,10 @@ use move_compiler::{
     unit_test::{self, TestPlan},
     Compiler, Flags, PASS_CFGIR,
 };
+use move_compiler_v2::plan_builder as plan_builder_v2;
 use move_core_types::{effects::ChangeSet, language_storage::ModuleId};
+use move_model::metadata::{CompilerVersion, LanguageVersion};
+use move_package::compilation::compiled_package::build_and_report_v2_driver;
 use move_vm_runtime::native_functions::NativeFunctionTable;
 use std::{
     collections::BTreeMap,
@@ -156,37 +161,59 @@ impl UnitTestingConfig {
     ) -> Option<TestPlan> {
         let addresses =
             verify_and_create_named_address_mapping(self.named_address_values.clone()).ok()?;
-        let (files, comments_and_compiler_res) = Compiler::from_files(
-            source_files,
-            deps,
-            addresses,
-            Flags::testing().set_skip_attribute_checks(false),
-            KnownAttribute::get_all_attribute_names(),
-        )
-        .run::<PASS_CFGIR>()
-        .unwrap();
-        let (_, compiler) =
-            diagnostics::unwrap_or_report_diagnostics(&files, comments_and_compiler_res);
-
-        let (mut compiler, cfgir) = compiler.into_ast();
-        let compilation_env = compiler.compilation_env();
-        let test_plan = unit_test::plan_builder::construct_test_plan(compilation_env, None, &cfgir);
-
-        if let Err(diags) = compilation_env.check_diags_at_or_above_severity(
-            if self.ignore_compile_warnings {
-                Severity::NonblockingError
-            } else {
-                Severity::Warning
-            },
-        ) {
-            diagnostics::report_diagnostics(&files, diags);
-        }
+        let (test_plan, files, units) = if get_move_compiler_v2_from_env() {
+            let options = move_compiler_v2::Options {
+                compile_test_code: true,
+                testing: true,
+                sources: source_files,
+                dependencies: deps,
+                compiler_version: Some(CompilerVersion::latest_stable()),
+                language_version: Some(LanguageVersion::latest_stable()),
+                named_address_mapping: addresses
+                    .iter()
+                    .map(|(string, num_addr)| format!("{}={}", string, num_addr))
+                    .collect(),
+                ..Default::default()
+            };
+            let (files, units, opt_env) = build_and_report_v2_driver(options).unwrap();
+            let env = opt_env.expect("v2 driver should return env");
+            let test_plan = plan_builder_v2::construct_test_plan(&env, None);
+            (test_plan, files, units)
+        } else {
+            let (files, comments_and_compiler_res) = Compiler::from_files(
+                source_files,
+                deps,
+                addresses,
+                Flags::testing().set_skip_attribute_checks(false),
+                KnownAttribute::get_all_attribute_names(),
+            )
+            .run::<PASS_CFGIR>()
+            .unwrap();
+            let (_, compiler) =
+                diagnostics::unwrap_or_report_diagnostics(&files, comments_and_compiler_res);
+
+            let (mut compiler, cfgir) = compiler.into_ast();
+            let compilation_env = compiler.compilation_env();
+            let test_plan =
+                unit_test::plan_builder::construct_test_plan(compilation_env, None, &cfgir);
+
+            if let Err(diags) = compilation_env.check_diags_at_or_above_severity(
+                if self.ignore_compile_warnings {
+                    Severity::NonblockingError
+                } else {
+                    Severity::Warning
+                },
+            ) {
+                diagnostics::report_diagnostics(&files, diags);
+            }
 
-        let compilation_result = compiler.at_cfgir(cfgir).build();
+            let compilation_result = compiler.at_cfgir(cfgir).build();
 
-        let (units, warnings) =
-            diagnostics::unwrap_or_report_diagnostics(&files, compilation_result);
-        diagnostics::report_warnings(&files, warnings);
+            let (units, warnings) =
+                diagnostics::unwrap_or_report_diagnostics(&files, compilation_result);
+            diagnostics::report_warnings(&files, warnings);
+            (test_plan, files, units)
+        };
         test_plan.map(|tests| TestPlan::new(tests, files, units))
     }
 
diff --git a/third_party/move/tools/move-unit-test/tests/test_sources/missing_data.v2_exp b/third_party/move/tools/move-unit-test/tests/test_sources/missing_data.v2_exp
index 2b61f4e0d5a72..9a63c9e43f498 100644
--- a/third_party/move/tools/move-unit-test/tests/test_sources/missing_data.v2_exp
+++ b/third_party/move/tools/move-unit-test/tests/test_sources/missing_data.v2_exp
@@ -23,7 +23,7 @@ Failures in 0x1::MissingData:
 │ 5 │     fun missing_data() acquires Missing {
 │   │         ------------ In this function in 0x1::MissingData
 │ 6 │         borrow_global<Missing>(@0x0);
-│   │         ^^^^^^^^^^^^^ Test was not expected to error, but it gave a MISSING_DATA (code 4008) error with error message: "Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000000". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000001::MissingData rooted here
+│   │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a MISSING_DATA (code 4008) error with error message: "Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000000". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000001::MissingData rooted here
 │ 
 │ 
 └──────────────────
@@ -36,7 +36,7 @@ Failures in 0x1::MissingData:
 │ 5 │     fun missing_data() acquires Missing {
 │   │         ------------ In this function in 0x1::MissingData
 │ 6 │         borrow_global<Missing>(@0x0);
-│   │         ^^^^^^^^^^^^^ Test was not expected to error, but it gave a MISSING_DATA (code 4008) error with error message: "Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000000". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000001::MissingData rooted here
+│   │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a MISSING_DATA (code 4008) error with error message: "Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000000". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000001::MissingData rooted here
 │ 
 │ 
 │ stack trace
diff --git a/third_party/move/tools/move-unit-test/tests/test_sources/native_signer_creation.v2_exp b/third_party/move/tools/move-unit-test/tests/test_sources/native_signer_creation.v2_exp
index 9b98bb942e7bf..ee17a0a77e621 100644
--- a/third_party/move/tools/move-unit-test/tests/test_sources/native_signer_creation.v2_exp
+++ b/third_party/move/tools/move-unit-test/tests/test_sources/native_signer_creation.v2_exp
@@ -15,13 +15,13 @@ Failures in 0x1::M:
 
 ┌── test_doesnt_exist ──────
 │ error[E11001]: test failure
-│    ┌─ native_signer_creation.move:47:9
+│    ┌─ native_signer_creation.move:43:17
 │    │
 │ 36 │     fun test_doesnt_exist() {
 │    │         ----------------- In this function in 0x1::M
 │    ·
-│ 47 │         abort 0
-│    │         ^^^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0000000000000000000000000000000000000000000000000000000000000001::M rooted here
+│ 43 │             i = i + 1;
+│    │                 ^^^^^ Test was not expected to error, but it aborted with code 0 originating in the module 0000000000000000000000000000000000000000000000000000000000000001::M rooted here
 │ 
 │ 
 └──────────────────
diff --git a/third_party/move/tools/move-unit-test/tests/test_sources/out_of_gas.v2_exp b/third_party/move/tools/move-unit-test/tests/test_sources/out_of_gas.v2_exp
index ee93f3921bb8c..f33824c63ed26 100644
--- a/third_party/move/tools/move-unit-test/tests/test_sources/out_of_gas.v2_exp
+++ b/third_party/move/tools/move-unit-test/tests/test_sources/out_of_gas.v2_exp
@@ -20,12 +20,12 @@ Failures in 0x42::m:
 
 ┌── t1 ──────
 │ error[E11001]: test failure
-│    ┌─ out_of_gas.move:10:10
+│    ┌─ out_of_gas.move:10:5
 │    │
 │  9 │ fun t1() {
 │    │     -- In this function in 0x42::m
 │ 10 │     loop {}
-│    │          ^^ Test did not error as expected. Expected test to give an arithmetic error originating in the module 0000000000000000000000000000000000000000000000000000000000000042::m but instead it ran out of gas in the module 0000000000000000000000000000000000000000000000000000000000000042::m rooted here
+│    │     ^^^^^^^ Test did not error as expected. Expected test to give an arithmetic error originating in the module 0000000000000000000000000000000000000000000000000000000000000042::m but instead it ran out of gas in the module 0000000000000000000000000000000000000000000000000000000000000042::m rooted here
 │ 
 │ 
 └──────────────────
@@ -33,12 +33,12 @@ Failures in 0x42::m:
 
 ┌── t2 ──────
 │ error[E11001]: test failure
-│    ┌─ out_of_gas.move:16:7
+│    ┌─ out_of_gas.move:16:5
 │    │
 │ 15 │ fun t2() {
 │    │     -- In this function in 0x42::m
 │ 16 │     0 - 1;
-│    │       ^ Test did not error as expected. Expected test to run out of gas in the module 0000000000000000000000000000000000000000000000000000000000000042::m but instead it gave an arithmetic error with error message: "Subtraction overflow". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000042::m rooted here
+│    │     ^^^^^ Test did not error as expected. Expected test to run out of gas in the module 0000000000000000000000000000000000000000000000000000000000000042::m but instead it gave an arithmetic error with error message: "Subtraction overflow". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000042::m rooted here
 │ 
 │ 
 └──────────────────
diff --git a/third_party/move/tools/move-unit-test/tests/test_sources/proposal_test.v2_exp b/third_party/move/tools/move-unit-test/tests/test_sources/proposal_test.v2_exp
index 2bfad174e6b53..7df933167ed6a 100644
--- a/third_party/move/tools/move-unit-test/tests/test_sources/proposal_test.v2_exp
+++ b/third_party/move/tools/move-unit-test/tests/test_sources/proposal_test.v2_exp
@@ -24,13 +24,19 @@ Failures in 0x1::Module:
 
 ┌── tests_d ──────
 │ error[E11001]: test failure
-│     ┌─ proposal_test.move:102:9
-│     │
-│  95 │     fun tests_d(a1: signer, a2: signer)
-│     │         ------- In this function in 0x1::Module
-│     ·
-│ 102 │         assert!(d<u64>(@0x2, 6), 3);
-│     │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it aborted with code 3 originating in the module 0000000000000000000000000000000000000000000000000000000000000001::Module rooted here
+│     ┌─ proposal_test.move:96:16
+│     │  
+│  95 │       fun tests_d(a1: signer, a2: signer)
+│     │           ------- In this function in 0x1::Module
+│  96 │       acquires B {
+│     │ ╭────────────────^
+│  97 │ │         setup_storage_tests_d(&a1, &a2);
+│  98 │ │         assert!(d<u64>(@0x1, 5), 0);
+│  99 │ │         assert!(!d<u64>(@0x1, 6), 1);
+│     · │
+│ 102 │ │         assert!(d<u64>(@0x2, 6), 3);
+│ 103 │ │     }
+│     │ ╰─────^ Test was not expected to error, but it aborted with code 3 originating in the module 0000000000000000000000000000000000000000000000000000000000000001::Module rooted here
 │ 
 │ 
 └──────────────────