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 0365dc3bd6fe..dc010291073d 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>> + 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> 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 c46e8d848c00..f77ad73a1c01 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 @@ 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 { diff --git a/gcc/testsuite/rust/borrowck/subset.rs b/gcc/testsuite/rust/borrowck/subset.rs index d7c00ca966c1..5b4a663a0c3d 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 +}