https://gcc.gnu.org/g:e61d37aae9a47461370cbd3c49123eba6fb64dc9

commit e61d37aae9a47461370cbd3c49123eba6fb64dc9
Author: Kushal Pal <kushalpal...@gmail.com>
Date:   Mon Aug 12 05:48:27 2024 +0000

    Move errors with locations
    
    gcc/rust/ChangeLog:
    
            * checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
            (BorrowCheckerDiagnostics::report_move_errors): Specify
            locations for code causing errors and related moves.
    
    gcc/testsuite/ChangeLog:
    
            * rust/borrowck/test_move.rs: Test rich-errors related to moves.
            * rust/borrowck/test_move_conditional.rs: Likewise.
    
    Signed-off-by: Kushal Pal <kushalpal...@gmail.com>

Diff:
---
 .../borrowck/rust-borrow-checker-diagnostics.cc    | 39 +++++++++++++++++--
 gcc/testsuite/rust/borrowck/test_move.rs           | 22 +++++++++--
 .../rust/borrowck/test_move_conditional.rs         | 45 ++++++++++++++++++++--
 3 files changed, 96 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc 
b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
index dc010291073d..f2e4c38cfa0f 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
@@ -34,11 +34,42 @@ BorrowCheckerDiagnostics::report_errors ()
 void
 BorrowCheckerDiagnostics::report_move_errors ()
 {
-  if (!move_errors.empty ())
+  for (const auto &pair : move_errors)
     {
-      rust_error_at (hir_function->get_locus (),
-                    "Found move errors in function %s",
-                    hir_function->get_function_name ().as_string ().c_str ());
+      auto error_location = get_statement (pair.first).get_location ();
+
+      // in future, we can use the assigned at location to hint the
+      // user to implement copy trait for the type
+      /*
+      for (auto it : facts.path_assigned_at_base)
+       {
+         if (pair.second[0] == it.first)
+           {
+             auto point_assigned_at = it.second;
+             auto assigned_at_location
+               = get_statement (point_assigned_at).get_location ();
+           }
+       }
+       */
+
+      std::vector<LabelLocationPair> labels{
+       {"moved value used here", error_location}};
+      // add labels to all the moves for the given path
+      for (auto it : facts.path_moved_at_base)
+       {
+         if (pair.second[0] == it.first)
+           {
+             auto point_moved_at = it.second;
+             // don't label the move location where the error occured
+             if (pair.first != point_moved_at)
+               {
+                 auto move_at_location
+                   = get_statement (point_moved_at).get_location ();
+                 labels.push_back ({"value moved here", move_at_location});
+               }
+           }
+       }
+      multi_label_error ("use of moved value", error_location, labels);
     }
 }
 
diff --git a/gcc/testsuite/rust/borrowck/test_move.rs 
b/gcc/testsuite/rust/borrowck/test_move.rs
index 26a1a5b7bdec..b6475839c04a 100644
--- a/gcc/testsuite/rust/borrowck/test_move.rs
+++ b/gcc/testsuite/rust/borrowck/test_move.rs
@@ -1,11 +1,27 @@
-// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck" }
-fn test_move() { // { dg-error "Found move errors in function test_move" }
+// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
+// { dg-enable-nn-line-numbers "" }
+
+fn test_move() {
     struct A {
         i: i32,
     }
     let a = A { i: 1 };
     let b = a;
-    let c = a;
+    let c = a; //~ ERROR
+    // { dg-error "use of moved value" "" { target *-*-* } .-1 }
+    /*
+     { dg-begin-multiline-output "" }
+   NN |     let b = a;
+      |             ~
+      |             |
+      |             value moved here
+   NN |     let c = a; //~ ERROR
+      |             ^
+      |             |
+      |             moved value used here
+     { dg-end-multiline-output "" }
+     */
+    
 }
 
 fn test_move_fixed() {
diff --git a/gcc/testsuite/rust/borrowck/test_move_conditional.rs 
b/gcc/testsuite/rust/borrowck/test_move_conditional.rs
index e1e8e2025cf1..94882bca5a77 100644
--- a/gcc/testsuite/rust/borrowck/test_move_conditional.rs
+++ b/gcc/testsuite/rust/borrowck/test_move_conditional.rs
@@ -1,6 +1,7 @@
-// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck" }
+// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
+// { dg-enable-nn-line-numbers "" }
 
-fn test_move_conditional(b1: bool, b2:bool) { // { dg-error "Found move errors 
in function test_move" }
+fn test_move_conditional(b1: bool, b2:bool) {
     struct A {
         i: i32,
     }
@@ -9,9 +10,47 @@ fn test_move_conditional(b1: bool, b2:bool) { // { dg-error 
"Found move errors i
     let b = a;
     if b1 {
         let b = a;
+        // { dg-error "use of moved value" "" { target *-*-* } .-1 }
+    /*
+     { dg-begin-multiline-output "" }
+   NN |     let b = a;
+      |             ~    
+      |             |
+      |             value moved here
+   NN |     if b1 {
+   NN |         let b = a;
+      |                 ~
+      |                 |
+      |                 value moved here
+......
+   NN |         let c = a;
+      |                 ^
+      |                 |
+      |                 moved value used here
+     { dg-end-multiline-output "" }
+     */
     }
     if b2 {
         let c = a;
+        // { dg-error "use of moved value" "" { target *-*-* } .-1 }
+    /*
+     { dg-begin-multiline-output "" }
+   NN |     let b = a;
+      |             ~    
+      |             |
+      |             value moved here
+   NN |     if b1 {
+   NN |         let b = a;
+      |                 ^
+      |                 |
+      |                 moved value used here
+......
+   NN |         let c = a;
+      |                 ~
+      |                 |
+      |                 value moved here
+     { dg-end-multiline-output "" }
+     */
     }
 }
 
@@ -25,4 +64,4 @@ fn test_move_fixed(b1: bool, b2:bool) {
     if b2 {
         let c = a;
     }
-}
\ No newline at end of file
+}

Reply via email to