// <http://www.gnu.org/licenses/>.
#include "rust-borrow-checker-diagnostics.h"
+#include "polonius/rust-polonius-ffi.h"
+#include "rust-diagnostics.h"
namespace Rust {
namespace BIR {
void
BorrowCheckerDiagnostics::report_loan_errors ()
{
- if (!loan_errors.empty ())
+ for (const auto &pair : loan_errors)
{
- rust_error_at (hir_function->get_locus (),
- "Found loan errors in function %s",
- hir_function->get_function_name ().as_string ().c_str ());
+ auto error_location = get_statement (pair.first).get_location ();
+ for (const auto &loan : pair.second)
+ {
+ auto loan_struct = get_loan (loan);
+ multi_label_error ("use of borrowed value", error_location,
+ {{"borrow occurs here", loan_struct.location},
+ {"borrowed value used here", error_location}});
+ }
}
}
}
}
+const BIR::Statement &
+BorrowCheckerDiagnostics::get_statement (Polonius::Point point)
+{
+ auto statement_index = Polonius::FullPoint::extract_stmt (point);
+ auto bb_index = Polonius::FullPoint::extract_bb (point);
+ // assert that the extracted indexes are valid
+ rust_assert (bb_index < bir_function.basic_blocks.size ());
+ rust_assert (statement_index
+ < bir_function.basic_blocks[bb_index].statements.size ());
+ return bir_function.basic_blocks[bb_index].statements[statement_index];
+}
+
+const BIR::Loan &
+BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan)
+{
+ return bir_function.place_db.get_loans ()[loan];
+}
+
+void
+BorrowCheckerDiagnostics::multi_label_error (
+ const char *error_message, location_t error_location,
+ std::vector<LabelLocationPair> location_label_pairs)
+{
+ rich_location r{line_table, error_location};
+ for (auto &label_location : location_label_pairs)
+ {
+ r.add_range (label_location.location, SHOW_RANGE_WITHOUT_CARET,
+ &label_location.label);
+ }
+ rust_error_at (r, "%s", error_message);
+}
+
} // namespace BIR
} // namespace Rust
#include "polonius/rust-polonius.h"
#include "rust-bir.h"
#include "rust-hir-item.h"
+#include "text-range-label.h"
namespace Rust {
namespace BIR {
void report_move_errors ();
void report_loan_errors ();
void report_subset_errors ();
+
+ const BIR::Statement &get_statement (Polonius::Point point);
+ const BIR::Loan &get_loan (Polonius::Loan loan);
+
+ struct LabelLocationPair
+ {
+ text_range_label label;
+ location_t location;
+ };
+ static void
+ multi_label_error (const char *error_message, location_t error_location,
+ std::vector<LabelLocationPair> location_label_pairs);
};
} // namespace BIR
-// { 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 "" }
#[lang = "sized"]
pub trait Sized {}
}
fn immutable_borrow_while_mutable_borrowed_struct() {
- // { dg-error "Found loan errors in function immutable_borrow_while_mutable_borrowed_struct" "" { target *-*-* } .-1 }
let mut x = 0;
let y = ReferenceMut::new(&mut x);
let z = &x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = ReferenceMut::new(&mut x);
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = &x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn mutable_borrow_while_immutable_borrowed_struct() {
- // { dg-error "Found loan errors in function mutable_borrow_while_immutable_borrowed_struct" "" { target *-*-* } .-1 }
let x = 0;
let y = Reference::new(&x);
let z = &mut x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = Reference::new(&x);
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = &mut x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn mutable_borrow_while_mutable_borrowed_struct() {
- // { dg-error "Found loan errors in function mutable_borrow_while_mutable_borrowed_struct" "" { target *-*-* } .-1 }
let mut x = 0;
let y = ReferenceMut::new(&mut x);
let z = &mut x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = ReferenceMut::new(&mut x);
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = &mut x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn immutable_reborrow_while_immutable_borrowed_struct() {
fn mutable_reborrow_while_immutable_borrowed_struct() {
// { dg-error "Cannot reborrow immutable borrow as mutable" "" { target *-*-* } .-1 }
+ /*
+ { dg-begin-multiline-output "" }
+ NN | fn mutable_reborrow_while_immutable_borrowed_struct() {
+ | ^~
+ { dg-end-multiline-output "" }
+ */
let x = 0;
let y = Reference::new(&x);
let z = &mut *y.value; //~ ERROR
}
fn read_while_mutable_borrowed_struct() {
- // { dg-error "Found loan errors in function read_while_mutable_borrowed_struct" "" { target *-*-* } .-1 }
let mut x = 0;
let y = ReferenceMut::new(&mut x);
let z = x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = ReferenceMut::new(&mut x);
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn write_while_borrowed_struct() {
- // { dg-error "Found loan errors in function write_while_borrowed_struct" "" { target *-*-* } .-1 }
let mut x = 0;
let y = Reference::new(&x);
x = 1; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let z = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = Reference::new(&x);
+ | ~
+ | |
+ | borrow occurs here
+ NN | x = 1; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn write_while_immutable_borrowed_struct() {
- // { dg-error "Found loan errors in function write_while_immutable_borrowed_struct" "" { target *-*-* } .-1 }
let x = 0;
let y = Reference::new(&x);
x = 1; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let z = y;
-}
\ No newline at end of file
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = Reference::new(&x);
+ | ~
+ | |
+ | borrow occurs here
+ NN | x = 1; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
+}
-// { 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 "" }
-pub fn return_ref_to_local() -> &'static i32 { // { dg-error "Found loan errors in function return_ref_to_local" }
+pub fn return_ref_to_local() -> &'static i32 {
let x = 0;
&x //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
+ /*
+ { dg-begin-multiline-output "" }
+ NN | &x //~ ERROR
+ | ^
+ | |
+ | borrow occurs here
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
-// { 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 "" }
#[lang = "sized"]
pub trait Sized {}
fn immutable_borrow_while_mutable_borrowed() {
- // { dg-error "Found loan errors in function immutable_borrow_while_mutable_borrowed" "" { target *-*-* } .-1 }
let mut x = 0;
let y = &mut x;
let z = &x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &mut x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = &x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn mutable_borrow_while_immutable_borrowed() {
- // { dg-error "Found loan errors in function mutable_borrow_while_immutable_borrowed" "" { target *-*-* } .-1 }
let x = 0;
let y = &x;
let z = &mut x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = &mut x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn mutable_borrow_while_mutable_borrowed() {
- // { dg-error "Found loan errors in function mutable_borrow_while_mutable_borrowed" "" { target *-*-* } .-1 }
let mut x = 0;
let y = &mut x;
let z = &mut x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &mut x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = &mut x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn immutable_reborrow_while_immutable_borrowed() {
let x = 0;
let y = &x;
let z = &mut *y; //~ ERROR
+ /*
+ { dg-begin-multiline-output "" }
+ NN | fn mutable_reborrow_while_immutable_borrowed() {
+ | ^~
+ { dg-end-multiline-output "" }
+ */
}
fn read_while_mutable_borrowed() {
- // { dg-error "Found loan errors in function read_while_mutable_borrowed" "" { target *-*-* } .-1 }
let mut x = 0;
let y = &mut x;
let z = x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &mut x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn write_while_borrowed() {
- // { dg-error "Found loan errors in function write_while_borrowed" "" { target *-*-* } .-1 }
let mut x = 0;
let y = &x;
x = 1; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let z = y;
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | x = 1; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
fn write_while_immutable_borrowed() {
- // { dg-error "Found loan errors in function write_while_immutable_borrowed" "" { target *-*-* } .-1 }
let x = 0;
let y = &x;
x = 1; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let z = y;
-}
\ No newline at end of file
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | x = 1; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
+}
-// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
-pub fn use_while_mut() { // { dg-error "Found loan errors in function use_while_mut" }
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
+// { dg-enable-nn-line-numbers "" }
+
+pub fn use_while_mut() {
let mut x = 0;
let y = &mut x;
let z = x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
let w = y;
-}
\ No newline at end of file
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &mut x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
+}
-// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
-
-pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 { // { dg-error "Found loan errors in function use_while_mut_fr" }
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
+// { dg-enable-nn-line-numbers "" }
+pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {
let y = &mut *x;
let z = x; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
y
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let y = &mut *x;
+ | ~
+ | |
+ | borrow occurs here
+ NN | let z = x; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
}
-// { 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 foo<'a, 'b>(p: &'b &'a mut usize) -> &'b&'a mut usize {
p
}
-fn well_formed_function_inputs() { // { dg-error "Found loan errors in function well_formed_function_inputs" }
+fn well_formed_function_inputs() {
let s = &mut 1;
let r = &mut *s;
let tmp = foo(&r );
// let aarg = &*arg;
// let tmp = arg;
s; //~ ERROR
+ // { dg-error "use of borrowed value" "" { target *-*-* } .-1 }
tmp;
-}
\ No newline at end of file
+ /*
+ { dg-begin-multiline-output "" }
+ NN | let r = &mut *s;
+ | ~
+ | |
+ | borrow occurs here
+......
+ NN | s; //~ ERROR
+ | ^
+ | |
+ | borrowed value used here
+ { dg-end-multiline-output "" }
+ */
+}