diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index dc5894cd6b9..cbdeda7b902 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -392,6 +392,12 @@ declare_lint! { "nested occurrence of `impl Trait` type" } +declare_lint! { + pub MUTABLE_BORROW_RESERVATION_CONFLICT, + Warn, + "reservation of a two-phased borrow conflicts with other shared borrows" +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -457,6 +463,7 @@ declare_lint_pass! { AMBIGUOUS_ASSOCIATED_ITEMS, NESTED_IMPL_TRAIT, DUPLICATE_MATCHER_BINDING_NAME, + MUTABLE_BORROW_RESERVATION_CONFLICT, ] } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 7e77962a16e..07c505c6bde 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -438,6 +438,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #59014 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT), + reference: "issue #59159 ", + edition: None, + } ]); // Register renamed and removed lints. diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 64c0eaab923..255dc2df5b8 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -6,6 +6,7 @@ use rustc::hir::Node; use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; use rustc::lint::builtin::UNUSED_MUT; +use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT}; use rustc::middle::borrowck::SignalledError; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{ @@ -26,7 +27,7 @@ use std::collections::BTreeMap; use std::mem; use std::rc::Rc; -use syntax_pos::Span; +use syntax_pos::{Span, DUMMY_SP}; use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex}; use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError}; @@ -262,11 +263,19 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( } mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer - // Buffer any reservation warnings. + // Convert any reservation warnings into lints. let reservation_warnings = mem::replace(&mut mbcx.reservation_warnings, Default::default()); for (_, (place, span, context, bk, borrow)) in reservation_warnings { - let mut diag = mbcx.report_conflicting_borrow(context, (&place, span), bk, &borrow); - downgrade_if_error(&mut diag); + let mut initial_diag = mbcx.report_conflicting_borrow(context, (&place, span), bk, &borrow); + + // Span and message don't matter; we overwrite them below anyway + let mut diag = mbcx.infcx.tcx.struct_span_lint_hir( + MUTABLE_BORROW_RESERVATION_CONFLICT, id, DUMMY_SP, ""); + + diag.message = initial_diag.styled_message().clone(); + diag.span = initial_diag.span.clone(); + + initial_diag.cancel(); diag.buffer(&mut mbcx.errors_buffer); }