[COMMITTED 024/144] gccrs: Subset errors with locations

arthur.cohen@embecosm.com arthur.cohen@embecosm.com
Wed Mar 19 14:43:05 GMT 2025


From: Kushal Pal <kushalpal109@gmail.com>

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>
---
 .../rust-borrow-checker-diagnostics.cc        | 43 ++++++++++++++++---
 .../rust-borrow-checker-diagnostics.h         |  1 +
 gcc/testsuite/rust/borrowck/subset.rs         | 29 +++++++++++--
 3 files changed, 64 insertions(+), 9 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 0365dc3bd6f..dc010291073 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
@@ -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,
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
index 136f4679075..9ab059152d7 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
@@ -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
   {
diff --git a/gcc/testsuite/rust/borrowck/subset.rs b/gcc/testsuite/rust/borrowck/subset.rs
index d7c00ca966c..5b4a663a0c3 100644
--- a/gcc/testsuite/rust/borrowck/subset.rs
+++ b/gcc/testsuite/rust/borrowck/subset.rs
@@ -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
+}
-- 
2.45.2



More information about the Gcc-rust mailing list