diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index a3f1340d429..5b5d9f5a7cf 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -614,11 +614,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { let partial = moved_lp.depth() > lp.depth(); let msg = if !has_fork && partial { "partially " } else if has_fork && !has_common { "collaterally "} - else { "" }; - let mut err = struct_span_err!( - self.tcx.sess, use_span, E0382, - "{} of {}moved value: `{}`", - verb, msg, nl); + else { "" }; + let mut err = self.cannot_act_on_moved_value(use_span, + verb, + msg, + &format!("{}", nl)); let need_note = match lp.ty.sty { ty::TypeVariants::TyClosure(id, _) => { let node_id = self.tcx.hir.as_local_node_id(id).unwrap(); @@ -698,10 +698,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { &self, span: Span, lp: &LoanPath<'tcx>) { - span_err!( - self.tcx.sess, span, E0383, - "partial reinitialization of uninitialized structure `{}`", - self.loan_path_to_string(lp)); + self.cannot_partially_reinit_an_uninit_struct(span, &self.loan_path_to_string(lp)) + .emit(); } pub fn report_reassigned_immutable_variable(&self, @@ -762,8 +760,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.cannot_assign(error_span, &descr, Origin::Ast) } BorrowViolation(euv::ClosureCapture(_)) => { - struct_span_err!(self.tcx.sess, error_span, E0595, - "closure cannot assign to {}", descr) + self.closure_cannot_assign_to_borrowed(error_span, &descr) } BorrowViolation(euv::OverloadedOperator) | BorrowViolation(euv::AddrOf) | @@ -772,8 +769,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { BorrowViolation(euv::AutoUnsafe) | BorrowViolation(euv::ForLoop) | BorrowViolation(euv::MatchDiscriminant) => { - struct_span_err!(self.tcx.sess, error_span, E0596, - "cannot borrow {} as mutable", descr) + self.cannot_borrow_path_as_mutable(error_span, &descr) } BorrowViolation(euv::ClosureInvocation) => { span_bug!(err.span, @@ -855,21 +851,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { if let Some((yield_span, _)) = maybe_borrow_across_yield { debug!("err_out_of_scope: opt_yield_span = {:?}", yield_span); - struct_span_err!(self.tcx.sess, - error_span, - E0626, - "borrow may still be in use when generator yields") - .span_label(yield_span, "possible yield occurs here") + self.cannot_borrow_across_generator_yield(error_span, yield_span) .emit(); return; } - let mut db = struct_span_err!(self.tcx.sess, - error_span, - E0597, - "{} does not live long enough", - msg); - + let mut db = self.path_does_not_live_long_enough(error_span, &msg); let (value_kind, value_msg) = match err.cmt.cat { mc::Categorization::Rvalue(..) => ("temporary value", "temporary value created here"), @@ -978,11 +965,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } err_borrowed_pointer_too_short(loan_scope, ptr_scope) => { let descr = self.cmt_to_path_or_string(&err.cmt); - let mut db = struct_span_err!(self.tcx.sess, error_span, E0598, - "lifetime of {} is too short to guarantee \ - its contents can be safely reborrowed", - descr); - + let mut db = self.lifetime_too_short_for_reborrow(error_span, &descr); let descr = match opt_loan_path(&err.cmt) { Some(lp) => { format!("`{}`", self.loan_path_to_string(&lp)) @@ -1054,12 +1037,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { let blame = cmt.immutability_blame(); let mut err = match blame { Some(ImmutabilityBlame::ClosureEnv(id)) => { - let mut err = struct_span_err!( - self.tcx.sess, span, E0387, - "{} in a captured outer variable in an `Fn` closure", prefix); - // FIXME: the distinction between these 2 messages looks wrong. - let help = if let BorrowViolation(euv::ClosureCapture(_)) = kind { + let help_msg = if let BorrowViolation(euv::ClosureCapture(_)) = kind { // The aliasability violation with closure captures can // happen for nested closures, so we know the enclosing // closure incorrectly accepts an `Fn` while it needs to @@ -1070,15 +1049,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { "consider changing this closure to take self by mutable reference" }; let node_id = self.tcx.hir.def_index_to_node_id(id); - err.span_help(self.tcx.hir.span(node_id), help); - err + let help_span = self.tcx.hir.span(node_id); + self.cannot_act_on_capture_in_sharable_fn(span, prefix, (help_span, help_msg)) } _ => { - let mut err = struct_span_err!( - self.tcx.sess, span, E0389, - "{} in a `&` reference", prefix); - err.span_label(span, "assignment into an immutable reference"); - err + self.cannot_assign_into_immutable_reference(span, prefix) } }; self.note_immutability_blame(&mut err, blame); @@ -1230,17 +1205,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { Err(_) => format!("move || ") }; - struct_span_err!(self.tcx.sess, err.span, E0373, - "closure may outlive the current function, \ - but it borrows {}, \ - which is owned by the current function", - cmt_path_or_string) - .span_label(capture_span, - format!("{} is borrowed here", - cmt_path_or_string)) - .span_label(err.span, - format!("may outlive borrowed value {}", - cmt_path_or_string)) + self.cannot_capture_in_long_lived_closure(err.span, + &cmt_path_or_string, + capture_span) .span_suggestion(err.span, &format!("to force the closure to take ownership of {} \ (and any other referenced variables), \ diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 94548f57249..11120d2e46f 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -18,7 +18,7 @@ #![feature(quote)] #[macro_use] extern crate log; -#[macro_use] extern crate syntax; +extern crate syntax; extern crate syntax_pos; extern crate rustc_errors as errors; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cd21060aff6..3514302c6c8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1259,7 +1259,6 @@ pub fn diagnostics_registry() -> errors::registry::Registry { let mut all_errors = Vec::new(); all_errors.extend_from_slice(&rustc::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_typeck::DIAGNOSTICS); - all_errors.extend_from_slice(&rustc_borrowck::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS); #[cfg(feature="llvm")] diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 37d53ca829e..3c002b586fa 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -294,6 +294,124 @@ pub trait BorrowckErrors { err.span_label(move_from_span, "cannot move out of here"); err } + + fn cannot_act_on_moved_value(&self, + use_span: Span, + verb: &str, + optional_adverb_for_moved: &str, + moved_path: &str) + -> DiagnosticBuilder + { + let err = struct_span_err!(self, use_span, E0382, + "{} of {}moved value: `{}`", + verb, optional_adverb_for_moved, moved_path); + err + } + + fn cannot_partially_reinit_an_uninit_struct(&self, + span: Span, + uninit_path: &str) + -> DiagnosticBuilder + { + let err = struct_span_err!(self, + span, + E0383, + "partial reinitialization of uninitialized structure `{}`", + uninit_path); + err + } + + fn closure_cannot_assign_to_borrowed(&self, + span: Span, + descr: &str) + -> DiagnosticBuilder + { + let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}", descr); + err + } + + fn cannot_borrow_path_as_mutable(&self, + span: Span, + path: &str) + -> DiagnosticBuilder + { + let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable", path); + err + } + + fn cannot_borrow_across_generator_yield(&self, + span: Span, + yield_span: Span) + -> DiagnosticBuilder + { + let mut err = struct_span_err!(self, + span, + E0626, + "borrow may still be in use when generator yields"); + err.span_label(yield_span, "possible yield occurs here"); + err + } + + fn path_does_not_live_long_enough(&self, + span: Span, + path: &str) + -> DiagnosticBuilder + { + let err = struct_span_err!(self, span, E0597, "{} does not live long enough", path); + err + } + + fn lifetime_too_short_for_reborrow(&self, + span: Span, + path: &str) + -> DiagnosticBuilder + { + let err = struct_span_err!(self, span, E0598, + "lifetime of {} is too short to guarantee \ + its contents can be safely reborrowed", + path); + err + } + + fn cannot_act_on_capture_in_sharable_fn(&self, + span: Span, + bad_thing: &str, + help: (Span, &str)) + -> DiagnosticBuilder + { + let (help_span, help_msg) = help; + let mut err = struct_span_err!(self, span, E0387, + "{} in a captured outer variable in an `Fn` closure", + bad_thing); + err.span_help(help_span, help_msg); + err + } + + fn cannot_assign_into_immutable_reference(&self, + span: Span, + bad_thing: &str) + -> DiagnosticBuilder + { + let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference", bad_thing); + err.span_label(span, "assignment into an immutable reference"); + err + } + + fn cannot_capture_in_long_lived_closure(&self, + closure_span: Span, + borrowed_path: &str, + capture_span: Span) + -> DiagnosticBuilder + { + let mut err = struct_span_err!(self, closure_span, E0373, + "closure may outlive the current function, \ + but it borrows {}, \ + which is owned by the current function", + borrowed_path); + err.span_label(capture_span, format!("{} is borrowed here", borrowed_path)) + .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path)); + err + } } impl<'b, 'tcx, 'gcx> BorrowckErrors for TyCtxt<'b, 'tcx, 'gcx> {