]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Subset errors with locations
authorKushal Pal <kushalpal109@gmail.com>
Fri, 26 Jul 2024 07:40:58 +0000 (07:40 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Wed, 19 Mar 2025 14:32:03 +0000 (15:32 +0100)
gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
(BorrowCheckerDiagnostics::report_subset_errors): Highlight
lifetime locations while reporting subset errors.
(BorrowCheckerDiagnostics::get_lifetime_param): Helper function
to fetch HIR::Lifetime node from Polonius::Origin.
* checks/errors/borrowck/rust-borrow-checker-diagnostics.h:
Definition of helper function.

gcc/testsuite/ChangeLog:

* rust/borrowck/subset.rs: Better subset errors.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
gcc/testsuite/rust/borrowck/subset.rs

index 0365dc3bd6fe213cc6dab13fbd0351ab8d33b6c4..dc010291073d26c9763e83b0ae27ad49dd38c366 100644 (file)
@@ -61,12 +61,38 @@ BorrowCheckerDiagnostics::report_loan_errors ()
 void
 BorrowCheckerDiagnostics::report_subset_errors ()
 {
-  if (!subset_errors.empty ())
+  // remove duplicates in subset_errors
+  //
+  // Polonius may output subset errors for same 2 origins at multiple points
+  // so to avoid duplicating the errors, we can remove the elements in subset
+  // errors with same origin pair
+  std::vector<std::pair<size_t, std::pair<size_t, size_t>>>
+    deduplicated_subset_errors;
+
+  for (auto pair : subset_errors)
     {
-      rust_error_at (hir_function->get_locus (),
-                    "Found subset errors in function %s. Some lifetime "
-                    "constraints need to be added.",
-                    hir_function->get_function_name ().as_string ().c_str ());
+      auto it = std::find_if (
+       deduplicated_subset_errors.begin (), deduplicated_subset_errors.end (),
+       [&pair] (std::pair<size_t, std::pair<size_t, size_t>> element) {
+         return element.second == pair.second;
+       });
+      if (it == deduplicated_subset_errors.end ())
+       {
+         deduplicated_subset_errors.push_back (pair);
+       }
+    }
+  for (const auto &error : deduplicated_subset_errors)
+    {
+      auto first_lifetime_location
+       = get_lifetime_param (error.second.first)->get_locus ();
+      auto second_lifetime_location
+       = get_lifetime_param (error.second.second)->get_locus ();
+      multi_label_error (
+       "subset error, some lifetime constraints need to be added",
+       bir_function.location,
+       {{"lifetime defined here", first_lifetime_location},
+        {"lifetime defined here", second_lifetime_location},
+        {"subset error occurs in this function", bir_function.location}});
     }
 }
 
@@ -88,6 +114,13 @@ BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan)
   return bir_function.place_db.get_loans ()[loan];
 }
 
+const HIR::LifetimeParam *
+BorrowCheckerDiagnostics::get_lifetime_param (Polonius::Origin origin)
+
+{
+  return bir_function.region_hir_map.at (origin);
+}
+
 void
 BorrowCheckerDiagnostics::multi_label_error (
   const char *error_message, location_t error_location,
index 136f467907512664031a60b9dc6b139e4e82f736..9ab059152d72c0b7277f759b998438f46fd9c288 100644 (file)
@@ -66,6 +66,7 @@ private:
 
   const BIR::Statement &get_statement (Polonius::Point point);
   const BIR::Loan &get_loan (Polonius::Loan loan);
+  const HIR::LifetimeParam *get_lifetime_param (Polonius::Origin origin);
 
   struct LabelLocationPair
   {
index d7c00ca966c151ad2b9c54aa28fa1f81eb063831..5b4a663a0c3d796ba197bcce74b5894e6e9bfd9a 100644 (file)
@@ -1,8 +1,19 @@
-// { 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 missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
-    // { dg-error "Found subset errors in function missing_subset" "" { target *-*-* } .-1 }
+    // { dg-error "subset error, some lifetime constraints need to be added" "" { target *-*-* } .-1 }
     y //~ ERROR
+    /*
+     { dg-begin-multiline-output "" }
+   NN | fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
+      | ^~                ~~  ~~
+      | |                 |   |
+      | |                 |   lifetime defined here
+      | |                 lifetime defined here
+      | subset error occurs in this function
+     { dg-end-multiline-output "" }
+    */
 }
 
 fn missing_subset_fixed<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 where 'b: 'a {
@@ -10,12 +21,22 @@ fn missing_subset_fixed<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 where 'b: 'a
 }
 
 fn complex_cfg_subset<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 {
-    // { dg-error "Found subset errors in function complex_cfg_subset" "" { target *-*-* } .-1 }
+    // { dg-error "subset error, some lifetime constraints need to be added" "" { target *-*-* } .-1 }
     if b {
         y //~ ERROR
     } else {
         x
     }
+    /*
+     { dg-begin-multiline-output "" }
+   NN | fn complex_cfg_subset<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 {
+      | ^~                    ~~  ~~
+      | |                     |   |
+      | |                     |   lifetime defined here
+      | |                     lifetime defined here
+      | subset error occurs in this function
+     { dg-end-multiline-output "" }
+    */
 }
 
 fn complex_cfg_subset_fixed<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 where 'b: 'a {
@@ -24,4 +45,4 @@ fn complex_cfg_subset_fixed<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32
     } else {
         y
     }
-}
\ No newline at end of file
+}