diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index 41279588e6334..563ff056ae467 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::nll::ToRegionVid; use crate::path_utils::allow_two_phase_borrow; use crate::place_ext::PlaceExt; diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 08ea00d71ef9d..c24a008d447ff 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -1,16 +1,28 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{ struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan, }; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; +use crate::session_diagnostics::{ + ActMovedValueErr, AssignBorrowErr, AssignErr, BorrowAcrossDestructor, + BorrowAcrossGeneratorYield, BorrowEscapeClosure, ClosureConstructLabel, + ClosureUniquelyBorrowErr, ClosureVarOutliveErr, ImmuteArgAssign, ImmuteVarReassign, + InteriorDropMoveErr, InteriorNoncopyMoveErr, MoveBorrowedErr, MovedOutErr, MutateInImmute, + PathShortLive, ReturnRefLocalErr, TemporaryDroppedErr, ThreadLocalOutliveErr, + TwoClosuresUniquelyBorrowErr, UniquelyBorrowReborrowErr, UseMutBorrowErr, +}; + impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { pub(crate) fn cannot_move_when_borrowed( &self, span: Span, desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,) + self.infcx.tcx.sess.create_err(MoveBorrowedErr { desc, span }) } pub(crate) fn cannot_use_when_mutably_borrowed( @@ -20,17 +32,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrow_span: Span, borrow_desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - span, - E0503, - "cannot use {} because it was mutably borrowed", - desc, - ); - - err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_desc)); - err.span_label(span, format!("use of borrowed {}", borrow_desc)); - err + self.infcx.tcx.sess.create_err(UseMutBorrowErr { desc, borrow_desc, span, borrow_span }) } pub(crate) fn cannot_mutably_borrow_multiply( @@ -42,6 +44,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_opt_via: &str, old_load_end_span: Option, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { + //FIXME: migrate later let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) }; let mut err = struct_span_err!( @@ -90,26 +93,22 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_loan_span: Span, old_load_end_span: Option, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - new_loan_span, - E0524, - "two closures require unique access to {} at the same time", - desc, - ); + let case: ClosureConstructLabel; + let diff_span: Option; if old_loan_span == new_loan_span { - err.span_label( - old_loan_span, - "closures are constructed here in different iterations of loop", - ); + case = ClosureConstructLabel::Both { old_loan_span }; + diff_span = None; } 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"); + case = ClosureConstructLabel::First { old_loan_span }; + diff_span = Some(new_loan_span); } - err + self.infcx.tcx.sess.create_err(TwoClosuresUniquelyBorrowErr { + desc, + case, + new_loan_span, + old_load_end_span, + diff_span, + }) } pub(crate) fn cannot_uniquely_borrow_by_one_closure( @@ -123,24 +122,16 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_opt_via: &str, previous_end_span: Option, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - new_loan_span, - E0500, - "closure requires unique access to {} but {} is already borrowed{}", + self.infcx.tcx.sess.create_err(ClosureUniquelyBorrowErr { + container_name, desc_new, + opt_via, noun_old, old_opt_via, - ); - 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"); - } - err + old_loan_span, + previous_end_span, + }) } pub(crate) fn cannot_reborrow_already_uniquely_borrowed( @@ -155,27 +146,17 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { previous_end_span: Option, second_borrow_desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - new_loan_span, - E0501, - "cannot borrow {}{} as {} because previous closure requires unique access", + self.infcx.tcx.sess.create_err(UniquelyBorrowReborrowErr { + container_name, desc_new, opt_via, kind_new, - ); - err.span_label( + old_opt_via, + second_borrow_desc, new_loan_span, - format!("{}borrow occurs here{}", second_borrow_desc, 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"); - } - err + previous_end_span, + }) } pub(crate) fn cannot_reborrow_already_borrowed( @@ -190,6 +171,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { msg_old: &str, old_load_end_span: Option, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { + //FIXME: would it be better for manual impl for this case? let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) }; let mut err = struct_span_err!( @@ -233,17 +215,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrow_span: Span, desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - span, - E0506, - "cannot assign to {} because it is borrowed", - desc, - ); - - err.span_label(borrow_span, format!("borrow of {} occurs here", desc)); - err.span_label(span, format!("assignment to borrowed {} occurs here", desc)); - err + self.infcx.tcx.sess.create_err(AssignBorrowErr { desc, span, borrow_span }) } pub(crate) fn cannot_reassign_immutable( @@ -252,8 +224,11 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { desc: &str, is_arg: bool, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; - struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc) + if is_arg { + self.infcx.tcx.sess.create_err(ImmuteArgAssign { desc, span }) + } else { + self.infcx.tcx.sess.create_err(ImmuteVarReassign { desc, span }) + } } pub(crate) fn cannot_assign( @@ -261,7 +236,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, span, E0594, "cannot assign to {}", desc) + self.infcx.tcx.sess.create_err(AssignErr { desc, span }) } pub(crate) fn cannot_move_out_of( @@ -269,7 +244,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, move_from_desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,) + self.infcx.tcx.sess.create_err(MovedOutErr { move_from_desc, move_from_span }) } /// Signal an error due to an attempt to move out of the interior @@ -286,16 +261,10 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { (&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 {}", - ty, - type_name, - ); - err.span_label(move_from_span, "cannot move out of here"); - err + //FIXME: failed ui test diag-migration + // - error[E0508]: cannot move out of type `[S; 1]`, a non-copy array + // + error[E0508]: cannot move out of type `S`, a non-copy array + self.infcx.tcx.sess.create_err(InteriorNoncopyMoveErr { ty, type_name, move_from_span }) } pub(crate) fn cannot_move_out_of_interior_of_drop( @@ -303,15 +272,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, container_ty: Ty<'_>, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - move_from_span, - E0509, - "cannot move out of type `{}`, which implements the `Drop` trait", - container_ty, - ); - err.span_label(move_from_span, "cannot move out of here"); - err + self.infcx.tcx.sess.create_err(InteriorDropMoveErr { container_ty, move_from_span }) } pub(crate) fn cannot_act_on_moved_value( @@ -322,18 +283,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { moved_path: Option, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default(); - - struct_span_err!( - self, - use_span, - E0382, - "{} of {}moved value{}", + self.infcx.tcx.sess.create_err(ActMovedValueErr { verb, optional_adverb_for_moved, moved_path, - ) + use_span, + }) } + //FIXME: nested with other file, replace reason with subdiag. pub(crate) fn cannot_borrow_path_as_mutable_because( &self, span: Span, @@ -351,18 +309,13 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { immutable_section: &str, action: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - mutate_span, - E0510, - "cannot {} {} in {}", + self.infcx.tcx.sess.create_err(MutateInImmute { action, immutable_place, immutable_section, - ); - err.span_label(mutate_span, format!("cannot {}", action)); - err.span_label(immutable_span, format!("value is immutable in {}", immutable_section)); - err + mutate_span, + immutable_span, + }) } pub(crate) fn cannot_borrow_across_generator_yield( @@ -370,26 +323,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, yield_span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - 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 + self.infcx.tcx.sess.create_err(BorrowAcrossGeneratorYield { span, yield_span }) } pub(crate) fn cannot_borrow_across_destructor( &self, borrow_span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!( - self, - borrow_span, - E0713, - "borrow may still be in use when destructor runs", - ) + self.infcx.tcx.sess.create_err(BorrowAcrossDestructor { borrow_span }) } pub(crate) fn path_does_not_live_long_enough( @@ -397,7 +338,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, path: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, span, E0597, "{} does not live long enough", path,) + self.infcx.tcx.sess.create_err(PathShortLive { path, span }) } pub(crate) fn cannot_return_reference_to_local( @@ -407,22 +348,12 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { reference_desc: &str, path_desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - span, - E0515, - "cannot {RETURN} {REFERENCE} {LOCAL}", - RETURN = return_kind, - REFERENCE = reference_desc, - LOCAL = path_desc, - ); - - err.span_label( + self.infcx.tcx.sess.create_err(ReturnRefLocalErr { + return_kind, + reference: reference_desc, + local: path_desc, span, - format!("{}s a {} data owned by the current function", return_kind, reference_desc), - ); - - err + }) } pub(crate) fn cannot_capture_in_long_lived_closure( @@ -432,32 +363,26 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrowed_path: &str, capture_span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, - closure_span, - E0373, - "{} may outlive the current function, but it borrows {}, which is owned by the current \ - function", + self.infcx.tcx.sess.create_err(ClosureVarOutliveErr { closure_kind, 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 + closure_span, + capture_span, + }) } pub(crate) fn thread_local_value_does_not_live_long_enough( &self, span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",) + self.infcx.tcx.sess.create_err(ThreadLocalOutliveErr { span }) } pub(crate) fn temporary_value_borrowed_for_too_long( &self, span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",) + self.infcx.tcx.sess.create_err(TemporaryDroppedErr { span }) } #[rustc_lint_diagnostics] @@ -476,11 +401,5 @@ pub(crate) fn borrowed_data_escapes_closure<'tcx>( escape_span: Span, escapes_from: &str, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - struct_span_err!( - tcx.sess, - escape_span, - E0521, - "borrowed data escapes outside of {}", - escapes_from, - ) + tcx.sess.create_err(BorrowEscapeClosure { escapes_from, escape_span }) } diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 144fd15fc2407..65fbb8da44a11 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_infer::infer::InferCtxt; use rustc_middle::mir::visit::TyContext; use rustc_middle::mir::visit::Visitor; diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index 609fbc2bc1515..a9e223cd0d592 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_data_structures::graph; use rustc_index::vec::IndexVec; use rustc_middle::mir::ConstraintCategory; diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index c94dfe39b6903..7f6ed48a477c4 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_data_structures::graph::scc::Sccs; use rustc_index::vec::IndexVec; use rustc_middle::mir::ConstraintCategory; diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index efc17a173f4d3..bb4a35f42753b 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This file provides API for compiler consumers. use rustc_hir::def_id::LocalDefId; diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 9f7a4d49989ab..8070c0e6710ee 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; use rustc_middle::mir::{self, BasicBlock, Body, Location, Place}; diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index a5c0d77429de8..8e62a0198be46 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_middle::mir::visit::{ MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index b1def189230f7..12f2b31addda6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 2f61849c383c5..9cd7ac1b07407 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + //! Print diagnostics to explain why values are borrowed. use std::collections::VecDeque; @@ -16,6 +19,10 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, DesugaringKind, Span}; use crate::region_infer::BlameConstraint; +use crate::session_diagnostics::{ + BorrowLaterBorrowUsedLaterInLoop, BorrowUsedHere, BorrowUsedLater, BorrowUsedLaterInLoop, + MustValidFor, UsedLaterDropped, +}; use crate::{ borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, WriteKind, @@ -67,20 +74,28 @@ impl<'tcx> BorrowExplanation<'tcx> { ) { match *self { BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => { - let message = match later_use_kind { - LaterUseKind::TraitCapture => "captured here by trait object", - LaterUseKind::ClosureCapture => "captured here by closure", - LaterUseKind::Call => "used by call", - LaterUseKind::FakeLetRead => "stored here", - LaterUseKind::Other => "used here", - }; // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) { if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) { - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, message), - ); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => { + BorrowUsedLater::TraitCapture { borrow_desc, span: var_or_use_span } + } + LaterUseKind::ClosureCapture => BorrowUsedLater::ClosureCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Call => { + BorrowUsedLater::Call { borrow_desc, span: var_or_use_span } + } + LaterUseKind::FakeLetRead => { + BorrowUsedLater::FakeLetRead { borrow_desc, span: var_or_use_span } + } + LaterUseKind::Other => { + BorrowUsedLater::Other { borrow_desc, span: var_or_use_span } + } + }; + err.subdiagnostic(sub_err); } } else { // path_span must be `Some` as otherwise the if condition is true @@ -88,44 +103,92 @@ impl<'tcx> BorrowExplanation<'tcx> { // path_span is only present in the case of closure capture assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture)); if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) { - let path_label = "used here by closure"; - let capture_kind_label = message; - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, capture_kind_label), - ); - err.span_label(path_span, path_label); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => { + BorrowUsedLater::TraitCapture { borrow_desc, span: var_or_use_span } + } + LaterUseKind::ClosureCapture => BorrowUsedLater::ClosureCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Call => { + BorrowUsedLater::Call { borrow_desc, span: var_or_use_span } + } + LaterUseKind::FakeLetRead => { + BorrowUsedLater::FakeLetRead { borrow_desc, span: var_or_use_span } + } + LaterUseKind::Other => { + BorrowUsedLater::Other { borrow_desc, span: var_or_use_span } + } + }; + err.subdiagnostic(sub_err); + let sub_label = BorrowUsedHere::ByClosure { path_span }; + err.subdiagnostic(sub_label); } } } BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span) => { - let message = match later_use_kind { - LaterUseKind::TraitCapture => { - "borrow captured here by trait object, in later iteration of loop" - } - LaterUseKind::ClosureCapture => { - "borrow captured here by closure, in later iteration of loop" - } - LaterUseKind::Call => "borrow used by call, in later iteration of loop", - LaterUseKind::FakeLetRead => "borrow later stored here", - LaterUseKind::Other => "borrow used here, in later iteration of loop", - }; // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) { - err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message)); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => BorrowUsedLaterInLoop::TraitCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::ClosureCapture => BorrowUsedLaterInLoop::ClosureCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Call => { + BorrowUsedLaterInLoop::Call { borrow_desc, span: var_or_use_span } + } + LaterUseKind::FakeLetRead => BorrowUsedLaterInLoop::FakeLetRead { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Other => { + BorrowUsedLaterInLoop::Other { borrow_desc, span: var_or_use_span } + } + }; + err.subdiagnostic(sub_err); + // err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message)); } else { // path_span must be `Some` as otherwise the if condition is true let path_span = path_span.unwrap(); // path_span is only present in the case of closure capture assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture)); if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) { - let path_label = "used here by closure"; - let capture_kind_label = message; - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, capture_kind_label), - ); - err.span_label(path_span, path_label); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => { + BorrowLaterBorrowUsedLaterInLoop::TraitCapture { + borrow_desc, + span: var_or_use_span, + } + } + LaterUseKind::ClosureCapture => { + BorrowLaterBorrowUsedLaterInLoop::ClosureCapture { + borrow_desc, + span: var_or_use_span, + } + } + LaterUseKind::Call => BorrowLaterBorrowUsedLaterInLoop::Call { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::FakeLetRead => { + BorrowLaterBorrowUsedLaterInLoop::FakeLetRead { + borrow_desc, + span: var_or_use_span, + } + } + LaterUseKind::Other => BorrowLaterBorrowUsedLaterInLoop::Other { + borrow_desc, + span: var_or_use_span, + }, + }; + err.subdiagnostic(sub_err); + let sub_label = BorrowUsedHere::ByClosure { path_span }; + err.subdiagnostic(sub_label); } } } @@ -161,41 +224,33 @@ impl<'tcx> BorrowExplanation<'tcx> { match local_names[dropped_local] { Some(local_name) if !local_decl.from_compiler_desugaring() => { - let message = format!( - "{B}borrow might be used here, when `{LOC}` is dropped \ - and runs the {DTOR} for {TYPE}", - B = borrow_desc, - LOC = local_name, - TYPE = type_desc, - DTOR = dtor_desc - ); - err.span_label(body.source_info(drop_loc).span, message); + let sub_label = UsedLaterDropped::UsedHere { + borrow_desc, + local_name, + type_desc: &type_desc, + dtor_desc, + span: body.source_info(drop_loc).span, + }; + err.subdiagnostic(sub_label); if should_note_order { - err.note( - "values in a scope are dropped \ - in the opposite order they are defined", - ); + let sub_note = UsedLaterDropped::OppositeOrder; + err.subdiagnostic(sub_note); } } _ => { - err.span_label( - local_decl.source_info.span, - format!( - "a temporary with access to the {B}borrow \ - is created here ...", - B = borrow_desc - ), - ); - let message = format!( - "... and the {B}borrow might be used here, \ - when that temporary is dropped \ - and runs the {DTOR} for {TYPE}", - B = borrow_desc, - TYPE = type_desc, - DTOR = dtor_desc - ); - err.span_label(body.source_info(drop_loc).span, message); + let sub_label = UsedLaterDropped::TemporaryCreatedHere { + borrow_desc, + span: local_decl.source_info.span, + }; + err.subdiagnostic(sub_label); + let sub_label_2 = UsedLaterDropped::MightUsedHere { + borrow_desc, + type_desc: &type_desc, + dtor_desc, + span: body.source_info(drop_loc).span, + }; + err.subdiagnostic(sub_label_2); if let Some(info) = &local_decl.is_block_tail { if info.tail_result_is_ignored { @@ -207,31 +262,16 @@ impl<'tcx> BorrowExplanation<'tcx> { }) .unwrap_or(false) { - err.span_suggestion_verbose( - info.span.shrink_to_hi(), - "consider adding semicolon after the expression so its \ - temporaries are dropped sooner, before the local variables \ - declared by the block are dropped", - ";", - Applicability::MaybeIncorrect, - ); + err.subdiagnostic(UsedLaterDropped::AddSemicolon { + span: info.span.shrink_to_hi(), + }); } } else { - err.note( - "the temporary is part of an expression at the end of a \ - block;\nconsider forcing this temporary to be dropped sooner, \ - before the block's local variables are dropped", - ); - err.multipart_suggestion( - "for example, you could save the expression's value in a new \ - local variable `x` and then make `x` be the expression at the \ - end of the block", - vec![ - (info.span.shrink_to_lo(), "let x = ".to_string()), - (info.span.shrink_to_hi(), "; x".to_string()), - ], - Applicability::MaybeIncorrect, - ); + err.subdiagnostic(UsedLaterDropped::ManualDrop); + err.subdiagnostic(UsedLaterDropped::MoveBlockEnd { + lo_span: info.span.shrink_to_lo(), + hi_span: info.span.shrink_to_hi(), + }); }; } } @@ -247,15 +287,13 @@ impl<'tcx> BorrowExplanation<'tcx> { region_name.highlight_region_name(err); if let Some(desc) = opt_place_desc { - err.span_label( + let sub_label = MustValidFor::Borrowed { + category: category.description(), + desc, + region_name, span, - format!( - "{}requires that `{}` is borrowed for `{}`", - category.description(), - desc, - region_name, - ), - ); + }; + err.subdiagnostic(sub_label); } else { err.span_label( span, diff --git a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs index b3edc35dc3642..498e9834354b7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::BTreeSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index b5a3081e56a7a..15f42e26cbf4a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::VecDeque; use std::rc::Rc; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 683084cf09d44..5840bdefd8d0c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1,3 +1,5 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] //! Borrow checker diagnostics. use itertools::Itertools; @@ -20,6 +22,8 @@ use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions; +use crate::session_diagnostics::{CaptureCausedBy, ClosureCannotAgain, NotImplCopy}; + use super::borrow_set::BorrowData; use super::MirBorrowckCtxt; @@ -117,14 +121,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some((span, hir_place)) = self.infcx.tcx.typeck(did).closure_kind_origins().get(hir_id) { - diag.span_note( - *span, - &format!( - "closure cannot be invoked more than once because it moves the \ - variable `{}` out of its environment", - ty::place_to_string_for_capture(self.infcx.tcx, hir_place) - ), - ); + diag.subdiagnostic(ClosureCannotAgain::Invoke { + place: ty::place_to_string_for_capture(self.infcx.tcx, hir_place), + span: *span, + }); return; } } @@ -141,14 +141,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some((span, hir_place)) = self.infcx.tcx.typeck(did).closure_kind_origins().get(hir_id) { - diag.span_note( - *span, - &format!( - "closure cannot be moved more than once as it is not `Copy` due to \ - moving the variable `{}` out of its environment", - ty::place_to_string_for_capture(self.infcx.tcx, hir_place) - ), - ); + diag.subdiagnostic(ClosureCannotAgain::Move { + place: ty::place_to_string_for_capture(self.infcx.tcx, hir_place), + span: *span, + }); } } } @@ -395,14 +391,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { span: Option, move_prefix: &str, ) { - let message = format!( - "{}move occurs because {} has type `{}`, which does not implement the `Copy` trait", - move_prefix, place_desc, ty, - ); if let Some(span) = span { - err.span_label(span, message); + err.subdiagnostic(NotImplCopy::Label { span, place_desc, ty, move_prefix }); } else { - err.note(&message); + err.subdiagnostic(NotImplCopy::Note { place_desc, ty, move_prefix }); } } @@ -986,37 +978,35 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { CallKind::FnCall { fn_trait_id, .. } if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() => { - err.span_label( - fn_call_span, - &format!( - "{} {}moved due to this call{}", - place_name, partially_str, loop_message - ), - ); - err.span_note( - var_span, - "this value implements `FnOnce`, which causes it to be moved when called", - ); + let label = CaptureCausedBy::Call { + place_name: &place_name, + partially_str, + loop_message, + span: fn_call_span, + }; + err.subdiagnostic(label); + let note = CaptureCausedBy::FnOnceVal { span: var_span }; + err.subdiagnostic(note); } CallKind::Operator { self_arg, .. } => { let self_arg = self_arg.unwrap(); - err.span_label( - fn_call_span, - &format!( - "{} {}moved due to usage in operator{}", - place_name, partially_str, loop_message - ), - ); + let label = CaptureCausedBy::OperatorUse { + place_name: &place_name, + partially_str, + loop_message, + span: fn_call_span, + }; + err.subdiagnostic(label); if self.fn_self_span_reported.insert(fn_span) { - err.span_note( + let span = // Check whether the source is accessible if self.infcx.tcx.sess.source_map().is_span_accessible(self_arg.span) { self_arg.span } else { fn_call_span - }, - "calling this operator moves the left-hand side", - ); + }; + let note = CaptureCausedBy::OperatorCall { span }; + err.subdiagnostic(note); } } CallKind::Normal { self_arg, desugaring, is_option_or_result } => { @@ -1051,13 +1041,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - err.span_label( - fn_call_span, - &format!( - "{} {}moved due to this implicit call to `.into_iter()`{}", - place_name, partially_str, loop_message - ), - ); + let label = CaptureCausedBy::ImplicitCall { + place_name: &place_name, + partially_str, + loop_message, + span: fn_call_span, + }; + err.subdiagnostic(label); // If we have a `&mut` ref, we need to reborrow. if let Some(ty::Ref(_, _, hir::Mutability::Mut)) = used_place .map(|used_place| used_place.ty(self.body, self.infcx.tcx).ty.kind()) @@ -1078,27 +1068,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } } else { - err.span_label( - fn_call_span, - &format!( - "{} {}moved due to this method call{}", - place_name, partially_str, loop_message - ), - ); + let label = CaptureCausedBy::MethodCall { + place_name: &place_name, + partially_str, + loop_message, + span: fn_call_span, + }; + err.subdiagnostic(label); } // Avoid pointing to the same function in multiple different // error messages. if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) { - err.span_note( - self_arg.span, - &format!("this function takes ownership of the receiver `self`, which moves {}", place_name) - ); + let label = CaptureCausedBy::FnTakeSelf { + place_name: &place_name, + span: self_arg.span, + }; + err.subdiagnostic(label); } if is_option_or_result && maybe_reinitialized_locations_is_empty { - err.span_label( - var_span, - "help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents", - ); + let label = CaptureCausedBy::ConsiderManualBorrow { span: var_span }; + err.subdiagnostic(label); } } // Other desugarings takes &self, which cannot cause a move @@ -1106,10 +1095,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { if move_span != span || !loop_message.is_empty() { - err.span_label( - move_span, - format!("value {}moved{} here{}", partially_str, move_msg, loop_message), - ); + let label = CaptureCausedBy::ValueHere { + move_msg, + partially_str, + loop_message, + span: move_span, + }; + err.subdiagnostic(label); } // If the move error occurs due to a loop, don't show // another message for the same span diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 16c2f9ccc6aa4..b44d7fed87f73 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_middle::mir::*; use rustc_middle::ty; @@ -8,6 +11,7 @@ use rustc_span::Span; use crate::diagnostics::{DescribePlaceOpt, UseSpans}; use crate::prefixes::PrefixSet; +use crate::session_diagnostics::AddMoveErr; use crate::MirBorrowckCtxt; // Often when desugaring a pattern match we may have many individual moves in @@ -503,9 +507,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let binding_span = bind_to.source_info.span; if j == 0 { - err.span_label(binding_span, "data moved here"); + err.subdiagnostic(AddMoveErr::Here { binding_span }); } else { - err.span_label(binding_span, "...and here"); + err.subdiagnostic(AddMoveErr::AndHere { binding_span }); } if binds_to.len() == 1 { @@ -520,10 +524,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } if binds_to.len() > 1 { - err.note( - "move occurs because these variables have types that \ - don't implement the `Copy` trait", - ); + err.subdiagnostic(AddMoveErr::MovedNotCopy); } } } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 2c6c461267a91..8a27462b62553 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{ Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, }; @@ -19,6 +22,7 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, BytePos, Span}; use crate::diagnostics::BorrowedContentSource; +use crate::session_diagnostics::{FnMutBumpFn, ShowMutatingUpvar}; use crate::MirBorrowckCtxt; use rustc_const_eval::util::collect_writes::FindAssignments; @@ -864,14 +868,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { bug!("not an upvar") }; - err.span_label( - *span, - format!( - "calling `{}` requires mutable binding due to {}", - self.describe_place(the_place_err).unwrap(), - reason - ), - ); + let place = self.describe_place(the_place_err).unwrap(); + let sub_label = ShowMutatingUpvar::RequireMutableBinding { place, reason, span: *span }; + err.subdiagnostic(sub_label); } } @@ -969,7 +968,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected. fn expected_fn_found_fn_mut_call(&self, err: &mut Diagnostic, sp: Span, act: &str) { - err.span_label(sp, format!("cannot {act}")); + err.subdiagnostic(FnMutBumpFn::Cannot { act, sp }); let hir = self.infcx.tcx.hir(); let closure_id = self.mir_hir_id(); @@ -1022,9 +1021,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { _ => None, }; if let Some(span) = arg { - err.span_label(span, "change this to accept `FnMut` instead of `Fn`"); - err.span_label(func.span, "expects `Fn` instead of `FnMut`"); - err.span_label(self.body.span, "in this closure"); + err.subdiagnostic(FnMutBumpFn::AcceptFnMut { span }); + err.subdiagnostic(FnMutBumpFn::AcceptFn { span: func.span }); + err.subdiagnostic(FnMutBumpFn::Here { span: self.body.span }); look_at_return = false; } } @@ -1045,12 +1044,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { kind: hir::ImplItemKind::Fn(sig, _), .. }) => { - err.span_label(ident.span, ""); - err.span_label( - sig.decl.output.span(), - "change this to return `FnMut` instead of `Fn`", - ); - err.span_label(self.body.span, "in this closure"); + err.subdiagnostic(FnMutBumpFn::EmptyLabel { span: ident.span }); + err.subdiagnostic(FnMutBumpFn::ReturnFnMut { span: sig.decl.output.span() }); + err.subdiagnostic(FnMutBumpFn::Here { span: self.body.span }); } _ => {} } diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 35c3df768995a..d1eebd4c93789 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -1,3 +1,5 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] //! Contains utilities for generating suggestions for borrowck errors related to unsatisfied //! outlives constraints. @@ -7,7 +9,7 @@ use rustc_middle::ty::RegionVid; use smallvec::SmallVec; use std::collections::BTreeMap; -use crate::MirBorrowckCtxt; +use crate::{session_diagnostics::OnLifetimeBound, MirBorrowckCtxt}; use super::{ErrorConstraintInfo, RegionName, RegionNameSource}; @@ -171,9 +173,7 @@ impl OutlivesSuggestionBuilder { if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) && !matches!(outlived_fr_name.source, RegionNameSource::Static) { - diag.help(&format!( - "consider adding the following bound: `{fr_name}: {outlived_fr_name}`", - )); + diag.subdiagnostic(OnLifetimeBound::Add { fr_name: &fr_name, outlived_fr_name: &outlived_fr_name }); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 75fde53b6cdec..f2b7a0f46878f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + use std::fmt::{self, Display}; use std::iter; @@ -10,6 +13,7 @@ use rustc_middle::ty::{self, DefIdTree, RegionVid, Ty}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use crate::session_diagnostics::RegionNameLabels; use crate::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; /// A name for a particular region used in emitting diagnostics. This name could be a generated @@ -133,48 +137,58 @@ impl RegionName { RegionNameHighlight::MatchedAdtAndSegment(span), _, ) => { - diag.span_label(*span, format!("let's call this `{self}`")); + diag.subdiagnostic(RegionNameLabels::NameRegion { span: *span, rg_name: self }); } RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::Occluded( span, type_name, )) => { - diag.span_label( - *span, - format!("lifetime `{self}` appears in the type {type_name}"), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInType { + span: *span, + type_name: &type_name, + rg_name: self, + }); } RegionNameSource::AnonRegionFromOutput( RegionNameHighlight::Occluded(span, type_name), mir_description, ) => { - diag.span_label( - *span, - format!( - "return type{mir_description} `{type_name}` contains a lifetime `{self}`" - ), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInReturned { + span: *span, + mir_description, + type_name: &type_name, + rg_name: self, + }); } RegionNameSource::AnonRegionFromUpvar(span, upvar_name) => { - diag.span_label( - *span, - format!("lifetime `{self}` appears in the type of `{upvar_name}`"), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInTypeOf { + span: *span, + upvar_name: upvar_name.to_ident_string(), + rg_name: self, + }); } RegionNameSource::AnonRegionFromOutput( RegionNameHighlight::CannotMatchHirTy(span, type_name), mir_description, ) => { - diag.span_label(*span, format!("return type{mir_description} is {type_name}")); + diag.subdiagnostic(RegionNameLabels::ReturnTypeIsTpye { + span: *span, + mir_description, + type_name: &type_name, + }); } RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { - diag.span_label(*span, format!("yield type is {type_name}")); + diag.subdiagnostic(RegionNameLabels::YieldTypeIsTpye { + span: *span, + type_name: &type_name, + }); } RegionNameSource::AnonRegionFromImplSignature(span, location) => { - diag.span_label( - *span, - format!("lifetime `{self}` appears in the `impl`'s {location}"), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInImpl { + span: *span, + rg_name: self, + location: &location, + }); } RegionNameSource::Static => {} } diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 9ba29f04b1a9a..b385f95b67c6f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use crate::Upvar; use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; use rustc_index::vec::{Idx, IndexVec}; diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index 22134d5a71ce1..51ed27c167d38 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::location::{LocationIndex, LocationTable}; use crate::BorrowIndex; use polonius_engine::AllFacts as PoloniusFacts; diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 3157f861d93be..f5317a143aed7 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::graph::dominators::Dominators; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue}; diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 5ca3f2f4d033c..9e683ddd977ce 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::{BasicBlock, Body, Location}; diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index 43253a2aab00c..b48f9f97daad8 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::IndexVec; diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 0961203d76d7d..abe6e325716d1 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! The entry point of the NLL borrow checker. use rustc_data_structures::vec_map::VecMap; diff --git a/compiler/rustc_borrowck/src/path_utils.rs b/compiler/rustc_borrowck/src/path_utils.rs index b2c8dfc82c206..f8a99a2699e6f 100644 --- a/compiler/rustc_borrowck/src/path_utils.rs +++ b/compiler/rustc_borrowck/src/path_utils.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; use crate::places_conflict; use crate::AccessDepth; diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs index 93d202e49a159..9f6b1fdfcb540 100644 --- a/compiler/rustc_borrowck/src/place_ext.rs +++ b/compiler/rustc_borrowck/src/place_ext.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::borrow_set::LocalsStateAtExit; use rustc_hir as hir; use rustc_middle::mir::ProjectionElem; diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 6e5a96bee97e6..c49d62ab93e91 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::ArtificialField; use crate::Overlap; use crate::{AccessDepth, Deep, Shallow}; diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index bdf2becb71126..45f99882b379c 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an //! place are formed by stripping away fields and derefs, except that //! we stop when we reach the deref of a shared reference. [...] " diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs index fe5193102f958..649ca4ab8b48b 100644 --- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs +++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! As part of generating the regions, if you enable `-Zdump-mir=nll`, //! we will generate an annotated copy of the MIR that includes the //! state of region inference. This code handles emitting the region diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index f31ccd74ca6f7..2e15586e03b3b 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This module provides linkage between RegionInferenceContext and //! `rustc_graphviz` traits, specialized to attaching borrowck analysis //! data to rendered labels. diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 8dc9368a0b994..cfc3f20e8001d 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::VecDeque; use std::rc::Rc; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 0392367288c40..62430bb003915 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::vec_map::VecMap; use rustc_hir::def_id::LocalDefId; @@ -16,7 +19,9 @@ use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::TraitEngineExt as _; -use crate::session_diagnostics::ConstNotUsedTraitAlias; +use crate::session_diagnostics::{ + ConstNotUsedTraitAlias, OpaqueTyDefineErrCause, OpaqueTypeNotDefine, UnusedTypeParameter, +}; use super::RegionInferenceContext; @@ -374,15 +379,12 @@ fn check_opaque_type_parameter_valid( let arg_is_param = match arg.unpack() { GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Lifetime(lt) if lt.is_static() => { - tcx.sess - .struct_span_err(span, "non-defining opaque type use in defining scope") - .span_label( - tcx.def_span(opaque_generics.param_at(i, tcx).def_id), - "cannot use static lifetime; use a bound lifetime \ - instead or remove the lifetime parameter from the \ - opaque type", - ) - .emit(); + tcx.sess.emit_err(OpaqueTypeNotDefine { + cause: OpaqueTyDefineErrCause::UsedStaticLifetime { + span: tcx.def_span(opaque_generics.param_at(i, tcx).def_id), + }, + span, + }); return false; } GenericArgKind::Lifetime(lt) => { @@ -396,17 +398,14 @@ fn check_opaque_type_parameter_valid( } else { // Prevent `fn foo() -> Foo` from being defining. let opaque_param = opaque_generics.param_at(i, tcx); - tcx.sess - .struct_span_err(span, "non-defining opaque type use in defining scope") - .span_note( - tcx.def_span(opaque_param.def_id), - &format!( - "used non-generic {} `{}` for generic parameter", - opaque_param.kind.descr(), - arg, - ), - ) - .emit(); + tcx.sess.emit_err(OpaqueTypeNotDefine { + cause: OpaqueTyDefineErrCause::NonGenericUsed { + span: tcx.def_span(opaque_param.def_id), + descr: opaque_param.kind.descr().to_string(), + arg: arg.to_string(), + }, + span, + }); return false; } } @@ -418,6 +417,7 @@ fn check_opaque_type_parameter_valid( .into_iter() .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) .collect(); + //FIXME: wait for lists? tcx.sess .struct_span_err(span, "non-defining opaque type use in defining scope") .span_note(spans, &format!("{} used multiple times", descr)) @@ -525,18 +525,13 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { self.tcx.lifetimes.re_root_empty } None => { - self.tcx - .sess - .struct_span_err(self.span, "non-defining opaque type use in defining scope") - .span_label( - self.span, - format!( - "lifetime `{}` is part of concrete type but not used in \ - parameter list of the `impl Trait` type alias", - r - ), - ) - .emit(); + self.tcx.sess.emit_err(OpaqueTypeNotDefine { + cause: OpaqueTyDefineErrCause::UnusedLifetime { + span: self.span, + r: r.to_string(), + }, + span: self.span, + }); self.tcx().lifetimes.re_static } @@ -608,17 +603,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(u) => panic!("type mapped to unexpected kind: {:?}", u), None => { debug!(?param, ?self.map); - self.tcx - .sess - .struct_span_err( - self.span, - &format!( - "type parameter `{}` is part of concrete type but not \ - used in parameter list for the `impl Trait` type alias", - ty - ), - ) - .emit(); + self.tcx.sess.emit_err(UnusedTypeParameter { ty, span: self.span }); self.tcx().ty_error() } diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 1e6798eee3df8..167f664609698 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::constraints::ConstraintSccIndex; use crate::RegionInferenceContext; use itertools::Itertools; diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index de20a4bb465c2..7498ddccf196a 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxIndexSet; use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::IntervalSet; diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 7a8ce621c5d0b..57ddda92d8fc3 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_index::vec::IndexVec; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::mir::visit::{MutVisitor, TyContext}; diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 5d750c6ca8c7b..b119164102dc3 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,7 +1,7 @@ use rustc_errors::{IntoDiagnosticArg, MultiSpan}; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use crate::diagnostics::RegionName; @@ -157,3 +157,681 @@ pub(crate) enum RequireStaticErr { multi_span: MultiSpan, }, } + +#[derive(SessionSubdiagnostic)] +pub(crate) enum AddMoveErr { + #[label(borrowck::data_moved_here)] + Here { + #[primary_span] + binding_span: Span, + }, + #[label(borrowck::and_data_moved_here)] + AndHere { + #[primary_span] + binding_span: Span, + }, + #[note(borrowck::moved_var_cannot_copy)] + MovedNotCopy, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowUsedHere { + #[label(borrowck::used_here_by_closure)] + ByClosure { + #[primary_span] + path_span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowUsedLater<'a> { + #[label(borrowck::borrow_later_captured_by_trait_object)] + TraitCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::borrow_later_captured_by_closure)] + ClosureCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::borrow_later_used_by_call)] + Call { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::borrow_later_stored_here)] + FakeLetRead { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::borrow_later_used_here)] + Other { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowUsedLaterInLoop<'a> { + #[label(borrowck::trait_capture_borrow_in_later_iteration_loop)] + TraitCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::closure_capture_borrow_in_later_iteration_loop)] + ClosureCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::call_used_borrow_in_later_iteration_loop)] + Call { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::borrow_later_stored_here)] + FakeLetRead { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::used_borrow_in_later_iteration_loop)] + Other { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowLaterBorrowUsedLaterInLoop<'a> { + #[label(borrowck::bl_trait_capture_borrow_in_later_iteration_loop)] + TraitCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::bl_closure_capture_borrow_in_later_iteration_loop)] + ClosureCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::call_used_borrow_in_later_iteration_loop)] + Call { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::bl_borrow_later_stored_here)] + FakeLetRead { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::bl_used_borrow_in_later_iteration_loop)] + Other { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum UsedLaterDropped<'a> { + #[label(borrowck::drop_local_might_cause_borrow)] + UsedHere { + borrow_desc: &'a str, + local_name: Symbol, + type_desc: &'a str, + dtor_desc: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck::var_dropped_in_wrong_order)] + OppositeOrder, + #[label(borrowck::temporary_access_to_borrow)] + TemporaryCreatedHere { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::drop_temporary_might_cause_borrow_use)] + MightUsedHere { + borrow_desc: &'a str, + type_desc: &'a str, + dtor_desc: &'a str, + #[primary_span] + span: Span, + }, + #[suggestion_verbose( + borrowck::consider_add_semicolon, + applicability = "maybe-incorrect", + code = ";" + )] + AddSemicolon { + #[primary_span] + span: Span, + }, + #[multipart_suggestion( + borrowck::consider_move_expression_end_of_block, + applicability = "maybe-incorrect" + )] + MoveBlockEnd { + #[suggestion_part(code = "let x = ")] + lo_span: Span, + #[suggestion_part(code = "; x")] + hi_span: Span, + }, + #[note(borrowck::consider_forcing_temporary_drop_sooner)] + ManualDrop, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum MustValidFor<'a> { + #[label(borrowck::outlive_constraint_need_borrow_for)] + Borrowed { + category: &'a str, + desc: &'a str, + region_name: &'a RegionName, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum OnLifetimeBound<'a> { + #[help(borrowck::consider_add_lifetime_bound)] + Add { fr_name: &'a RegionName, outlived_fr_name: &'a RegionName }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum ClosureCannotAgain { + #[note(borrowck::closure_cannot_invoke_again)] + Invoke { + place: String, + #[primary_span] + span: Span, + }, + #[note(borrowck::closure_cannot_move_again)] + Move { + place: String, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum ShowMutatingUpvar { + #[label(borrowck::require_mutable_binding)] + RequireMutableBinding { + place: String, + reason: String, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum CaptureCausedBy<'a> { + #[label(borrowck::moved_by_call)] + Call { + place_name: &'a str, + partially_str: &'a str, + loop_message: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck::moved_fnonce_value)] + FnOnceVal { + #[primary_span] + span: Span, + }, + #[label(borrowck::moved_by_operator_use)] + OperatorUse { + place_name: &'a str, + partially_str: &'a str, + loop_message: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck::lhs_moved_by_operator_call)] + OperatorCall { + #[primary_span] + span: Span, + }, + #[label(borrowck::moved_by_implicit_call)] + ImplicitCall { + place_name: &'a str, + partially_str: &'a str, + loop_message: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::moved_by_method_call)] + MethodCall { + place_name: &'a str, + partially_str: &'a str, + loop_message: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck::function_takes_self_ownership)] + FnTakeSelf { + place_name: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::consider_borrow_content_of_type)] + ConsiderManualBorrow { + #[primary_span] + span: Span, + }, + #[label(borrowck::value_moved_here)] + ValueHere { + move_msg: &'a str, + partially_str: &'a str, + loop_message: &'a str, + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum NotImplCopy<'a, 'tcx> { + #[label(borrowck::type_not_impl_Copy)] + Label { + place_desc: &'a str, + ty: Ty<'tcx>, + move_prefix: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck::type_not_impl_Copy)] + Note { place_desc: &'a str, ty: Ty<'tcx>, move_prefix: &'a str }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum FnMutBumpFn<'a> { + #[label(borrowck::cannot_act)] + Cannot { + act: &'a str, + #[primary_span] + sp: Span, + }, + #[label(borrowck::expects_fnmut_not_fn)] + AcceptFnMut { + #[primary_span] + span: Span, + }, + #[label(borrowck::expects_fn_not_fnmut)] + AcceptFn { + #[primary_span] + span: Span, + }, + #[label(borrowck::empty_label)] + EmptyLabel { + #[primary_span] + span: Span, + }, + #[label(borrowck::in_this_closure)] + Here { + #[primary_span] + span: Span, + }, + #[label(borrowck::return_fnmut)] + ReturnFnMut { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum RegionNameLabels<'a> { + #[label(borrowck::name_this_region)] + NameRegion { + #[primary_span] + span: Span, + rg_name: &'a RegionName, + }, + #[label(borrowck::lifetime_appears_in_type)] + LifetimeInType { + #[primary_span] + span: Span, + type_name: &'a str, + rg_name: &'a RegionName, + }, + #[label(borrowck::return_type_has_lifetime)] + LifetimeInReturned { + #[primary_span] + span: Span, + mir_description: &'a str, + type_name: &'a str, + rg_name: &'a RegionName, + }, + #[label(borrowck::lifetime_appears_in_type_of)] + LifetimeInTypeOf { + #[primary_span] + span: Span, + upvar_name: String, + rg_name: &'a RegionName, + }, + #[label(borrowck::return_type_is_type)] + ReturnTypeIsTpye { + #[primary_span] + span: Span, + mir_description: &'a str, + type_name: &'a str, + }, + #[label(borrowck::yield_type_is_type)] + YieldTypeIsTpye { + #[primary_span] + span: Span, + type_name: &'a str, + }, + #[label(borrowck::lifetime_appears_here_in_impl)] + LifetimeInImpl { + #[primary_span] + span: Span, + rg_name: &'a RegionName, + location: &'a str, + }, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::type_parameter_not_used_in_trait_type_alias)] +pub(crate) struct UnusedTypeParameter<'tcx> { + pub ty: Ty<'tcx>, + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::non_defining_opaque_type)] +pub(crate) struct OpaqueTypeNotDefine { + #[subdiagnostic] + pub cause: OpaqueTyDefineErrCause, + #[primary_span] + pub span: Span, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum OpaqueTyDefineErrCause { + #[label(borrowck::lifetime_not_used_in_trait_type_alias)] + UnusedLifetime { + #[primary_span] + span: Span, + r: String, + }, + #[note(borrowck::used_non_generic_for_generic)] + NonGenericUsed { + #[primary_span] + span: Span, + descr: String, + arg: String, + }, + #[label(borrowck::cannot_use_static_lifetime_here)] + UsedStaticLifetime { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum DefiningTypeNote<'a> { + #[note(borrowck::define_type_with_closure_substs)] + Closure { type_name: &'a str, subsets: &'a str }, + #[note(borrowck::define_type_with_generator_substs)] + Generator { type_name: &'a str, subsets: &'a str }, + #[note(borrowck::define_type)] + FnDef { type_name: &'a str }, + #[note(borrowck::define_const_type)] + Const { type_name: &'a str }, + #[note(borrowck::define_inline_constant_type)] + InlineConst { type_name: &'a str }, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::borrowed_temporary_value_dropped, code = "E0716")] +pub(crate) struct TemporaryDroppedErr { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::thread_local_outlive_function, code = "E0712")] +pub(crate) struct ThreadLocalOutliveErr { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::closure_borrowing_outlive_function, code = "E0373")] +pub(crate) struct ClosureVarOutliveErr<'a> { + pub closure_kind: &'a str, + pub borrowed_path: &'a str, + #[primary_span] + #[label] + pub closure_span: Span, + #[label(borrowck::path_label)] + pub capture_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_return_ref_to_local, code = "E0515")] +pub(crate) struct ReturnRefLocalErr<'a> { + pub return_kind: &'a str, + pub reference: &'a str, + pub local: &'a str, + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::path_does_not_live_long_enough, code = "E0597")] +pub(crate) struct PathShortLive<'a> { + pub path: &'a str, + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_borrow_across_destructor, code = "E0713")] +pub(crate) struct BorrowAcrossDestructor { + #[primary_span] + pub borrow_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_borrow_across_generator_yield, code = "E0626")] +pub(crate) struct BorrowAcrossGeneratorYield { + #[primary_span] + pub span: Span, + #[label] + pub yield_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_mutate_in_immutable_section, code = "E0510")] +pub(crate) struct MutateInImmute<'a> { + pub action: &'a str, + pub immutable_place: &'a str, + pub immutable_section: &'a str, + #[primary_span] + #[label] + pub mutate_span: Span, + #[label(borrowck::immutable_value_label)] + pub immutable_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_act_moved_value, code = "E0382")] +pub(crate) struct ActMovedValueErr<'a> { + pub verb: &'a str, + pub optional_adverb_for_moved: &'a str, + pub moved_path: String, + #[primary_span] + pub use_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_move_out_of_interior_of_drop, code = "E0509")] +pub(crate) struct InteriorDropMoveErr<'a> { + pub container_ty: Ty<'a>, + #[primary_span] + #[label] + pub move_from_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_move_out_of, code = "E0507")] +pub(crate) struct MovedOutErr<'a> { + pub move_from_desc: &'a str, + #[primary_span] + pub move_from_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_assign, code = "E0594")] +pub(crate) struct AssignErr<'a> { + pub desc: &'a str, + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_assign_immutable_argument, code = "E0384")] +pub(crate) struct ImmuteArgAssign<'a> { + pub desc: &'a str, + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_reassign_immutable_variable, code = "E0384")] +pub(crate) struct ImmuteVarReassign<'a> { + pub desc: &'a str, + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_assign_to_borrowed, code = "E0506")] +pub(crate) struct AssignBorrowErr<'a> { + pub desc: &'a str, + #[primary_span] + #[label] + pub span: Span, + #[label(borrowck::borrow_here_label)] + pub borrow_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_move_out_of_interior_noncopy, code = "E0508")] +pub(crate) struct InteriorNoncopyMoveErr<'a, 'b> { + pub ty: Ty<'a>, + pub type_name: &'b str, + #[primary_span] + #[label] + pub move_from_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_reborrow_already_uniquely_borrowed, code = "E0501")] +pub(crate) struct UniquelyBorrowReborrowErr<'a> { + pub container_name: &'a str, + pub desc_new: &'a str, + pub opt_via: &'a str, + pub kind_new: &'a str, + pub old_opt_via: &'a str, + pub second_borrow_desc: &'a str, + #[primary_span] + #[label] + pub new_loan_span: Span, + #[label(borrowck::old_span_label)] + pub old_loan_span: Span, + #[label(borrowck::optional_label)] + pub previous_end_span: Option, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_uniquely_borrow_by_one_closure, code = "E0501")] +pub(crate) struct ClosureUniquelyBorrowErr<'a> { + pub container_name: &'a str, + pub desc_new: &'a str, + pub opt_via: &'a str, + pub noun_old: &'a str, + pub old_opt_via: &'a str, + #[primary_span] + #[label] + pub new_loan_span: Span, + #[label(borrowck::old_span_label)] + pub old_loan_span: Span, + #[label(borrowck::optional_label)] + pub previous_end_span: Option, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::borrowed_data_escapes_closure, code = "E0521")] +pub(crate) struct BorrowEscapeClosure<'a> { + pub escapes_from: &'a str, + #[primary_span] + pub escape_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_uniquely_borrow_by_two_closures, code = "E0524")] +pub(crate) struct TwoClosuresUniquelyBorrowErr<'a> { + pub desc: &'a str, + #[subdiagnostic] + pub case: ClosureConstructLabel, + #[primary_span] + pub new_loan_span: Span, + #[label] + pub old_load_end_span: Option, + #[label(borrowck::new_span_label)] + pub diff_span: Option, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum ClosureConstructLabel { + #[label(borrowck::first_closure_constructed_here)] + First { + #[primary_span] + old_loan_span: Span, + }, + #[label(borrowck::closures_constructed_here)] + Both { + #[primary_span] + old_loan_span: Span, + }, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_use_when_mutably_borrowed, code = "E0503")] +pub(crate) struct UseMutBorrowErr<'a> { + pub desc: &'a str, + pub borrow_desc: &'a str, + #[primary_span] + #[label] + pub span: Span, + #[label(borrowck::borrow_span_label)] + pub borrow_span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::cannot_move_when_borrowed, code = "E0505")] +pub(crate) struct MoveBorrowedErr<'a> { + pub desc: &'a str, + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 29195b3922fcd..0afd92b7a707c 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use std::fmt; use rustc_infer::infer::canonical::Canonical; diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 9fab7ad914a84..40cc6f398f5bd 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_infer::infer::canonical::QueryOutlivesConstraint; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 7c10047e9dc83..d8f7501d601c1 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::frozen::Frozen; use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder}; use rustc_infer::infer::canonical::QueryRegionConstraints; diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 4431a2e8ec60d..884720674d4c7 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This module contains code to equate the input/output types appearing //! in the MIR with the expected input/output types from the function //! signature. This requires a bit of processing, as the expected types diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index fda2cee43fbf1..dd890bed651f2 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::vec_linked_list as vll; use rustc_index::vec::IndexVec; use rustc_middle::mir::visit::{PlaceContext, Visitor}; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index d5c401ae1c6ed..56e1b1b789f13 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use itertools::{Either, Itertools}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::{Body, Local}; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs index bc76a465e3c3a..0674eb424b0ac 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::def_use::{self, DefUse}; use crate::location::{LocationIndex, LocationTable}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 42b577175e437..651601925d4ef 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::bit_set::HybridBitSet; use rustc_index::interval::IntervalSet; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index fc0e95f30c98f..70d6ecfa75808 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This pass type-checks the MIR to ensure it is not broken. use std::rc::Rc; diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index c97a6a1a6587a..b2626751d5c90 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::ObligationCause; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index b9b181681ec4b..6df718ecd31cf 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + //! Code to extract the universally quantified regions declared on a //! function and the relationships between them. For example: //! @@ -27,6 +30,7 @@ use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVi use std::iter; use crate::nll::ToRegionVid; +use crate::session_diagnostics::DefiningTypeNote; #[derive(Debug)] pub struct UniversalRegions<'tcx> { @@ -339,11 +343,9 @@ impl<'tcx> UniversalRegions<'tcx> { pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { match self.defining_ty { DefiningTy::Closure(def_id, substs) => { - err.note(&format!( - "defining type: {} with closure substs {:#?}", - tcx.def_path_str_with_substs(def_id, substs), - &substs[tcx.generics_of(def_id).parent_count..], - )); + let type_name = &tcx.def_path_str_with_substs(def_id, substs); + let subsets = &format!("{:#?}", &substs[tcx.generics_of(def_id).parent_count..]); + err.subdiagnostic(DefiningTypeNote::Closure { type_name, subsets }); // FIXME: It'd be nice to print the late-bound regions // here, but unfortunately these wind up stored into @@ -356,11 +358,9 @@ impl<'tcx> UniversalRegions<'tcx> { }); } DefiningTy::Generator(def_id, substs, _) => { - err.note(&format!( - "defining type: {} with generator substs {:#?}", - tcx.def_path_str_with_substs(def_id, substs), - &substs[tcx.generics_of(def_id).parent_count..], - )); + let type_name = &tcx.def_path_str_with_substs(def_id, substs); + let subsets = &format!("{:#?}", &substs[tcx.generics_of(def_id).parent_count..]); + err.subdiagnostic(DefiningTypeNote::Generator { type_name, subsets }); // FIXME: As above, we'd like to print out the region // `r` but doing so is not stable across architectures @@ -371,22 +371,16 @@ impl<'tcx> UniversalRegions<'tcx> { }); } DefiningTy::FnDef(def_id, substs) => { - err.note(&format!( - "defining type: {}", - tcx.def_path_str_with_substs(def_id, substs), - )); + let type_name = &tcx.def_path_str_with_substs(def_id, substs); + err.subdiagnostic(DefiningTypeNote::FnDef { type_name }); } DefiningTy::Const(def_id, substs) => { - err.note(&format!( - "defining constant type: {}", - tcx.def_path_str_with_substs(def_id, substs), - )); + let type_name = &tcx.def_path_str_with_substs(def_id, substs); + err.subdiagnostic(DefiningTypeNote::Const { type_name }); } DefiningTy::InlineConst(def_id, substs) => { - err.note(&format!( - "defining inline constant type: {}", - tcx.def_path_str_with_substs(def_id, substs), - )); + let type_name = &tcx.def_path_str_with_substs(def_id, substs); + err.subdiagnostic(DefiningTypeNote::InlineConst { type_name }); } } } diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 8833753b12c5d..e297b1230ea0c 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{ diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 67f2156f32e50..63489acff503f 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -58,3 +58,288 @@ borrowck_returned_lifetime_short = borrowck_used_impl_require_static = the used `impl` has a `'static` requirement + +borrowck_data_moved_here = + data moved here + +borrowck_and_data_moved_here = ...and here + +borrowck_moved_var_cannot_copy = + move occurs because these variables have types that don't implement the `Copy` trait + +borrowck_borrow_later_captured_by_trait_object = + {$borrow_desc}borrow later captured here by trait object + +borrowck_borrow_later_captured_by_closure = + {$borrow_desc}borrow later captured here by closure + +borrowck_borrow_later_used_by_call = + {$borrow_desc}borrow later used by call + +borrowck_borrow_later_stored_here = + {$borrow_desc}borrow later stored here + +borrowck_borrow_later_used_here = + {$borrow_desc}borrow later used here + +borrowck_used_here_by_closure = + used here by closure + +borrowck_trait_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow captured here by trait object, in later iteration of loop + +borrowck_closure_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow captured here by closure, in later iteration of loop + +borrowck_call_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow used by call, in later iteration of loop + +borrowck_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow used here, in later iteration of loop + +borrowck_bl_trait_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow captured here by trait object, in later iteration of loop + +borrowck_bl_closure_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow captured here by closure, in later iteration of loop + +borrowck_bl_call_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow used by call, in later iteration of loop + +borrowck_bl_borrow_later_stored_here = + {$borrow_desc}borrow later borrow later stored here + +borrowck_bl_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow used here, in later iteration of loop + +borrowck_drop_local_might_cause_borrow = + {$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_desc} for {$type_desc} + +borrowck_var_dropped_in_wrong_order = + values in a scope are dropped in the opposite order they are defined + +borrowck_temporary_access_to_borrow = + a temporary with access to the {$borrow_desc}borrow is created here ... + +borrowck_drop_temporary_might_cause_borrow_use = ... and the {$borrow_desc}borrow might be used here, when that temporary is dropped and runs the {$dtor_desc} for {$type_desc} + +borrowck_consider_add_semicolon = + consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped + +borrowck_consider_move_expression_end_of_block = + for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block + +borrowck_consider_forcing_temporary_drop_sooner = + the temporary is part of an expression at the end of a block; + consider forcing this temporary to be dropped sooner, before the block's local variables are dropped + +borrowck_perhaps_save_in_new_local_to_drop = + for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block + +borrowck_outlive_constraint_need_borrow_for = + {$category}requires that {$desc} is borrowed for `{$region_name}` + +borrowck_consider_add_lifetime_bound = + consider adding the following bound: `{$fr_name}: {$outlived_fr_name}` + +borrowck_closure_cannot_invoke_again = + closure cannot be invoked more than once because it moves the variable `{$place}` out of its environment + +borrowck_closure_cannot_move_again = + closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place}` out of its environment + +borrowck_value_moved_here = + value {$partially_str}moved{$move_msg} here{$loop_message} + +borrowck_consider_borrow_content_of_type = + help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents + +borrowck_function_takes_self_ownership = + this function takes ownership of the receiver `self`, which moves {$place_name} + +borrowck_moved_by_method_call = + {$place_name} {$partially_str}moved due to this method call{$loop_message} + +borrowck_moved_by_implicit_call = + {$place_name} {$partially_str}moved due to this implicit call to `.into_iter()`{$loop_message} + +borrowck_lhs_moved_by_operator_call = + calling this operator moves the left-hand side + +borrowck_moved_by_operator_use = + {$place_name} {$partially_str}moved due to usage in operator{$loop_message} + +borrowck_moved_fnonce_value = + this value implements `FnOnce`, which causes it to be moved when called + +borrowck_moved_by_call = + {$place_name} {$partially_str}moved due to this call{$loop_message} + +borrowck_type_not_impl_Copy = + {$move_prefix}move occurs because {$place_desc} has type `{$ty}`, which does not implement the `Copy` trait + +borrowck_outlive_constraint_need_borrow_lasts = + {$category}requires that `{$borrow_desc}` lasts for `{$region_name}` + +borrowck_require_mutable_binding = + calling `{$place}` requires mutable binding due to {$reason} + +borrowck_cannot_act = + cannot {$act} + +borrowck_expects_fnmut_not_fn = + change this to accept `FnMut` instead of `Fn` + +borrowck_expects_fn_not_fnmut = + expects `Fn` instead of `FnMut` + +borrowck_empty_label = {""} + +borrowck_in_this_closure = + in this closure + +borrowck_return_fnmut = + change this to return `FnMut` instead of `Fn` + +borrowck_name_this_region = + let's call this `{$rg_name}` + +borrowck_lifetime_appears_in_type = + lifetime `{$rg_name}` appears in the type {$type_name} + +borrowck_return_type_has_lifetime = + return type{$mir_description} `{$type_name}` contains a lifetime `{$rg_name}` + +borrowck_lifetime_appears_in_type_of = + lifetime `{$rg_name}` appears in the type of `{$upvar_name}` + +borrowck_return_type_is_type = + return type{$mir_description} is {$type_name} + +borrowck_yield_type_is_type = + yield type is {$type_name} + +borrowck_lifetime_appears_here_in_impl = + lifetime `{$rg_name}` appears in the `impl`'s {$location} + +borrowck_type_parameter_not_used_in_trait_type_alias = + type parameter `{$ty}` is part of concrete type but not used in parameter list for the `impl Trait` type alias + +borrowck_non_defining_opaque_type = + non-defining opaque type use in defining scope + +borrowck_lifetime_not_used_in_trait_type_alias = + lifetime `{$r}` is part of concrete type but not used in parameter list of the `impl Trait` type alias + +borrowck_used_non_generic_for_generic = + used non-generic {$descr} `{$arg}` for generic parameter + +borrowck_cannot_use_static_lifetime_here = + cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type + +borrowck_define_inline_constant_type = + defining inline constant type: {$type_name} + +borrowck_define_const_type = + defining constant type: {$type_name} + +borrowck_define_type = + defining type: {$type_name} + +borrowck_define_type_with_generator_substs = + defining type: {$type_name} with generator substs {$subsets} + +borrowck_define_type_with_closure_substs = + defining type: {$type_name} with closure substs {$subsets} + +borrowck_borrowed_temporary_value_dropped = + temporary value dropped while borrowed + +borrowck_thread_local_outlive_function = + thread-local variable borrowed past end of function + +borrowck_closure_borrowing_outlive_function = + {$closure_kind} may outlive the current function, but it borrows {$borrowed_path}, which is owned by the current function + .label = may outlive borrowed value {$borrowed_path} + .path_label = {$borrowed_path} is borrowed here + +borrowck_cannot_return_ref_to_local = + cannot {$return_kind} {$reference} {$local} + .label = {$return_kind}s a {$reference} data owned by the current function + +borrowck_path_does_not_live_long_enough = + {$path} does not live long enough + +borrowck_cannot_borrow_across_destructor = + borrow may still be in use when destructor runs + +borrowck_cannot_borrow_across_generator_yield = + borrow may still be in use when generator yields + .label = possible yield occurs here + +borrowck_cannot_mutate_in_immutable_section = + cannot {$action} {$immutable_place} in {$immutable_section} + .label = cannot {$action} + .immutable_value_label = value is immutable in {$immutable_section} + +borrowck_cannot_act_moved_value = + {$verb} of {$optional_adverb_for_moved}moved value{$moved_path} + +borrowck_cannot_move_out_of_interior_of_drop = + cannot move out of type `{$container_ty}`, which implements the `Drop` trait + .label = cannot move out of here + +borrowck_cannot_move_out_of = + cannot move out of {$move_from_desc} + +borrowck_cannot_assign = + cannot assign to {$desc} + +borrowck_cannot_assign_immutable_argument = + cannot assign to immutable argument {$desc} + +borrowck_cannot_reassign_immutable_variable = + cannot assign twice to immutable variable {$desc} + +borrowck_cannot_assign_to_borrowed = + cannot assign to {$desc} because it is borrowed + .label = assignment to borrowed {$desc} occurs here + .borrow_here_label = borrow of {$desc} occurs here + +borrowck_cannot_move_out_of_interior_noncopy = + cannot move out of type `{$ty}`, a non-copy {$type_name} + .label = cannot move out of here + +borrowck_cannot_reborrow_already_uniquely_borrowed = + cannot borrow {$desc_new}{$opt_via} as {$kind_new} because previous closure requires unique access + .label = {$second_borrow_desc}borrow occurs here{$opt_via} + .old_span_label = {$container_name} construction occurs here{$old_opt_via} + .optional_label = borrow from closure ends here + +borrowck_cannot_uniquely_borrow_by_one_closure = + closure requires unique access to {$desc_new} but {$noun_old} is already borrowed{$old_opt_via} + .label = {$container_name} construction occurs here{$opt_via} + .old_span_label = borrow occurs here{$old_opt_via} + .optional_label = borrow ends here + +borrowck_borrowed_data_escapes_closure = + borrowed data escapes outside of {$escapes_from} + +borrowck_cannot_uniquely_borrow_by_two_closures = + two closures require unique access to {$desc} at the same time + .label = borrow from first closure ends here + .new_span_label = second closure is constructed here + +borrowck_first_closure_constructed_here = + first closure is constructed here + +borrowck_closures_constructed_here = + closures are constructed here in different iterations of loop + +borrowck_cannot_use_when_mutably_borrowed = + cannot use {$desc} because it was mutably borrowed + .label = use of borrowed {$borrow_desc} + .borrow_span_label = borrow of {$borrow_desc} occurs here + +borrowck_cannot_move_when_borrowed = + cannot move out of {$desc} because it is borrowed