Skip to content

Commit

Permalink
Subset errors with locations
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
braw-lee authored and P-E-P committed Aug 16, 2024
1 parent ddda47c commit c6d0824
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 9 deletions.
43 changes: 38 additions & 5 deletions gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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}});
}
}

Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class BorrowCheckerDiagnostics

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
{
Expand Down
29 changes: 25 additions & 4 deletions gcc/testsuite/rust/borrowck/subset.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
// { 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 {
y
}

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 {
Expand All @@ -24,4 +45,4 @@ fn complex_cfg_subset_fixed<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32
} else {
y
}
}
}

0 comments on commit c6d0824

Please sign in to comment.