diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index eed8f82b5d8..43e9cdd73c4 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -464,40 +464,36 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { match (new_loan.kind, old_loan.kind) { (ty::MutBorrow, ty::MutBorrow) => { - self.bccx.span_err( - new_loan.span, - &format!("cannot borrow `{}`{} as mutable \ - more than once at a time", - nl, new_loan_msg)) + span_err!(self.bccx, new_loan.span, E0499, + "cannot borrow `{}`{} as mutable \ + more than once at a time", + nl, new_loan_msg); } (ty::UniqueImmBorrow, _) => { - self.bccx.span_err( - new_loan.span, - &format!("closure requires unique access to `{}` \ - but {} is already borrowed{}", - nl, ol_pronoun, old_loan_msg)); + span_err!(self.bccx, new_loan.span, E0500, + "closure requires unique access to `{}` \ + but {} is already borrowed{}", + nl, ol_pronoun, old_loan_msg); } (_, ty::UniqueImmBorrow) => { - self.bccx.span_err( - new_loan.span, - &format!("cannot borrow `{}`{} as {} because \ - previous closure requires unique access", - nl, new_loan_msg, new_loan.kind.to_user_str())); + span_err!(self.bccx, new_loan.span, E0501, + "cannot borrow `{}`{} as {} because \ + previous closure requires unique access", + nl, new_loan_msg, new_loan.kind.to_user_str()); } (_, _) => { - self.bccx.span_err( - new_loan.span, - &format!("cannot borrow `{}`{} as {} because \ - {} is also borrowed as {}{}", - nl, - new_loan_msg, - new_loan.kind.to_user_str(), - ol_pronoun, - old_loan.kind.to_user_str(), - old_loan_msg)); + span_err!(self.bccx, new_loan.span, E0502, + "cannot borrow `{}`{} as {} because \ + {} is also borrowed as {}{}", + nl, + new_loan_msg, + new_loan.kind.to_user_str(), + ol_pronoun, + old_loan.kind.to_user_str(), + old_loan_msg); } } @@ -617,11 +613,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) { UseOk => { } UseWhileBorrowed(loan_path, loan_span) => { - self.bccx.span_err( - span, - &format!("cannot use `{}` because it was mutably borrowed", - &self.bccx.loan_path_to_string(copy_path)) - ); + span_err!(self.bccx, span, E0503, + "cannot use `{}` because it was mutably borrowed", + &self.bccx.loan_path_to_string(copy_path)); self.bccx.span_note( loan_span, &format!("borrow of `{}` occurs here", @@ -642,18 +636,19 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { match self.analyze_restrictions_on_use(id, move_path, ty::MutBorrow) { UseOk => { } UseWhileBorrowed(loan_path, loan_span) => { - let err_message = match move_kind { + match move_kind { move_data::Captured => - format!("cannot move `{}` into closure because it is borrowed", - &self.bccx.loan_path_to_string(move_path)), + span_err!(self.bccx, span, E0504, + "cannot move `{}` into closure because it is borrowed", + &self.bccx.loan_path_to_string(move_path)), move_data::Declared | move_data::MoveExpr | move_data::MovePat => - format!("cannot move out of `{}` because it is borrowed", - &self.bccx.loan_path_to_string(move_path)) + span_err!(self.bccx, span, E0505, + "cannot move out of `{}` because it is borrowed", + &self.bccx.loan_path_to_string(move_path)) }; - self.bccx.span_err(span, &err_message[..]); self.bccx.span_note( loan_span, &format!("borrow of `{}` occurs here", @@ -820,10 +815,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { span: Span, loan_path: &LoanPath<'tcx>, loan: &Loan) { - self.bccx.span_err( - span, - &format!("cannot assign to `{}` because it is borrowed", - self.bccx.loan_path_to_string(loan_path))); + span_err!(self.bccx, span, E0506, + "cannot assign to `{}` because it is borrowed", + self.bccx.loan_path_to_string(loan_path)); self.bccx.span_note( loan.span, &format!("borrow of `{}` occurs here", diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index c39b1a9da07..bbcf5193342 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -119,18 +119,18 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, mc::cat_deref(_, _, mc::Implicit(..)) | mc::cat_deref(_, _, mc::UnsafePtr(..)) | mc::cat_static_item => { - bccx.span_err(move_from.span, - &format!("cannot move out of {}", - move_from.descriptive_string(bccx.tcx))); + span_err!(bccx, move_from.span, E0507, + "cannot move out of {}", + move_from.descriptive_string(bccx.tcx)); } mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => { let expr = bccx.tcx.map.expect_expr(move_from.id); if let hir::ExprIndex(..) = expr.node { - bccx.span_err(move_from.span, - &format!("cannot move out of type `{}`, \ - a non-copy fixed-size array", - b.ty)); + span_err!(bccx, move_from.span, E0508, + "cannot move out of type `{}`, \ + a non-copy fixed-size array", + b.ty); } } @@ -139,11 +139,10 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, match b.ty.sty { ty::TyStruct(def, _) | ty::TyEnum(def, _) if def.has_dtor() => { - bccx.span_err( - move_from.span, - &format!("cannot move out of type `{}`, \ - which defines the `Drop` trait", - b.ty)); + span_err!(bccx, move_from.span, E0509, + "cannot move out of type `{}`, \ + which defines the `Drop` trait", + b.ty); }, _ => { bccx.span_bug(move_from.span, "this path should not cause illegal move") diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index e94a214309d..ede1bb58ce6 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -263,12 +263,46 @@ fn mutable() { You can read more about cell types in the API documentation: https://doc.rust-lang.org/std/cell/ -"## +"##, + +E0499: r##" +A variable was borrowed as mutable more than once. Erroneous code example: + +``` +let mut i = 0; +let mut x = &mut i; +let mut a = &mut i; +// error: cannot borrow `i` as mutable more than once at a time +``` + +Please note that in rust, you can have as many reference on a variable as you +want, but only one can be mutable. Example: + + +``` +let mut i = 0; +let mut x = &mut i; +let mut a = &i; +let mut b = &i; +let mut c = &i; +// ... +``` +"##, } register_diagnostics! { E0385, // {} in an aliasable location E0388, // {} in a static location - E0389 // {} in a `&` reference + E0389, // {} in a `&` reference + E0500, // closure requires unique access to `..` but .. is already borrowed + E0501, // cannot borrow `..`.. as .. because previous closure requires unique access + E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ... + E0503, // cannot use `..` because it was mutably borrowed + E0504, // cannot move `..` into closure because it is borrowed + E0505, // cannot move out of `..` because it is borrowed + E0506, // cannot assign to `..` because it is borrowed + E0507, // cannot move out of .. + E0508, // cannot move out of type `..`, a non-copy fixed-size array + E0509, // cannot move out of type `..`, which defines the `Drop` trait }