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

Issue:
[Bug][compiler-v2] V2 crashes when using unassigned reference
# 🐛 Bug

```
//# publish
module 0xCAFE::Module0 {
    struct S has copy, drop {}
    public fun function0() {
        let y: &S;
        *y;
    }
}
```

This will cause compiler V2 to panic:
```
thread 'main' panicked at .../aptos-core/third_party/move/move-borrow-graph/src/graph.rs:61:44:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

V1 will give the expected error message `error[E06002]: use of unassigned variable`.


Discussion / hints:

Fix patch:
diff --git a/third_party/move/evm/move-to-yul/src/context.rs b/third_party/move/evm/move-to-yul/src/context.rs
index ec6590069a69c..ef8e251ee89e8 100644
--- a/third_party/move/evm/move-to-yul/src/context.rs
+++ b/third_party/move/evm/move-to-yul/src/context.rs
@@ -225,7 +225,7 @@ impl<'a> Context<'a> {
         pipeline.add_processor(ReachingDefProcessor::new());
         pipeline.add_processor(LiveVarAnalysisProcessor::new());
         if options.dump_bytecode {
-            pipeline.run_with_dump(env, &mut targets, &options.output, false, &|_| {})
+            pipeline.run_with_dump(env, &mut targets, &options.output, false, &|_| {}, || true)
         } else {
             pipeline.run(env, &mut targets);
         }
diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs
index 4ab79a7c10ea6..f1c9ab6ba0394 100644
--- a/third_party/move/move-compiler-v2/src/lib.rs
+++ b/third_party/move/move-compiler-v2/src/lib.rs
@@ -124,9 +124,10 @@ where
             &dump_base_name,
             false,
             &pipeline::register_formatters,
+            || !env.has_errors(),
         )
     } else {
-        pipeline.run(&env, &mut targets)
+        pipeline.run_with_hook(&env, &mut targets, |_| {}, |_, _, _| !env.has_errors())
     }
     check_errors(&env, error_writer, "stackless-bytecode analysis errors")?;
 
diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs
index 12eeb06bb2b24..d0ee90cab53c9 100644
--- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs
+++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs
@@ -16,6 +16,8 @@
 //! in the stack machine they are put on the stack in independent instructions.
 //! Another difference is the need for generating good error messages which
 //! the bytecode verifier has not.
+//!
+//! Prerequisites: there are no uninitialized locals.
 
 use crate::pipeline::{
     livevar_analysis_processor::{LiveVarAnnotation, LiveVarInfoAtCodeOffset},
diff --git a/third_party/move/move-model/bytecode/src/function_target_pipeline.rs b/third_party/move/move-model/bytecode/src/function_target_pipeline.rs
index 1d64445e299b7..6834b82844cb3 100644
--- a/third_party/move/move-model/bytecode/src/function_target_pipeline.rs
+++ b/third_party/move/move-model/bytecode/src/function_target_pipeline.rs
@@ -411,6 +411,7 @@ impl FunctionTargetPipeline {
     /// preceding it in the pipeline have been executed for all functions before it is called.
     /// `hook_before_pipeline` is called before the pipeline is run, and `hook_after_each_processor`
     /// is called after each processor in the pipeline has been run on all functions.
+    /// If `hook_after_each_processor` returns false, the pipeline is stopped.
     /// Note that `hook_after_each_processor` is called with index starting at 1.
     pub fn run_with_hook<Before, AfterEach>(
         &self,
@@ -420,7 +421,7 @@ impl FunctionTargetPipeline {
         hook_after_each_processor: AfterEach,
     ) where
         Before: Fn(&FunctionTargetsHolder),
-        AfterEach: Fn(usize, &dyn FunctionTargetProcessor, &FunctionTargetsHolder),
+        AfterEach: Fn(usize, &dyn FunctionTargetProcessor, &FunctionTargetsHolder) -> bool,
     {
         let rev_topo_order = Self::sort_in_reverse_topological_order(env, targets);
         info!("transforming bytecode");
@@ -463,18 +464,21 @@ impl FunctionTargetPipeline {
                 }
                 processor.finalize(env, targets);
             }
-            hook_after_each_processor(step_count + 1, processor.as_ref(), targets);
+            if !hook_after_each_processor(step_count + 1, processor.as_ref(), targets) {
+                break;
+            }
         }
     }
 
     /// Run the pipeline on all functions in the targets holder, with no hooks in effect
     pub fn run(&self, env: &GlobalEnv, targets: &mut FunctionTargetsHolder) {
-        self.run_with_hook(env, targets, |_| {}, |_, _, _| {})
+        self.run_with_hook(env, targets, |_| {}, |_, _, _| true)
     }
 
     /// Runs the pipeline on all functions in the targets holder, and dump the bytecode via `log` before the
     /// pipeline as well as after each processor pass, identifying it by `dump_base_name`. If `dump_cfg` is set,
     /// dump the per-function control-flow graph (in dot format) to a file, using the given base name.
+    /// `continue_to_next_processor` determines whether the pipeline should continue to the next processor.
     pub fn run_with_dump(
         &self,
         env: &GlobalEnv,
@@ -482,6 +486,7 @@ impl FunctionTargetPipeline {
         dump_base_name: &str,
         dump_cfg: bool,
         register_annotations: &impl Fn(&FunctionTarget),
+        continue_to_next_processor: impl Fn() -> bool,
     ) {
         self.run_with_hook(
             env,
@@ -511,6 +516,7 @@ impl FunctionTargetPipeline {
                 if dump_cfg {
                     Self::dump_cfg(env, holders, dump_base_name, step_count, &suffix);
                 }
+                continue_to_next_processor()
             },
         );
     }
diff --git a/third_party/move/move-prover/src/lib.rs b/third_party/move/move-prover/src/lib.rs
index bb658d06f5711..d029e05e1767e 100644
--- a/third_party/move/move-prover/src/lib.rs
+++ b/third_party/move/move-prover/src/lib.rs
@@ -319,6 +319,7 @@ pub fn create_and_process_bytecode(options: &Options, env: &GlobalEnv) -> Functi
             &dump_file_base,
             options.prover.dump_cfg,
             &|_| {},
+            || true,
         )
     } else {
         pipeline.run(env, &mut targets);


Test patch:
diff --git a/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/diamond_clicker.v2_exp b/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/diamond_clicker.v2_exp
index 53f845c17f340..e454cf5a17b59 100644
--- a/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/diamond_clicker.v2_exp
+++ b/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/diamond_clicker.v2_exp
@@ -33,26 +33,26 @@ B0:
 	9: MutBorrowField[0](OuterStruct.any_field: vector<InnerStruct>)
 	10: StLoc[2](loc1: &mut vector<InnerStruct>)
 	11: LdU64(0)
-	12: StLoc[3](loc2: u64)
-	13: CopyLoc[2](loc1: &mut vector<InnerStruct>)
-	14: FreezeRef
-	15: VecLen(3)
+	12: CopyLoc[2](loc1: &mut vector<InnerStruct>)
+	13: FreezeRef
+	14: VecLen(3)
+	15: StLoc[3](loc2: u64)
 	16: StLoc[4](loc3: u64)
 B1:
-	17: CopyLoc[3](loc2: u64)
-	18: CopyLoc[4](loc3: u64)
+	17: CopyLoc[4](loc3: u64)
+	18: CopyLoc[3](loc2: u64)
 	19: Lt
 	20: BrFalse(31)
 B2:
 	21: CopyLoc[2](loc1: &mut vector<InnerStruct>)
-	22: CopyLoc[3](loc2: u64)
+	22: CopyLoc[4](loc3: u64)
 	23: VecMutBorrow(3)
 	24: FreezeRef
 	25: Call debug::print<InnerStruct>(&InnerStruct)
-	26: MoveLoc[3](loc2: u64)
+	26: MoveLoc[4](loc3: u64)
 	27: LdU64(1)
 	28: Add
-	29: StLoc[3](loc2: u64)
+	29: StLoc[4](loc3: u64)
 	30: Branch(34)
 B3:
 	31: MoveLoc[2](loc1: &mut vector<InnerStruct>)
diff --git a/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/table.v2_exp b/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/table.v2_exp
index d313008fc3358..b0352e4c59288 100644
--- a/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/table.v2_exp
+++ b/aptos-move/aptos-transactional-test-harness/tests/aptos_test_harness/table.v2_exp
@@ -52,7 +52,7 @@ Events:
 }
 {
     type:    0x1::transaction_fee::FeeStatement
-    data:    "9c0000000000000006000000000000000400000000000000c83a0200000000000000000000000000"
+    data:    "9c0000000000000007000000000000000400000000000000c83a0200000000000000000000000000"
 }mutable inputs after call: local#0: 0
 return values: 0
 
diff --git a/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/no_drop.exp b/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/no_drop.exp
new file mode 100644
index 0000000000000..87e25ce461590
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/no_drop.exp
@@ -0,0 +1,7 @@
+
+Diagnostics:
+error: local `x` of type `M::X` does not have the `drop` ability
+  ┌─ tests/ability-check/v1-borrow-tests/no_drop.move:6:9
+  │
+6 │         &x;
+  │         ^^ implicitly dropped here since it is no longer used
diff --git a/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/no_drop.move b/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/no_drop.move
new file mode 100644
index 0000000000000..bc28a8c7b0552
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/no_drop.move
@@ -0,0 +1,9 @@
+module 0x8675309::M {
+    struct X {}
+
+    fun t1(): bool {
+        let x = X {};
+        &x;
+        false
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/return_type_mismatch_and_unused_resource.exp b/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/return_type_mismatch_and_unused_resource.exp
index eb36f9c044dd4..7a1abffff1613 100644
--- a/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/return_type_mismatch_and_unused_resource.exp
+++ b/third_party/move/move-compiler-v2/tests/ability-check/v1-borrow-tests/return_type_mismatch_and_unused_resource.exp
@@ -7,11 +7,3 @@ error: cannot return a reference derived from value since it is not based on a p
    │                 -- value previously borrowed here
 13 │         r
    │         ^ return attempted here
-
-
-Diagnostics:
-error: local `x` of type `M::X` does not have the `drop` ability
-  ┌─ tests/ability-check/v1-borrow-tests/return_type_mismatch_and_unused_resource.move:6:9
-  │
-6 │         &x;
-  │         ^^ implicitly dropped here since it is no longer used
diff --git a/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_2.exp b/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_2.exp
index 2534345a02a1a..ef9bd20a5bed4 100644
--- a/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_2.exp
+++ b/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_2.exp
@@ -43,27 +43,3 @@ error: local `q` of type `m::S` does not have the `drop` ability
    │
 13 │         q.a
    │         ^ still borrowed but will be implicitly dropped later since it is no longer used
-
-============ after DeadStoreElimination: ================
-
-[variant baseline]
-fun m::test($t0: m::S): u64 {
-     var $t1: u64
-     var $t2: m::S
-     var $t3: m::S
-     var $t4: &mut u64
-     var $t5: &mut m::S
-     var $t6: u64
-     var $t7: &m::S
-     var $t8: &u64
-  0: $t2 := move($t0)
-  1: $t3 := copy($t2)
-  2: $t5 := borrow_local($t2)
-  3: $t4 := borrow_field<m::S>.a($t5)
-  4: $t6 := 0
-  5: write_ref($t4, $t6)
-  6: $t7 := borrow_local($t3)
-  7: $t8 := borrow_field<m::S>.a($t7)
-  8: $t1 := read_ref($t8)
-  9: return $t1
-}
diff --git a/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_3.exp b/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_3.exp
index dc4dae34c2cc5..6f746d4619b86 100644
--- a/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_3.exp
+++ b/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_3.exp
@@ -28,21 +28,3 @@ error: cannot write local `a` since it is borrowed
   │         ^^^^^^ write attempted here
 8 │         *c
   │         -- conflicting reference `c` used here
-
-============ after DeadStoreElimination: ================
-
-[variant baseline]
-fun m::test($t0: u64): u64 {
-     var $t1: u64
-     var $t2: &mut u64
-     var $t3: &mut u64
-     var $t4: &mut u64
-     var $t5: u64
-  0: $t2 := borrow_local($t0)
-  1: $t3 := copy($t2)
-  2: $t4 := move($t3)
-  3: $t5 := 0
-  4: write_ref($t2, $t5)
-  5: $t1 := read_ref($t4)
-  6: return $t1
-}
diff --git a/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_4.exp b/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_4.exp
index 1ca41be3dc1c9..688e83bfd2678 100644
--- a/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_4.exp
+++ b/third_party/move/move-compiler-v2/tests/copy-propagation/mut_refs_4.exp
@@ -30,23 +30,3 @@ error: cannot copy local `p` which is still mutably borrowed
   ·
 8 │         *a = 0;
   │         ------ conflicting reference `a` used here
-
-============ after DeadStoreElimination: ================
-
-[variant baseline]
-fun m::test($t0: u64): u64 {
-     var $t1: u64
-     var $t2: &mut u64
-     var $t3: u64
-     var $t4: u64
-     var $t5: u64
-     var $t6: u64
-  0: $t2 := borrow_local($t0)
-  1: $t3 := copy($t0)
-  2: $t4 := move($t3)
-  3: $t5 := move($t4)
-  4: $t6 := 0
-  5: write_ref($t2, $t6)
-  6: $t1 := move($t5)
-  7: return $t1
-}
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.exp b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.exp
new file mode 100644
index 0000000000000..21877660b76a6
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.exp
@@ -0,0 +1,7 @@
+
+Diagnostics:
+error: use of unassigned local `y`
+  ┌─ tests/reference-safety/unused_reference.move:6:9
+  │
+6 │         *y;
+  │         ^^
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.move b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.move
new file mode 100644
index 0000000000000..f3792a838dba4
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.move
@@ -0,0 +1,8 @@
+module 0xCAFE::Module0 {
+    struct S has copy, drop {f:u64}
+
+    public fun function0() {
+        let y: &S;
+        *y;
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.no-opt.exp
new file mode 100644
index 0000000000000..21877660b76a6
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.no-opt.exp
@@ -0,0 +1,7 @@
+
+Diagnostics:
+error: use of unassigned local `y`
+  ┌─ tests/reference-safety/unused_reference.move:6:9
+  │
+6 │         *y;
+  │         ^^
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.old.exp b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.old.exp
new file mode 100644
index 0000000000000..21877660b76a6
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/unused_reference.old.exp
@@ -0,0 +1,7 @@
+
+Diagnostics:
+error: use of unassigned local `y`
+  ┌─ tests/reference-safety/unused_reference.move:6:9
+  │
+6 │         *y;
+  │         ^^
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.exp
index 37a74ecfc0011..d32f03178117f 100644
--- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.exp
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.exp
@@ -19,11 +19,3 @@ error: cannot drop local `s` which is still borrowed
    │         ^^^^^^^^^^^^^^ dropped here
 17 │         z;
    │         - conflicting reference `z` used here
-
-
-Diagnostics:
-error: local `x` of type `M::X` does not have the `drop` ability
-  ┌─ tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.move:6:17
-  │
-6 │         let y = &x;
-  │                 ^^ still borrowed but will be implicitly dropped later since it is no longer used
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.no-opt.exp
index 37a74ecfc0011..d32f03178117f 100644
--- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.no-opt.exp
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.no-opt.exp
@@ -19,11 +19,3 @@ error: cannot drop local `s` which is still borrowed
    │         ^^^^^^^^^^^^^^ dropped here
 17 │         z;
    │         - conflicting reference `z` used here
-
-
-Diagnostics:
-error: local `x` of type `M::X` does not have the `drop` ability
-  ┌─ tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.move:6:17
-  │
-6 │         let y = &x;
-  │                 ^^ still borrowed but will be implicitly dropped later since it is no longer used
diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.old.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.old.exp
index 413b51c37ece9..68caf07c83ec2 100644
--- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.old.exp
+++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.old.exp
@@ -21,11 +21,3 @@ error: cannot assign to borrowed local `s`
    │         ^^^^^^^^^^^^^^ attempted to assign here
 17 │         z;
    │         - conflicting reference `z` used here
-
-
-Diagnostics:
-error: local `x` of type `M::X` does not have the `drop` ability
-  ┌─ tests/reference-safety/v1-borrow-tests/mutate_with_borrowed_loc_struct_invalid.move:6:17
-  │
-6 │         let y = &x;
-  │                 ^^ still borrowed but will be implicitly dropped later since it is no longer used
diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign.exp
index f10a3cdb4ab96..ac63e9d86f699 100644
--- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign.exp
+++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign.exp
@@ -26,11 +26,3 @@ error: use of unassigned local `x`
   │
 4 │     let y = x;
   │             ^
-
-
-Diagnostics:
-warning: Unused assignment to `y`. Consider removing or prefixing with an underscore: `_y`
-  ┌─ tests/simplifier-elimination/use_before_assign.move:4:13
-  │
-4 │     let y = x;
-  │             ^
diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign_while.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign_while.exp
index 3f769d77944f3..2152707901fdc 100644
--- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign_while.exp
+++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/use_before_assign_while.exp
@@ -103,22 +103,3 @@ error: use of unassigned local `x`
    │
 19 │         while (cond) { let y = &x; _ = move y; if (cond) { x = 0 }; break }
    │                                ^^
-
-
-Diagnostics:
-warning: Unused assignment to `x`. Consider removing or prefixing with an underscore: `_x`
-   ┌─ tests/simplifier-elimination/use_before_assign_while.move:19:60
-   │
-19 │         while (cond) { let y = &x; _ = move y; if (cond) { x = 0 }; break }
-   │                                                            ^^^^^
-
-
-Diagnostics:
-error: cannot move local `x` since it is still in use
-  ┌─ tests/simplifier-elimination/use_before_assign_while.move:9:32
-  │
-9 │         while (cond) { let y = move x + 1; if (cond) { continue }; x = 0; y; }
-  │                                ^^^^^^
-  │                                │
-  │                                attempted to move here
-  │                                used here
diff --git a/third_party/move/move-compiler-v2/tests/testsuite.rs b/third_party/move/move-compiler-v2/tests/testsuite.rs
index 3318472c84329..911c2aa1c8fc7 100644
--- a/third_party/move/move-compiler-v2/tests/testsuite.rs
+++ b/third_party/move/move-compiler-v2/tests/testsuite.rs
@@ -745,7 +745,7 @@ fn run_test(path: &Path, config: TestConfig) -> datatest_stable::Result<()> {
         }
     }
 
-    if options.compile_test_code {
+    if ok && options.compile_test_code {
         // Build the test plan here to parse and validate any test-related attributes in the AST.
         // In real use, this is run outside of the compilation process, but the needed info is
         // available in `env` once we finish the AST.
@@ -810,6 +810,7 @@ fn run_test(path: &Path, config: TestConfig) -> datatest_stable::Result<()> {
                         out.push_str(dump);
                         debug!("{}", dump);
                     }
+                    *ok.borrow()
                 },
             );
             if *ok.borrow() && config.stop_after == StopAfter::FileFormat {
diff --git a/third_party/move/move-compiler-v2/tests/uninit-use-checker/unused_reference.exp b/third_party/move/move-compiler-v2/tests/uninit-use-checker/unused_reference.exp
new file mode 100644
index 0000000000000..1749474d122c6
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/uninit-use-checker/unused_reference.exp
@@ -0,0 +1,29 @@
+============ initial bytecode ================
+
+[variant baseline]
+public fun Module0::function0() {
+     var $t0: &Module0::S
+     var $t1: Module0::S
+  0: $t1 := read_ref($t0)
+  1: return ()
+}
+
+
+Diagnostics:
+error: use of unassigned local `y`
+  ┌─ tests/uninit-use-checker/unused_reference.move:6:9
+  │
+6 │         *y;
+  │         ^^
+
+============ after uninitialized_use_checker: ================
+
+[variant baseline]
+public fun Module0::function0() {
+     var $t0: &Module0::S
+     var $t1: Module0::S
+     # before: { no: $t0, $t1 }, after: { no: $t0 }
+  0: $t1 := read_ref($t0)
+     # before: { no: $t0 }, after: { no: $t0 }
+  1: return ()
+}
diff --git a/third_party/move/move-compiler-v2/tests/uninit-use-checker/unused_reference.move b/third_party/move/move-compiler-v2/tests/uninit-use-checker/unused_reference.move
new file mode 100644
index 0000000000000..f3792a838dba4
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/uninit-use-checker/unused_reference.move
@@ -0,0 +1,8 @@
+module 0xCAFE::Module0 {
+    struct S has copy, drop {f:u64}
+
+    public fun function0() {
+        let y: &S;
+        *y;
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/attribute_location_invalid.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/attribute_location_invalid.exp
index 5274e15e01d45..2cc71f4441246 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/attribute_location_invalid.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/attribute_location_invalid.exp
@@ -23,6 +23,3 @@ error: invalid attribute
    │       │
    │       Attribute 'expected_failure' is not expected with a struct
    │       Expected to be used with one of the following: function
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/expected_failure_on_non_function.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/expected_failure_on_non_function.exp
index f7cc205b801eb..d4af8c6017545 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/expected_failure_on_non_function.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/expected_failure_on_non_function.exp
@@ -26,6 +26,3 @@ error: invalid attribute
   │       │
   │       Attribute 'expected_failure' is not expected with a constant
   │       Expected to be used with one of the following: function
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/extra_attributes2.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/extra_attributes2.exp
index 5b54c1868ee88..46fae5f7ace9b 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/extra_attributes2.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/extra_attributes2.exp
@@ -23,6 +23,3 @@ error: invalid attribute
    │
 21 │     #[expected_failure(verify_only)]
    │                        ^^^^^^^^^^^ Attribute 'verify_only' is not expected in a nested attribute position
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/function_with_spec.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/function_with_spec.exp
index fbcda8c812a5b..89074ae09c81b 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/function_with_spec.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/function_with_spec.exp
@@ -5,6 +5,3 @@ error: unresolved spec target
    │
 18 │     spec baz {
    │          ^^^
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_errors.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_errors.exp
index e0e1ead22c5a4..9fa6a051dc11f 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_errors.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_errors.exp
@@ -15,6 +15,3 @@ error: duplicate declaration, item, or annotation
    │       ---------------- Attribute previously given here
 42 │     #[expected_failure]
    │       ^^^^^^^^^^^^^^^^ Duplicate attribute 'expected_failure' attached to the same item
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_test_annotations.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_test_annotations.exp
index 1a805c89ac217..bea66cf6a56ed 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_test_annotations.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/multiple_test_annotations.exp
@@ -15,6 +15,3 @@ error: duplicate declaration, item, or annotation
    │       ---- Attribute previously given here
 10 │     #[test(_a=@0x1, _b=@0x2)]
    │       ^^^^^^^^^^^^^^^^^^^^^^ Duplicate attribute 'test' attached to the same item
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/named_address_no_value_in_annotation.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/named_address_no_value_in_annotation.exp
index ab78f3fd1e90a..ecf5c7f153fe3 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/named_address_no_value_in_annotation.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/named_address_no_value_in_annotation.exp
@@ -5,6 +5,3 @@ error: address with no value
   │
 2 │     #[test(_a = @UnboundAddr)]
   │                  ^^^^^^^^^^^ address 'UnboundAddr' is not assigned a value. Try assigning it a value when calling the compiler
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/other_failures_invalid_location_module.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/other_failures_invalid_location_module.exp
index 046b901892b81..dda6ecfe8a0f9 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/other_failures_invalid_location_module.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/other_failures_invalid_location_module.exp
@@ -5,6 +5,3 @@ error: unbound module
   │
 6 │     #[expected_failure(arithmetic_error, location=0x2::m)]
   │                                                   ^^^^^^ Unbound module '0x2::m'
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_on_main.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_on_main.exp
index 65e21248fb351..c6cbbb5ba6b51 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_on_main.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_on_main.exp
@@ -17,6 +17,3 @@ error: unable to generate test
   │
 5 │     #[test_only, test]
   │                  ^^^^ Testing attributes are not allowed in scripts.
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_top_level.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_top_level.exp
index bfec7ddde7714..5b6d53c60b399 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_top_level.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_multiple_top_level.exp
@@ -17,6 +17,3 @@ error: unable to generate test
   │
 4 │ #[test_only]
   │   ^^^^^^^^^ Testing attributes are not allowed in scripts.
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_on_main.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_on_main.exp
index d9e89f22c5b73..208a107511fd8 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_on_main.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_on_main.exp
@@ -5,6 +5,3 @@ error: unable to generate test
   │
 3 │     #[test]
   │       ^^^^ Testing attributes are not allowed in scripts.
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_top_level.exp b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_top_level.exp
index db272858f3cb6..6b95e44326f11 100644
--- a/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_top_level.exp
+++ b/third_party/move/move-compiler-v2/tests/unit_test/test/script_with_test_top_level.exp
@@ -5,6 +5,3 @@ error: unable to generate test
   │
 2 │ #[test_only]
   │   ^^^^^^^^^ Testing attributes are not allowed in scripts.
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/unused-assignment/v1-locals/struct_use_before_assign.exp b/third_party/move/move-compiler-v2/tests/unused-assignment/v1-locals/struct_use_before_assign.exp
index e8dbffafd0ea6..62ba0940bc159 100644
--- a/third_party/move/move-compiler-v2/tests/unused-assignment/v1-locals/struct_use_before_assign.exp
+++ b/third_party/move/move-compiler-v2/tests/unused-assignment/v1-locals/struct_use_before_assign.exp
@@ -79,53 +79,3 @@ error: use of unassigned local `x`
    │
 31 │         let q = x;
    │                 ^
-
-
-Diagnostics:
-warning: Unused assignment to `z`. Consider removing or prefixing with an underscore: `_z`
-  ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:8:17
-  │
-8 │         let z = y;
-  │                 ^
-
-warning: Unused assignment to `q`. Consider removing or prefixing with an underscore: `_q`
-  ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:9:17
-  │
-9 │         let q = x;
-  │                 ^
-
-warning: Unused assignment to `z`. Consider removing or prefixing with an underscore: `_z`
-   ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:17:17
-   │
-17 │         let z = y;
-   │                 ^
-
-warning: Unused assignment to `q`. Consider removing or prefixing with an underscore: `_q`
-   ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:18:17
-   │
-18 │         let q = x;
-   │                 ^
-
-warning: Unused assignment to `z`. Consider removing or prefixing with an underscore: `_z`
-   ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:24:17
-   │
-24 │         let z = y;
-   │                 ^
-
-warning: Unused assignment to `q`. Consider removing or prefixing with an underscore: `_q`
-   ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:25:17
-   │
-25 │         let q = x;
-   │                 ^
-
-warning: Unused assignment to `z`. Consider removing or prefixing with an underscore: `_z`
-   ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:30:17
-   │
-30 │         let z = y;
-   │                 ^
-
-warning: Unused assignment to `q`. Consider removing or prefixing with an underscore: `_q`
-   ┌─ tests/unused-assignment/v1-locals/struct_use_before_assign.move:31:17
-   │
-31 │         let q = x;
-   │                 ^
diff --git a/third_party/move/move-compiler-v2/tests/verification/verify/double_annotation.exp b/third_party/move/move-compiler-v2/tests/verification/verify/double_annotation.exp
index fbc781f959cb2..54358a045dfe6 100644
--- a/third_party/move/move-compiler-v2/tests/verification/verify/double_annotation.exp
+++ b/third_party/move/move-compiler-v2/tests/verification/verify/double_annotation.exp
@@ -15,6 +15,3 @@ error: duplicate declaration, item, or annotation
    │       ----------- Attribute previously given here
 18 │     #[verify_only]
    │       ^^^^^^^^^^^ Duplicate attribute 'verify_only' attached to the same item
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/verification/verify/function_with_spec.exp b/third_party/move/move-compiler-v2/tests/verification/verify/function_with_spec.exp
index 47f7a09cccdad..dae7653001606 100644
--- a/third_party/move/move-compiler-v2/tests/verification/verify/function_with_spec.exp
+++ b/third_party/move/move-compiler-v2/tests/verification/verify/function_with_spec.exp
@@ -5,6 +5,3 @@ error: unresolved spec target
    │
 15 │     spec baz {
    │          ^^^
-
-
-============ bytecode verification succeeded ========
diff --git a/third_party/move/move-model/tests/sources/structs_err.v2_exp b/third_party/move/move-model/tests/sources/structs_err.v2_exp
index 9829b115f35e8..44e351196c26a 100644
--- a/third_party/move/move-model/tests/sources/structs_err.v2_exp
+++ b/third_party/move/move-model/tests/sources/structs_err.v2_exp
@@ -22,11 +22,11 @@ error: missing fields `y`, `z`
 40 │       S{x: x}
    │       ^^^^^^^
 
-error: cannot return `G<u64>` from a function with result type `G<bool>`
-   ┌─ tests/sources/structs_err.move:45:7
+error: expected `bool` but found a value of type `u64`
+   ┌─ tests/sources/structs_err.move:45:12
    │
 45 │       G{x: x, y: y}
-   │       ^^^^^^^^^^^^^
+   │            ^
 
 error: expected 1 type argument but 2 were provided
    ┌─ tests/sources/structs_err.move:50:7