// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use rustc::session::config::BorrowckMode;
use rustc::ty::{self, TyCtxt};
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use syntax_pos::{MultiSpan, Span};
use std::fmt;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum Origin { Ast, Mir }
+pub enum Origin {
+ Ast,
+ Mir,
+}
impl fmt::Display for Origin {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- Origin::Mir => write!(w, " (Mir)"),
- Origin::Ast => ty::tls::with_opt(|opt_tcx| {
- // If user passed `-Z borrowck-mir`, then include an
- // AST origin as part of the error report
- if let Some(tcx) = opt_tcx {
- if tcx.sess.opts.debugging_opts.borrowck_mir {
- return write!(w, " (Ast)");
- }
- }
- // otherwise, do not include the origin (i.e., print
- // nothing at all)
- Ok(())
- }),
+ // If the user passed `-Z borrowck=compare`, then include
+ // origin info as part of the error report,
+ // otherwise
+ let display_origin = ty::tls::with_opt(|opt_tcx| {
+ if let Some(tcx) = opt_tcx {
+ tcx.sess.opts.borrowck_mode == BorrowckMode::Compare
+ } else {
+ false
+ }
+ });
+ if display_origin {
+ match *self {
+ Origin::Mir => write!(w, " (Mir)"),
+ Origin::Ast => write!(w, " (Ast)"),
+ }
+ } else {
+ // Print no origin info
+ Ok(())
}
}
}
-pub trait BorrowckErrors {
- fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
- sp: S,
- msg: &str,
- code: &str)
- -> DiagnosticBuilder<'a>;
-
- fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
- sp: S,
- msg: &str)
- -> DiagnosticBuilder<'a>;
-
- fn cannot_move_when_borrowed(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0505,
- "cannot move out of `{}` because it is borrowed{OGN}",
- desc, OGN=o)
- }
-
- fn cannot_use_when_mutably_borrowed(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0503,
- "cannot use `{}` because it was mutably borrowed{OGN}",
- desc, OGN=o)
- }
-
- fn cannot_act_on_uninitialized_variable(&self,
- span: Span,
- verb: &str,
- desc: &str,
- o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0381,
- "{} of possibly uninitialized variable: `{}`{OGN}",
- verb, desc, OGN=o)
- }
-
- fn cannot_mutably_borrow_multiply(&self,
- span: Span,
- desc: &str,
- opt_via: &str,
- o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0499,
- "cannot borrow `{}`{} as mutable more than once at a time{OGN}",
- desc, opt_via, OGN=o)
- }
-
- fn cannot_uniquely_borrow_by_two_closures(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0524,
- "two closures require unique access to `{}` at the same time{OGN}",
- desc, OGN=o)
- }
-
- fn cannot_uniquely_borrow_by_one_closure(&self,
- span: Span,
- desc_new: &str,
- noun_old: &str,
- msg_old: &str,
- o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0500,
- "closure requires unique access to `{}` but {} is already borrowed{}{OGN}",
- desc_new, noun_old, msg_old, OGN=o)
- }
-
- fn cannot_reborrow_already_uniquely_borrowed(&self,
- span: Span,
- desc_new: &str,
- msg_new: &str,
- kind_new: &str,
- o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0501,
- "cannot borrow `{}`{} as {} because previous closure \
- requires unique access{OGN}",
- desc_new, msg_new, kind_new, OGN=o)
- }
-
- fn cannot_reborrow_already_borrowed(&self,
- span: Span,
- desc_new: &str,
- msg_new: &str,
- kind_new: &str,
- noun_old: &str,
- kind_old: &str,
- msg_old: &str,
- o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0502,
- "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}",
- desc_new, msg_new, kind_new, noun_old, kind_old, msg_old, OGN=o)
- }
-
- fn cannot_assign_to_borrowed(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0506,
- "cannot assign to `{}` because it is borrowed{OGN}",
- desc, OGN=o)
- }
-
- fn cannot_move_into_closure(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0504,
- "cannot move `{}` into closure because it is borrowed{OGN}",
- desc, OGN=o)
- }
-
- fn cannot_reassign_immutable(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- struct_span_err!(self, span, E0384,
- "re-assignment of immutable variable `{}`{OGN}",
- desc, OGN=o)
- }
-
- fn cannot_assign_static(&self, span: Span, desc: &str, o: Origin)
- -> DiagnosticBuilder
- {
- self.struct_span_err(span, &format!("cannot assign to immutable static item {}{OGN}",
- desc, OGN=o))
+impl Origin {
+ /// Whether we should emit errors for the origin in the given mode
+ pub fn should_emit_errors(self, mode: BorrowckMode) -> bool {
+ match self {
+ Origin::Ast => mode.use_ast(),
+ Origin::Mir => mode.use_mir(),
+ }
+ }
+}
+
+pub trait BorrowckErrors<'cx>: Sized + Copy {
+ fn struct_span_err_with_code<S: Into<MultiSpan>>(
+ self,
+ sp: S,
+ msg: &str,
+ code: DiagnosticId,
+ ) -> DiagnosticBuilder<'cx>;
+
+ fn struct_span_err<S: Into<MultiSpan>>(self, sp: S, msg: &str) -> DiagnosticBuilder<'cx>;
+
+ /// Cancels the given error if we shouldn't emit errors for a given
+ /// origin in the current mode.
+ ///
+ /// Always make sure that the error gets passed through this function
+ /// before you return it.
+ fn cancel_if_wrong_origin(
+ self,
+ diag: DiagnosticBuilder<'cx>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx>;
+
+ fn cannot_move_when_borrowed(
+ self,
+ span: Span,
+ desc: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0505,
+ "cannot move out of `{}` because it is borrowed{OGN}",
+ desc,
+ OGN = o
+ );
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_use_when_mutably_borrowed(
+ self,
+ span: Span,
+ desc: &str,
+ borrow_span: Span,
+ borrow_desc: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0503,
+ "cannot use `{}` because it was mutably borrowed{OGN}",
+ desc,
+ OGN = o
+ );
+
+ err.span_label(
+ borrow_span,
+ format!("borrow of `{}` occurs here", borrow_desc),
+ );
+ err.span_label(span, format!("use of borrowed `{}`", borrow_desc));
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_act_on_uninitialized_variable(
+ self,
+ span: Span,
+ verb: &str,
+ desc: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0381,
+ "{} of possibly uninitialized variable: `{}`{OGN}",
+ verb,
+ desc,
+ OGN = o
+ );
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_mutably_borrow_multiply(
+ self,
+ new_loan_span: Span,
+ desc: &str,
+ opt_via: &str,
+ old_loan_span: Span,
+ old_opt_via: &str,
+ old_load_end_span: Option<Span>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ new_loan_span,
+ E0499,
+ "cannot borrow `{}`{} as mutable more than once at a time{OGN}",
+ desc,
+ opt_via,
+ OGN = o
+ );
+ if old_loan_span == new_loan_span {
+ // Both borrows are happening in the same place
+ // Meaning the borrow is occurring in a loop
+ err.span_label(
+ new_loan_span,
+ format!(
+ "mutable borrow starts here in previous \
+ iteration of loop{}",
+ opt_via
+ ),
+ );
+ if let Some(old_load_end_span) = old_load_end_span {
+ err.span_label(old_load_end_span, "mutable borrow ends here");
+ }
+ } else {
+ err.span_label(
+ old_loan_span,
+ format!("first mutable borrow occurs here{}", old_opt_via),
+ );
+ err.span_label(
+ new_loan_span,
+ format!("second mutable borrow occurs here{}", opt_via),
+ );
+ if let Some(old_load_end_span) = old_load_end_span {
+ err.span_label(old_load_end_span, "first borrow ends here");
+ }
+ }
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_uniquely_borrow_by_two_closures(
+ self,
+ new_loan_span: Span,
+ desc: &str,
+ old_loan_span: Span,
+ old_load_end_span: Option<Span>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ new_loan_span,
+ E0524,
+ "two closures require unique access to `{}` at the same time{OGN}",
+ desc,
+ OGN = o
+ );
+ if old_loan_span == new_loan_span {
+ err.span_label(
+ old_loan_span,
+ "closures are constructed here in different iterations of loop"
+ );
+ } else {
+ err.span_label(old_loan_span, "first closure is constructed here");
+ err.span_label(new_loan_span, "second closure is constructed here");
+ }
+ if let Some(old_load_end_span) = old_load_end_span {
+ err.span_label(old_load_end_span, "borrow from first closure ends here");
+ }
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_uniquely_borrow_by_one_closure(
+ self,
+ new_loan_span: Span,
+ container_name: &str,
+ desc_new: &str,
+ opt_via: &str,
+ old_loan_span: Span,
+ noun_old: &str,
+ old_opt_via: &str,
+ previous_end_span: Option<Span>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ new_loan_span,
+ E0500,
+ "closure requires unique access to `{}` but {} is already borrowed{}{OGN}",
+ desc_new,
+ noun_old,
+ old_opt_via,
+ OGN = o
+ );
+ err.span_label(
+ new_loan_span,
+ format!("{} construction occurs here{}", container_name, opt_via),
+ );
+ err.span_label(old_loan_span, format!("borrow occurs here{}", old_opt_via));
+ if let Some(previous_end_span) = previous_end_span {
+ err.span_label(previous_end_span, "borrow ends here");
+ }
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_reborrow_already_uniquely_borrowed(
+ self,
+ new_loan_span: Span,
+ container_name: &str,
+ desc_new: &str,
+ opt_via: &str,
+ kind_new: &str,
+ old_loan_span: Span,
+ old_opt_via: &str,
+ previous_end_span: Option<Span>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ new_loan_span,
+ E0501,
+ "cannot borrow `{}`{} as {} because previous closure \
+ requires unique access{OGN}",
+ desc_new,
+ opt_via,
+ kind_new,
+ OGN = o
+ );
+ err.span_label(new_loan_span, format!("borrow occurs here{}", opt_via));
+ err.span_label(
+ old_loan_span,
+ format!("{} construction occurs here{}", container_name, old_opt_via),
+ );
+ if let Some(previous_end_span) = previous_end_span {
+ err.span_label(previous_end_span, "borrow from closure ends here");
+ }
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_reborrow_already_borrowed(
+ self,
+ span: Span,
+ desc_new: &str,
+ msg_new: &str,
+ kind_new: &str,
+ old_span: Span,
+ noun_old: &str,
+ kind_old: &str,
+ msg_old: &str,
+ old_load_end_span: Option<Span>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0502,
+ "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}",
+ desc_new,
+ msg_new,
+ kind_new,
+ noun_old,
+ kind_old,
+ msg_old,
+ OGN = o
+ );
+ err.span_label(span, format!("{} borrow occurs here{}", kind_new, msg_new));
+ err.span_label(
+ old_span,
+ format!("{} borrow occurs here{}", kind_old, msg_old),
+ );
+ if let Some(old_load_end_span) = old_load_end_span {
+ err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
+ }
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_assign_to_borrowed(
+ self,
+ span: Span,
+ borrow_span: Span,
+ desc: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0506,
+ "cannot assign to `{}` because it is borrowed{OGN}",
+ desc,
+ OGN = o
+ );
+
+ err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc));
+ err.span_label(
+ span,
+ format!("assignment to borrowed `{}` occurs here", desc),
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0504,
+ "cannot move `{}` into closure because it is borrowed{OGN}",
+ desc,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_reassign_immutable(
+ self,
+ span: Span,
+ desc: &str,
+ is_arg: bool,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let msg = if is_arg {
+ "to immutable argument"
+ } else {
+ "twice to immutable variable"
+ };
+ let err = struct_span_err!(
+ self,
+ span,
+ E0384,
+ "cannot assign {} `{}`{OGN}",
+ msg,
+ desc,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(self, span, E0594, "cannot assign to {}{OGN}", desc, OGN = o);
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_assign_static(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> {
+ self.cannot_assign(span, &format!("immutable static item `{}`", desc), o)
+ }
+
+ fn cannot_move_out_of(
+ self,
+ move_from_span: Span,
+ move_from_desc: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ move_from_span,
+ E0507,
+ "cannot move out of {}{OGN}",
+ move_from_desc,
+ OGN = o
+ );
+ err.span_label(
+ move_from_span,
+ format!("cannot move out of {}", move_from_desc),
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ /// Signal an error due to an attempt to move out of the interior
+ /// of an array or slice. `is_index` is None when error origin
+ /// didn't capture whether there was an indexing operation or not.
+ fn cannot_move_out_of_interior_noncopy(
+ self,
+ move_from_span: Span,
+ ty: ty::Ty,
+ is_index: Option<bool>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let type_name = match (&ty.sty, is_index) {
+ (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
+ (&ty::Slice(_), _) => "slice",
+ _ => span_bug!(move_from_span, "this path should not cause illegal move"),
+ };
+ let mut err = struct_span_err!(
+ self,
+ move_from_span,
+ E0508,
+ "cannot move out of type `{}`, \
+ a non-copy {}{OGN}",
+ ty,
+ type_name,
+ OGN = o
+ );
+ err.span_label(move_from_span, "cannot move out of here");
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_move_out_of_interior_of_drop(
+ self,
+ move_from_span: Span,
+ container_ty: ty::Ty,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ move_from_span,
+ E0509,
+ "cannot move out of type `{}`, \
+ which implements the `Drop` trait{OGN}",
+ container_ty,
+ OGN = o
+ );
+ err.span_label(move_from_span, "cannot move out of here");
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_act_on_moved_value(
+ self,
+ use_span: Span,
+ verb: &str,
+ optional_adverb_for_moved: &str,
+ moved_path: Option<String>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let moved_path = moved_path
+ .map(|mp| format!(": `{}`", mp))
+ .unwrap_or_default();
+
+ let err = struct_span_err!(
+ self,
+ use_span,
+ E0382,
+ "{} of {}moved value{}{OGN}",
+ verb,
+ optional_adverb_for_moved,
+ moved_path,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_partially_reinit_an_uninit_struct(
+ self,
+ span: Span,
+ uninit_path: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0383,
+ "partial reinitialization of uninitialized structure `{}`{OGN}",
+ uninit_path,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn closure_cannot_assign_to_borrowed(
+ self,
+ span: Span,
+ descr: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0595,
+ "closure cannot assign to {}{OGN}",
+ descr,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_borrow_path_as_mutable_because(
+ self,
+ span: Span,
+ path: &str,
+ reason: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0596,
+ "cannot borrow {} as mutable{}{OGN}",
+ path,
+ reason,
+ OGN = o,
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_borrow_path_as_mutable(
+ self,
+ span: Span,
+ path: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ self.cannot_borrow_path_as_mutable_because(span, path, "", o)
+ }
+
+ fn cannot_mutate_in_match_guard(
+ self,
+ mutate_span: Span,
+ match_span: Span,
+ match_place: &str,
+ action: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ mutate_span,
+ E0510,
+ "cannot {} `{}` in match guard{OGN}",
+ action,
+ match_place,
+ OGN = o
+ );
+ err.span_label(mutate_span, format!("cannot {}", action));
+ err.span_label(match_span, format!("value is immutable in match guard"));
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_borrow_across_generator_yield(
+ self,
+ span: Span,
+ yield_span: Span,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0626,
+ "borrow may still be in use when generator yields{OGN}",
+ OGN = o
+ );
+ err.span_label(yield_span, "possible yield occurs here");
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_borrow_across_destructor(
+ self,
+ borrow_span: Span,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ borrow_span,
+ E0713,
+ "borrow may still be in use when destructor runs{OGN}",
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn path_does_not_live_long_enough(
+ self,
+ span: Span,
+ path: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0597,
+ "{} does not live long enough{OGN}",
+ path,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_return_reference_to_local(
+ self,
+ span: Span,
+ reference_desc: &str,
+ path_desc: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0515,
+ "cannot return {REFERENCE} {LOCAL}{OGN}",
+ REFERENCE=reference_desc,
+ LOCAL=path_desc,
+ OGN = o
+ );
+
+ err.span_label(
+ span,
+ format!("returns a {} data owned by the current function", reference_desc),
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn lifetime_too_short_for_reborrow(
+ self,
+ span: Span,
+ path: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0598,
+ "lifetime of {} is too short to guarantee \
+ its contents can be safely reborrowed{OGN}",
+ path,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_act_on_capture_in_sharable_fn(
+ self,
+ span: Span,
+ bad_thing: &str,
+ help: (Span, &str),
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let (help_span, help_msg) = help;
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0387,
+ "{} in a captured outer variable in an `Fn` closure{OGN}",
+ bad_thing,
+ OGN = o
+ );
+ err.span_help(help_span, help_msg);
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_assign_into_immutable_reference(
+ self,
+ span: Span,
+ bad_thing: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let mut err = struct_span_err!(
+ self,
+ span,
+ E0389,
+ "{} in a `&` reference{OGN}",
+ bad_thing,
+ OGN = o
+ );
+ err.span_label(span, "assignment into an immutable reference");
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn cannot_capture_in_long_lived_closure(
+ self,
+ closure_span: Span,
+ borrowed_path: &str,
+ capture_span: Span,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ 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{OGN}",
+ borrowed_path,
+ OGN = o
+ );
+ err.span_label(capture_span, format!("{} is borrowed here", borrowed_path))
+ .span_label(
+ closure_span,
+ format!("may outlive borrowed value {}", borrowed_path),
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn borrowed_data_escapes_closure(
+ self,
+ escape_span: Span,
+ escapes_from: &str,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ escape_span,
+ E0521,
+ "borrowed data escapes outside of {}{OGN}",
+ escapes_from,
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn thread_local_value_does_not_live_long_enough(
+ self,
+ span: Span,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0712,
+ "thread-local variable borrowed past end of function{OGN}",
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
+ }
+
+ fn temporary_value_borrowed_for_too_long(
+ self,
+ span: Span,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ let err = struct_span_err!(
+ self,
+ span,
+ E0716,
+ "temporary value dropped while borrowed{OGN}",
+ OGN = o
+ );
+
+ self.cancel_if_wrong_origin(err, o)
}
}
-impl<'b, 'tcx, 'gcx> BorrowckErrors for TyCtxt<'b, 'tcx, 'gcx> {
- fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
- sp: S,
- msg: &str,
- code: &str)
- -> DiagnosticBuilder<'a>
- {
+impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> {
+ fn struct_span_err_with_code<S: Into<MultiSpan>>(
+ self,
+ sp: S,
+ msg: &str,
+ code: DiagnosticId,
+ ) -> DiagnosticBuilder<'cx> {
self.sess.struct_span_err_with_code(sp, msg, code)
}
- fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
- sp: S,
- msg: &str)
- -> DiagnosticBuilder<'a>
- {
+ fn struct_span_err<S: Into<MultiSpan>>(self, sp: S, msg: &str) -> DiagnosticBuilder<'cx> {
self.sess.struct_span_err(sp, msg)
}
+
+ fn cancel_if_wrong_origin(
+ self,
+ mut diag: DiagnosticBuilder<'cx>,
+ o: Origin,
+ ) -> DiagnosticBuilder<'cx> {
+ if !o.should_emit_errors(self.borrowck_mode()) {
+ self.sess.diagnostic().cancel(&mut diag);
+ }
+ diag
+ }
}