Skip to content

Commit c6d0824

Browse files
braw-leeP-E-P
authored andcommitted
Subset errors with locations
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]>
1 parent ddda47c commit c6d0824

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,38 @@ BorrowCheckerDiagnostics::report_loan_errors ()
6161
void
6262
BorrowCheckerDiagnostics::report_subset_errors ()
6363
{
64-
if (!subset_errors.empty ())
64+
// remove duplicates in subset_errors
65+
//
66+
// Polonius may output subset errors for same 2 origins at multiple points
67+
// so to avoid duplicating the errors, we can remove the elements in subset
68+
// errors with same origin pair
69+
std::vector<std::pair<size_t, std::pair<size_t, size_t>>>
70+
deduplicated_subset_errors;
71+
72+
for (auto pair : subset_errors)
6573
{
66-
rust_error_at (hir_function->get_locus (),
67-
"Found subset errors in function %s. Some lifetime "
68-
"constraints need to be added.",
69-
hir_function->get_function_name ().as_string ().c_str ());
74+
auto it = std::find_if (
75+
deduplicated_subset_errors.begin (), deduplicated_subset_errors.end (),
76+
[&pair] (std::pair<size_t, std::pair<size_t, size_t>> element) {
77+
return element.second == pair.second;
78+
});
79+
if (it == deduplicated_subset_errors.end ())
80+
{
81+
deduplicated_subset_errors.push_back (pair);
82+
}
83+
}
84+
for (const auto &error : deduplicated_subset_errors)
85+
{
86+
auto first_lifetime_location
87+
= get_lifetime_param (error.second.first)->get_locus ();
88+
auto second_lifetime_location
89+
= get_lifetime_param (error.second.second)->get_locus ();
90+
multi_label_error (
91+
"subset error, some lifetime constraints need to be added",
92+
bir_function.location,
93+
{{"lifetime defined here", first_lifetime_location},
94+
{"lifetime defined here", second_lifetime_location},
95+
{"subset error occurs in this function", bir_function.location}});
7096
}
7197
}
7298

@@ -88,6 +114,13 @@ BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan)
88114
return bir_function.place_db.get_loans ()[loan];
89115
}
90116

117+
const HIR::LifetimeParam *
118+
BorrowCheckerDiagnostics::get_lifetime_param (Polonius::Origin origin)
119+
120+
{
121+
return bir_function.region_hir_map.at (origin);
122+
}
123+
91124
void
92125
BorrowCheckerDiagnostics::multi_label_error (
93126
const char *error_message, location_t error_location,

gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class BorrowCheckerDiagnostics
6666

6767
const BIR::Statement &get_statement (Polonius::Point point);
6868
const BIR::Loan &get_loan (Polonius::Loan loan);
69+
const HIR::LifetimeParam *get_lifetime_param (Polonius::Origin origin);
6970

7071
struct LabelLocationPair
7172
{

gcc/testsuite/rust/borrowck/subset.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
1-
// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
1+
// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
2+
// { dg-enable-nn-line-numbers "" }
23

34
fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
4-
// { dg-error "Found subset errors in function missing_subset" "" { target *-*-* } .-1 }
5+
// { dg-error "subset error, some lifetime constraints need to be added" "" { target *-*-* } .-1 }
56
y //~ ERROR
7+
/*
8+
{ dg-begin-multiline-output "" }
9+
NN | fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
10+
| ^~ ~~ ~~
11+
| | | |
12+
| | | lifetime defined here
13+
| | lifetime defined here
14+
| subset error occurs in this function
15+
{ dg-end-multiline-output "" }
16+
*/
617
}
718

819
fn missing_subset_fixed<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 where 'b: 'a {
920
y
1021
}
1122

1223
fn complex_cfg_subset<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 {
13-
// { dg-error "Found subset errors in function complex_cfg_subset" "" { target *-*-* } .-1 }
24+
// { dg-error "subset error, some lifetime constraints need to be added" "" { target *-*-* } .-1 }
1425
if b {
1526
y //~ ERROR
1627
} else {
1728
x
1829
}
30+
/*
31+
{ dg-begin-multiline-output "" }
32+
NN | fn complex_cfg_subset<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 {
33+
| ^~ ~~ ~~
34+
| | | |
35+
| | | lifetime defined here
36+
| | lifetime defined here
37+
| subset error occurs in this function
38+
{ dg-end-multiline-output "" }
39+
*/
1940
}
2041

2142
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
2445
} else {
2546
y
2647
}
27-
}
48+
}

0 commit comments

Comments
 (0)