diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 4fcb5f3b5a94d..e6841f5fd9e2c 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -2,12 +2,12 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, struct_span_code_err}; use rustc_hir as hir; use rustc_middle::span_bug; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty}; use rustc_span::Span; -impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { - pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> { - self.infcx.dcx() +impl<'diag, 'tcx> crate::MirBorrowckCtxt<'_, 'diag, 'tcx> { + pub(crate) fn dcx(&self) -> DiagCtxtHandle<'diag> { + self.root_cx.dcx() } pub(crate) fn cannot_move_when_borrowed( @@ -17,7 +17,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { place: &str, borrow_place: &str, value_place: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { self.dcx().create_err(crate::session_diagnostics::MoveBorrow { place, span, @@ -33,7 +33,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { desc: &str, borrow_span: Span, borrow_desc: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), span, @@ -53,7 +53,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -100,7 +100,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { desc: &str, old_loan_span: Span, old_load_end_span: Option, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -133,7 +133,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -165,7 +165,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -197,7 +197,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { kind_old: &str, msg_old: &str, old_load_end_span: Option, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -238,7 +238,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { span: Span, borrow_span: Span, desc: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), span, @@ -255,12 +255,12 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { span: Span, desc: &str, is_arg: bool, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) } - pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx> { + pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'diag> { struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) } @@ -268,7 +268,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { &self, move_from_span: Span, move_from_desc: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), move_from_span, @@ -286,7 +286,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { move_from_span: Span, ty: Ty<'_>, is_index: Option, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let type_name = match (ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", @@ -307,7 +307,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { &self, move_from_span: Span, container_ty: Ty<'_>, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), move_from_span, @@ -325,7 +325,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { optional_adverb_for_moved: &str, moved_path: Option, primary_message: Option, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { if let Some(primary_message) = primary_message { struct_span_code_err!(self.dcx(), use_span, E0382, "{}", primary_message) } else { @@ -348,7 +348,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { span: Span, path: &str, reason: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), span, @@ -366,7 +366,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { immutable_place: &str, immutable_section: &str, action: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), mutate_span, @@ -384,7 +384,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { &self, span: Span, yield_span: Span, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; let mut diag = struct_span_code_err!( self.dcx(), @@ -418,7 +418,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { diag } - pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> { + pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'diag> { struct_span_code_err!( self.dcx(), borrow_span, @@ -427,7 +427,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) } - pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> { + pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'diag> { struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path) } @@ -437,7 +437,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { return_kind: &str, reference_desc: &str, path_desc: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), span, @@ -460,7 +460,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { borrowed_path: &str, capture_span: Span, scope: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { struct_span_code_err!( self.dcx(), closure_span, @@ -472,7 +472,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) } - pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'infcx> { + pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'diag> { struct_span_code_err!( self.dcx(), span, @@ -481,18 +481,18 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) } - pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> { + pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'diag> { struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed") } } -pub(crate) fn borrowed_data_escapes_closure<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn borrowed_data_escapes_closure<'diag>( + dcx: DiagCtxtHandle<'diag>, escape_span: Span, escapes_from: &str, -) -> Diag<'tcx> { +) -> Diag<'diag> { struct_span_code_err!( - tcx.dcx(), + dcx, escape_span, E0521, "borrowed data escapes outside of {}", diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 548973714105b..c84ab854340fb 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -125,8 +125,13 @@ pub fn get_bodies_with_borrowck_facts( root_def_id: LocalDefId, options: ConsumerOptions, ) -> FxHashMap> { - let mut root_cx = - BorrowCheckRootCtxt::new(tcx, root_def_id, Some(BorrowckConsumer::new(options))); + let tainted_by_errors = Default::default(); + let mut root_cx = BorrowCheckRootCtxt::new( + tcx, + root_def_id, + Some(BorrowckConsumer::new(options)), + &tainted_by_errors, + ); root_cx.do_mir_borrowck(); root_cx.consumer.unwrap().bodies } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 538c5887118e6..0ce966bc39624 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -137,13 +137,13 @@ pub(crate) trait TypeOpInfo<'tcx> { fn base_universe(&self) -> ty::UniverseIndex; - fn nice_error<'infcx>( + fn nice_error<'diag>( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; /// Constraints require that `error_element` appear in the /// values of `placeholder`, but this cannot be proven to @@ -213,13 +213,13 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { self.base_universe } - fn nice_error<'infcx>( + fn nice_error<'diag>( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -257,13 +257,13 @@ where self.base_universe } - fn nice_error<'infcx>( + fn nice_error<'diag>( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -310,13 +310,13 @@ where self.base_universe } - fn nice_error<'infcx>( + fn nice_error<'diag>( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -351,13 +351,13 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { self.base_universe } - fn nice_error<'infcx>( + fn nice_error<'diag>( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -384,13 +384,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { self.base_universe.unwrap() } - fn nice_error<'infcx>( + fn nice_error<'diag>( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, mbcx.mir_def_id(), @@ -404,6 +404,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { |vid| RegionVariableOrigin::Nll(mbcx.regioncx.definitions[vid].origin), |vid| mbcx.regioncx.definitions[vid].universe, ) + .map(|d| d.with_dcx(mbcx.dcx())) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 86e5a6700b039..68881326f23bb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -69,7 +69,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -352,7 +352,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn suggest_ref_or_clone( &self, mpi: MovePathIndex, - err: &mut Diag<'infcx>, + err: &mut Diag<'_>, move_spans: UseSpans<'tcx>, moved_place: PlaceRef<'tcx>, has_suggest_reborrow: &mut bool, @@ -589,7 +589,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { body: &hir::Expr<'_>, place: &Place<'tcx>, move_span: Span, - err: &mut Diag<'infcx>, + err: &mut Diag<'_>, ) { let var_info = self.body.var_debug_info.iter().find(|info| match info.value { VarDebugInfoContents::Place(ref p) => p == place, @@ -633,7 +633,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn suggest_reborrow( &self, - err: &mut Diag<'infcx>, + err: &mut Diag<'_>, span: Span, moved_place: PlaceRef<'tcx>, ) { @@ -828,7 +828,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { location: Location, span: Span, use_spans: UseSpans<'tcx>, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { // We need all statements in the body where the binding was assigned to later find all // the branching code paths where the binding *wasn't* assigned to. let inits = &self.move_data.init_path_map[mpi]; @@ -1758,7 +1758,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); @@ -1803,7 +1803,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_span = issued_spans.args_or_use(); @@ -2093,7 +2093,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { err } - fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'infcx>, place: Place<'tcx>) { + fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'_>, place: Place<'tcx>) { let tcx = self.infcx.tcx; let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; @@ -3141,7 +3141,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let borrow_span = borrow_spans.var_or_use_path_span(); if let BorrowExplanation::MustBeValidFor { category, @@ -3318,7 +3318,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { &self, drop_span: Span, borrow_span: Span, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { debug!( "report_thread_local_value_does_not_live_long_enough(\ {:?}, {:?}\ @@ -3355,7 +3355,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { @@ -3509,7 +3509,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, - ) -> Result<(), Diag<'infcx>> { + ) -> Result<(), Diag<'diag>> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", @@ -3627,7 +3627,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { constraint_span: Span, captured_var: &str, scope: &str, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -3745,13 +3745,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { upvar_span: Span, upvar_name: Symbol, escape_span: Span, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let tcx = self.infcx.tcx; let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); let mut err = - borrowck_errors::borrowed_data_escapes_closure(tcx, escape_span, escapes_from); + borrowck_errors::borrowed_data_escapes_closure(self.dcx(), escape_span, escapes_from); err.span_label( upvar_span, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a5b7a26a10ab4..438c2e4662028 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex}; use rustc_span::def_id::LocalDefId; -use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Spanned, Symbol, sym}; +use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::traits::call_kind::{CallDesugaringKind, call_kind}; use rustc_trait_selection::infer::InferCtxtExt; @@ -74,12 +74,12 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -enum BufferedDiag<'infcx> { - Error(Diag<'infcx>), - NonError(Diag<'infcx, ()>), +pub(crate) enum BufferedDiag<'diag> { + Error(Diag<'diag>), + NonError(Diag<'diag, ()>), } -impl<'infcx> BufferedDiag<'infcx> { +impl<'diag> BufferedDiag<'diag> { fn sort_span(&self) -> Span { match self { BufferedDiag::Error(diag) => diag.sort_span, @@ -89,7 +89,7 @@ impl<'infcx> BufferedDiag<'infcx> { } #[derive(Default)] -pub(crate) struct BorrowckDiagnosticsBuffer<'infcx, 'tcx> { +pub(crate) struct BorrowckDiagnosticsBuffer<'diag, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -104,25 +104,23 @@ pub(crate) struct BorrowckDiagnosticsBuffer<'infcx, 'tcx> { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'diag>)>, - buffered_mut_errors: FxIndexMap, usize)>, + buffered_mut_errors: FxIndexMap, usize)>, /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, + buffered_diags: Vec>, } -impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> { - pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { +impl<'diag, 'tcx> BorrowckDiagnosticsBuffer<'diag, 'tcx> { + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'diag, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { + pub(crate) fn buffer_error(&mut self, diag: Diag<'diag>) { self.buffered_diags.push(BufferedDiag::Error(diag)); } - pub(crate) fn emit_errors(&mut self) -> Option { - let mut res = None; - + pub(crate) fn emit_errors(&mut self) { // Buffer any move errors that we collected and de-duplicated. for (_, (_, diag)) in std::mem::take(&mut self.buffered_move_errors) { // We have already set tainted for this error, so just buffer it. @@ -139,29 +137,29 @@ impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> { self.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); for buffered_diag in self.buffered_diags.drain(..) { match buffered_diag { - BufferedDiag::Error(diag) => res = Some(diag.emit()), + BufferedDiag::Error(diag) => { + diag.emit(); + } BufferedDiag::NonError(diag) => diag.emit(), } } } - - res } } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.diags_buffer.buffer_error(diag); +impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { + pub(crate) fn buffer_error(&mut self, diag: Diag<'_>) { + self.diags_buffer.buffer_error(diag.with_dcx(self.dcx())); } - pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { - self.diags_buffer.buffer_non_error(diag); + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'_, ()>) { + self.diags_buffer.buffer_non_error(diag.with_dcx(self.dcx())); } pub(crate) fn buffer_move_error( &mut self, move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), + place_and_err: (PlaceRef<'tcx>, Diag<'diag>), ) -> bool { if let Some((_, diag)) = self.diags_buffer.buffered_move_errors.insert(move_out_indices, place_and_err) @@ -174,12 +172,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } - pub(crate) fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { + pub(crate) fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'diag>, usize)> { // FIXME(#120456) - is `swap_remove` correct? self.diags_buffer.buffered_mut_errors.swap_remove(&span) } - pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { + pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'diag>, count: usize) { self.diags_buffer.buffered_mut_errors.insert(span, (diag, count)); } @@ -190,7 +188,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn has_move_error( &self, move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { + ) -> Option<&(PlaceRef<'tcx>, Diag<'diag>)> { self.diags_buffer.buffered_move_errors.get(move_out_indices) } @@ -225,7 +223,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -241,7 +239,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { &self, location: Location, place: PlaceRef<'tcx>, - diag: &mut Diag<'infcx>, + diag: &mut Diag<'_>, ) -> bool { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); let mut target = place.local_or_deref_local(); @@ -1020,7 +1018,7 @@ pub(super) enum CloneSuggestion { NotEmitted, } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, @@ -1238,7 +1236,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn explain_captures( &mut self, - err: &mut Diag<'infcx>, + err: &mut Diag<'_>, span: Span, move_span: Span, move_spans: UseSpans<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index cc02206c50649..114502b62783c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -102,7 +102,7 @@ struct PatternBindingInfo { has_mutable_by_value_binding: bool, } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { @@ -310,7 +310,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && self.infcx.tcx.ensure_result().coherent_trait(copy_def_id).is_err() } - fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> { + fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'diag> { let description = if place.projection.len() == 1 { format!("static item {}", self.describe_any_place(place.as_ref())) } else { @@ -439,7 +439,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, - ) -> (Diag<'infcx>, CloneSuggestion) { + ) -> (Diag<'diag>, CloneSuggestion) { let tcx = self.infcx.tcx; // Inspect the type of the content behind the // borrow to provide feedback about why this @@ -573,7 +573,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { closure_kind_ty: Ty<'tcx>, upvar_field: FieldIdx, asyncness: ty::Asyncness, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let tcx = self.infcx.tcx; let closure_kind = match closure_kind_ty.to_opt_closure_kind() { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index a4025f28a5511..ec33030f90960 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -58,7 +58,7 @@ fn find_assignments(body: &Body<'_>, local: Local) -> Vec { visitor.locations } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, @@ -655,7 +655,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } /// Suggest `map[k] = v` => `map.insert(k, v)` and the like. - fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'infcx>, span: Span) { + fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'_>, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) @@ -664,15 +664,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// Walks through the HIR, looking for the corresponding span for this error. /// When it finds it, see if it corresponds to assignment operator whose LHS /// is an index expr. - struct SuggestIndexOperatorAlternativeVisitor<'a, 'infcx, 'tcx> { + struct SuggestIndexOperatorAlternativeVisitor<'a, 'diag, 'tcx> { assign_span: Span, - err: &'a mut Diag<'infcx>, + err: &'a mut Diag<'diag>, ty: Ty<'tcx>, suggested: bool, infcx: &'a rustc_infer::infer::InferCtxt<'tcx>, } - impl<'a, 'infcx, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'infcx, 'tcx> { + impl<'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'_, '_, 'tcx> { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { hir::intravisit::walk_stmt(self, stmt); let expr = match stmt.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs index da947376446cb..009dff77efd0f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs @@ -21,7 +21,7 @@ use crate::consumers::RegionInferenceContext; use crate::region_infer::opaque_types::DeferredOpaqueTypeError; use crate::type_check::Locations; -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { pub(crate) fn report_opaque_type_errors(&mut self, errors: Vec>) { if errors.is_empty() { return; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index a82cd5c74c330..0b1e893eee767 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -189,7 +189,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } -impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { +impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { // For generic associated types (GATs) which implied 'static requirement // from higher-ranked trait bounds (HRTB). Try to locate span of the trait // and the span which bounded to the trait for adding 'static lifetime suggestion @@ -606,7 +606,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { &self, errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, - ) -> Diag<'infcx> { + ) -> Diag<'diag> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -675,7 +675,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` #[instrument(level = "debug", skip(self))] - fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'diag> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -709,7 +709,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } let mut diag = - borrowck_errors::borrowed_data_escapes_closure(self.infcx.tcx, *span, escapes_from); + borrowck_errors::borrowed_data_escapes_closure(self.dcx(), *span, escapes_from); if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { diag.span_label( @@ -786,7 +786,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it /// | is returning data with lifetime `'b` /// ``` - fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'diag> { let ErrorConstraintInfo { fr, outlived_fr, span, category, .. } = errci; let mir_def_name = self.infcx.tcx.def_descr(self.mir_def_id().to_def_id()); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 9d66863ef70e1..c34cb0be2bbb9 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -139,7 +139,8 @@ fn mir_borrowck( let opaque_types = Default::default(); Ok(tcx.arena.alloc(opaque_types)) } else { - let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None); + let tainted_by_errors = Default::default(); + let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None, &tainted_by_errors); root_cx.do_mir_borrowck(); root_cx.finalize() } @@ -315,7 +316,7 @@ struct CollectRegionConstraintsResult<'tcx> { /// the current body. This initializes the relevant data structures /// and then type checks the MIR body. fn borrowck_collect_region_constraints<'tcx>( - root_cx: &mut BorrowCheckRootCtxt<'tcx>, + root_cx: &mut BorrowCheckRootCtxt<'_, 'tcx>, def: LocalDefId, ) -> CollectRegionConstraintsResult<'tcx> { let tcx = root_cx.tcx; @@ -393,8 +394,9 @@ fn borrowck_collect_region_constraints<'tcx>( /// Using the region constraints computed by [borrowck_collect_region_constraints] /// and the additional constraints from [BorrowCheckRootCtxt::handle_opaque_type_uses], /// compute the region graph and actually check for any borrowck errors. -fn borrowck_check_region_constraints<'tcx>( - root_cx: &mut BorrowCheckRootCtxt<'tcx>, +fn borrowck_check_region_constraints<'diag, 'tcx>( + root_cx: &mut BorrowCheckRootCtxt<'diag, 'tcx>, + diags_buffer: &mut BorrowckDiagnosticsBuffer<'diag, 'tcx>, CollectRegionConstraintsResult { infcx, body_owned, @@ -461,7 +463,6 @@ fn borrowck_check_region_constraints<'tcx>( let movable_coroutine = body.coroutine.is_some() && tcx.coroutine_movability(def.to_def_id()) == hir::Movability::Movable; - let diags_buffer = &mut BorrowckDiagnosticsBuffer::default(); // While promoteds should mostly be correct by construction, we need to check them for // invalid moves to detect moving out of arrays:`struct S; fn main() { &([S][0]); }`. for promoted_body in &promoted { @@ -495,8 +496,8 @@ fn borrowck_check_region_constraints<'tcx>( diags_buffer, polonius_context: polonius_context.as_ref(), }; - struct MoveVisitor<'a, 'b, 'infcx, 'tcx> { - ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>, + struct MoveVisitor<'a, 'b, 'diag, 'tcx> { + ctxt: &'a mut MirBorrowckCtxt<'b, 'diag, 'tcx>, } impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> { @@ -578,7 +579,7 @@ fn borrowck_check_region_constraints<'tcx>( used_mut_upvars: mbcx.used_mut_upvars, }; - if let Some(guar) = mbcx.diags_buffer.emit_errors().or(infcx.tainted_by_errors()) { + if let Some(guar) = infcx.tainted_by_errors() { root_cx.set_tainted_by_errors(guar); } @@ -727,9 +728,9 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { } } -pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { - root_cx: &'a BorrowCheckRootCtxt<'tcx>, - infcx: &'infcx BorrowckInferCtxt<'tcx>, +pub(crate) struct MirBorrowckCtxt<'a, 'diag, 'tcx> { + root_cx: &'a BorrowCheckRootCtxt<'diag, 'tcx>, + infcx: &'a BorrowckInferCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>, @@ -785,7 +786,7 @@ pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { /// The counter for generating new region names. next_region_name: RefCell, - diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, + diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'diag, 'tcx>, move_errors: Vec>, /// Results of Polonius analysis. diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index b11f1868b64c9..70975641bd622 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -111,7 +111,7 @@ pub(crate) fn compute_closure_requirements_modulo_opaques<'tcx>( /// /// This may result in errors being reported. pub(crate) fn compute_regions<'tcx>( - root_cx: &BorrowCheckRootCtxt<'tcx>, + root_cx: &BorrowCheckRootCtxt<'_, 'tcx>, infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, location_table: &PoloniusLocationTable, @@ -287,8 +287,8 @@ pub(crate) fn emit_nll_mir<'tcx>( Ok(()) } -pub(super) fn dump_annotation<'tcx, 'infcx>( - infcx: &'infcx BorrowckInferCtxt<'tcx>, +pub(super) fn dump_annotation<'tcx>( + infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index e406f158db216..b1aca758d64ae 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -1,8 +1,10 @@ +use std::cell::Cell; use std::mem; use std::rc::Rc; use rustc_abi::FieldIdx; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{self, TyCtxt}; @@ -10,6 +12,7 @@ use rustc_span::ErrorGuaranteed; use smallvec::SmallVec; use crate::consumers::BorrowckConsumer; +use crate::diagnostics::BorrowckDiagnosticsBuffer; use crate::nll::compute_closure_requirements_modulo_opaques; use crate::region_infer::opaque_types::{ UnexpectedHiddenRegion, apply_definition_site_hidden_types, clone_and_resolve_opaque_types, @@ -24,7 +27,7 @@ use crate::{ /// The shared context used by both the root as well as all its nested /// items. -pub(super) struct BorrowCheckRootCtxt<'tcx> { +pub(super) struct BorrowCheckRootCtxt<'diag, 'tcx: 'diag> { pub tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, /// This contains fully resolved hidden types or `ty::Error`. @@ -39,18 +42,19 @@ pub(super) struct BorrowCheckRootCtxt<'tcx> { collect_region_constraints_results: FxIndexMap>, propagated_borrowck_results: FxHashMap>, - tainted_by_errors: Option, + tainted_by_errors: &'diag Cell>, /// This should be `None` during normal compilation. See [`crate::consumers`] for more /// information on how this is used. pub consumer: Option>, } -impl<'tcx> BorrowCheckRootCtxt<'tcx> { +impl<'diag, 'tcx> BorrowCheckRootCtxt<'diag, 'tcx> { pub(super) fn new( tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, consumer: Option>, - ) -> BorrowCheckRootCtxt<'tcx> { + tainted_by_errors: &'diag Cell>, + ) -> BorrowCheckRootCtxt<'diag, 'tcx> { BorrowCheckRootCtxt { tcx, root_def_id, @@ -58,7 +62,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { unconstrained_hidden_type_errors: Default::default(), collect_region_constraints_results: Default::default(), propagated_borrowck_results: Default::default(), - tainted_by_errors: None, + tainted_by_errors, consumer, } } @@ -67,8 +71,12 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { self.root_def_id } - pub(super) fn set_tainted_by_errors(&mut self, guar: ErrorGuaranteed) { - self.tainted_by_errors = Some(guar); + pub(super) fn set_tainted_by_errors(&self, guar: ErrorGuaranteed) { + self.tainted_by_errors.set(Some(guar)); + } + + pub(super) fn dcx(&self) -> DiagCtxtHandle<'diag> { + self.tcx.dcx().taintable_handle(&self.tainted_by_errors) } pub(super) fn used_mut_upvars( @@ -82,7 +90,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { self, ) -> Result<&'tcx FxIndexMap>, ErrorGuaranteed> { - if let Some(guar) = self.tainted_by_errors { + if let Some(guar) = self.tainted_by_errors.get() { Err(guar) } else { Ok(self.tcx.arena.alloc(self.hidden_types)) @@ -157,7 +165,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { /// which don't depend on opaque types. In this case they get removed from /// `collect_region_constraints_results` and the final result gets put into /// `propagated_borrowck_results`. - fn apply_closure_requirements_modulo_opaques(&mut self) { + fn apply_closure_requirements_modulo_opaques( + &mut self, + diags_buffer: &mut BorrowckDiagnosticsBuffer<'diag, 'tcx>, + ) { let mut closure_requirements_modulo_opaques = FxHashMap::default(); // We need to `mem::take` both `self.collect_region_constraints_results` and // `input.deferred_closure_requirements` as we otherwise can't iterate over @@ -215,7 +226,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { self.collect_region_constraints_results.insert(def_id, input); } else { assert!(input.deferred_closure_requirements.is_empty()); - let result = borrowck_check_region_constraints(self, input); + let result = borrowck_check_region_constraints(self, diags_buffer, input); self.propagated_borrowck_results.insert(def_id, result); } } @@ -270,6 +281,8 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { self.collect_region_constraints_results.insert(def_id, result); } + let diags_buffer = &mut BorrowckDiagnosticsBuffer::default(); + // We now apply the closure requirements of nested bodies modulo // opaques. In case a body does not depend on opaque types, we // eagerly check its region constraints and use the final closure @@ -277,7 +290,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { // // We eagerly finish borrowck for bodies which don't depend on // opaques. - self.apply_closure_requirements_modulo_opaques(); + self.apply_closure_requirements_modulo_opaques(diags_buffer); // We handle opaque type uses for all bodies together. self.handle_opaque_type_uses(); @@ -303,8 +316,9 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { ); } - let result = borrowck_check_region_constraints(self, input); + let result = borrowck_check_region_constraints(self, diags_buffer, input); self.propagated_borrowck_results.insert(def_id, result); } + diags_buffer.emit_errors(); } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a0a2d1c135aa3..1d7373a15e67c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -95,7 +95,7 @@ mod relate_tys; /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis /// - `location_map` -- map between MIR `Location` and `PointIndex` pub(crate) fn type_check<'tcx>( - root_cx: &BorrowCheckRootCtxt<'tcx>, + root_cx: &BorrowCheckRootCtxt<'_, 'tcx>, infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, promoted: &IndexSlice>, @@ -228,7 +228,7 @@ enum FieldAccessError { /// way, it accrues region constraints -- these can later be used by /// NLL region checking. struct TypeChecker<'a, 'tcx> { - root_cx: &'a BorrowCheckRootCtxt<'tcx>, + root_cx: &'a BorrowCheckRootCtxt<'a, 'tcx>, infcx: &'a BorrowckInferCtxt<'tcx>, last_span: Span, body: &'a Body<'tcx>, diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index b0adbcd6db4ef..4257bf73f52b2 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -448,12 +448,12 @@ impl<'tcx> UniversalRegions<'tcx> { } } -struct UniversalRegionsBuilder<'infcx, 'tcx> { - infcx: &'infcx BorrowckInferCtxt<'tcx>, +struct UniversalRegionsBuilder<'a, 'tcx> { + infcx: &'a BorrowckInferCtxt<'tcx>, mir_def: LocalDefId, } -impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { +impl<'tcx> UniversalRegionsBuilder<'_, 'tcx> { fn build(self) -> UniversalRegions<'tcx> { debug!("build(mir_def={:?})", self.mir_def); diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 29c45e2c7bb6e..e743b0ce6e901 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -46,10 +46,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { /// MIR visitor for collecting used mutable variables. /// The 'visit lifetime represents the duration of the MIR walk. -struct GatherUsedMutsVisitor<'a, 'b, 'infcx, 'tcx> { +struct GatherUsedMutsVisitor<'a, 'b, 'diag, 'tcx> { temporary_used_locals: FxIndexSet, never_initialized_mut_locals: &'a mut FxIndexSet, - mbcx: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>, + mbcx: &'a mut MirBorrowckCtxt<'b, 'diag, 'tcx>, } impl GatherUsedMutsVisitor<'_, '_, '_, '_> { diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr index c479adfa56d7e..94fb78fadb6ff 100644 --- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr +++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -10,18 +10,23 @@ LL | *x += 1; LL | y | - returning this value requires that `*x` is borrowed for `'1` -error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:17:9 +error[E0716]: temporary value dropped while borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:13:5 | -LL | (async move || { - | - return type of async closure is &'1 i32 -... -LL | let y = &*x; - | --- `*x` is borrowed here -LL | *x += 1; - | ^^^^^^^ `*x` is assigned to here but it was already borrowed -LL | y - | - returning this value requires that `*x` is borrowed for `'1` +LL | pub fn async_closure(x: &mut i32) -> impl Future { + | - let's call the lifetime of this reference `'1` +LL | // (async move || { +LL | || +LL | || +LL | || let y = &*x; +LL | || *x += 1; +LL | || y +LL | || })() + | ||______^_- argument requires that borrow lasts for `'1` + | |_______| + | creates a temporary value which is freed while still in use +LL | } + | - temporary value is freed at the end of this statement error: lifetime may not live long enough --> $DIR/issue-74072-lifetime-name-annotations.rs:13:20 @@ -41,12 +46,25 @@ LL | | })() | = note: closure implements `AsyncFnMut`, so references to captured variables can't escape the closure +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:17:9 + | +LL | (async move || { + | - return type of async closure is &'1 i32 +... +LL | let y = &*x; + | --- `*x` is borrowed here +LL | *x += 1; + | ^^^^^^^ `*x` is assigned to here but it was already borrowed +LL | y + | - returning this value requires that `*x` is borrowed for `'1` + error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:13:5 + --> $DIR/issue-74072-lifetime-name-annotations.rs:23:5 | -LL | pub fn async_closure(x: &mut i32) -> impl Future { - | - let's call the lifetime of this reference `'1` -LL | // (async move || { +LL | pub fn async_closure_explicit_return_type(x: &mut i32) -> impl Future { + | - let's call the lifetime of this reference `'1` +LL | // (async move || -> &i32 { LL | || LL | || LL | || let y = &*x; @@ -59,19 +77,6 @@ LL | || })() LL | } | - temporary value is freed at the end of this statement -error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:27:9 - | -LL | (async move || -> &i32 { - | - return type of async closure is &'1 i32 -... -LL | let y = &*x; - | --- `*x` is borrowed here -LL | *x += 1; - | ^^^^^^^ `*x` is assigned to here but it was already borrowed -LL | y - | - returning this value requires that `*x` is borrowed for `'1` - error: lifetime may not live long enough --> $DIR/issue-74072-lifetime-name-annotations.rs:23:28 | @@ -90,23 +95,18 @@ LL | | })() | = note: closure implements `AsyncFnMut`, so references to captured variables can't escape the closure -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:23:5 +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:27:9 | -LL | pub fn async_closure_explicit_return_type(x: &mut i32) -> impl Future { - | - let's call the lifetime of this reference `'1` -LL | // (async move || -> &i32 { -LL | || -LL | || -LL | || let y = &*x; -LL | || *x += 1; -LL | || y -LL | || })() - | ||______^_- argument requires that borrow lasts for `'1` - | |_______| - | creates a temporary value which is freed while still in use -LL | } - | - temporary value is freed at the end of this statement +LL | (async move || -> &i32 { + | - return type of async closure is &'1 i32 +... +LL | let y = &*x; + | --- `*x` is borrowed here +LL | *x += 1; + | ^^^^^^^ `*x` is assigned to here but it was already borrowed +LL | y + | - returning this value requires that `*x` is borrowed for `'1` error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:35:9 diff --git a/tests/ui/async-await/issues/issue-62097.stderr b/tests/ui/async-await/issues/issue-62097.stderr index 21a61548d01e3..adc8265e6c482 100644 --- a/tests/ui/async-await/issues/issue-62097.stderr +++ b/tests/ui/async-await/issues/issue-62097.stderr @@ -1,3 +1,17 @@ +error[E0521]: borrowed data escapes outside of method + --> $DIR/issue-62097.rs:13:9 + | +LL | pub async fn run_dummy_fn(&self) { + | ----- + | | + | `self` is a reference that is only valid in the method body + | let's call the lifetime of this reference `'1` +LL | foo(|| self.bar()).await; + | ^^^^^^^^^^^^^^^^^^ + | | + | `self` escapes the method body here + | argument requires that `'1` must outlive `'static` + error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function --> $DIR/issue-62097.rs:13:13 | @@ -16,20 +30,6 @@ help: to force the closure to take ownership of `self` (and any other referenced LL | foo(move || self.bar()).await; | ++++ -error[E0521]: borrowed data escapes outside of method - --> $DIR/issue-62097.rs:13:9 - | -LL | pub async fn run_dummy_fn(&self) { - | ----- - | | - | `self` is a reference that is only valid in the method body - | let's call the lifetime of this reference `'1` -LL | foo(|| self.bar()).await; - | ^^^^^^^^^^^^^^^^^^ - | | - | `self` escapes the method body here - | argument requires that `'1` must outlive `'static` - error: aborting due to 2 previous errors Some errors have detailed explanations: E0373, E0521. diff --git a/tests/ui/borrowck/borrowck-closures-mut-of-imm.stderr b/tests/ui/borrowck/borrowck-closures-mut-of-imm.stderr index 46b41a0c8194b..f8af4eaf22241 100644 --- a/tests/ui/borrowck/borrowck-closures-mut-of-imm.stderr +++ b/tests/ui/borrowck/borrowck-closures-mut-of-imm.stderr @@ -4,12 +4,6 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference LL | let mut c1 = || set(&mut *x); | ^^^^^^^ cannot borrow as mutable -error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference - --> $DIR/borrowck-closures-mut-of-imm.rs:12:25 - | -LL | let mut c2 = || set(&mut *x); - | ^^^^^^^ cannot borrow as mutable - error[E0524]: two closures require unique access to `x` at the same time --> $DIR/borrowck-closures-mut-of-imm.rs:12:18 | @@ -26,6 +20,12 @@ LL | let mut c2 = || set(&mut *x); LL | c2(); c1(); | -- first borrow later used here +error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference + --> $DIR/borrowck-closures-mut-of-imm.rs:12:25 + | +LL | let mut c2 = || set(&mut *x); + | ^^^^^^^ cannot borrow as mutable + error: aborting due to 3 previous errors Some errors have detailed explanations: E0524, E0596. diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.stderr b/tests/ui/borrowck/borrowck-describe-lvalue.stderr index 666a21808d80b..88b2508116658 100644 --- a/tests/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/tests/ui/borrowck/borrowck-describe-lvalue.stderr @@ -1,46 +1,3 @@ -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:253:13 - | -LL | let y = &mut x; - | ------ first mutable borrow occurs here -LL | &mut x; - | ^^^^^^ second mutable borrow occurs here -LL | *y = 1; - | ------ first borrow later used here - -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:263:20 - | -LL | let y = &mut x; - | ------ first mutable borrow occurs here -LL | &mut x; - | ^^^^^^ second mutable borrow occurs here -LL | *y = 1; - | ------ first borrow later used here - -error: captured variable cannot escape `FnMut` closure body - --> $DIR/borrowck-describe-lvalue.rs:261:16 - | -LL | let mut x = 0; - | ----- variable defined here -LL | || { - | - inferred to be a `FnMut` closure -LL | / || { -LL | | let y = &mut x; - | | - variable captured here -LL | | &mut x; -LL | | *y = 1; -LL | | drop(y); -LL | | } - | |_________________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body - | - = note: `FnMut` closures only have access to their captured variables while they are executing... - = note: ...therefore, they cannot allow references to captured variables to escape -help: consider adding 'move' keyword before the nested closure - | -LL | move || { - | ++++ - error[E0503]: cannot use `f.x` because it was mutably borrowed --> $DIR/borrowck-describe-lvalue.rs:37:9 | @@ -323,6 +280,49 @@ LL | &[_, F {x: ref xf, ..}] => println!("{}", xf), LL | drop(x); | - mutable borrow later used here +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-describe-lvalue.rs:253:13 + | +LL | let y = &mut x; + | ------ first mutable borrow occurs here +LL | &mut x; + | ^^^^^^ second mutable borrow occurs here +LL | *y = 1; + | ------ first borrow later used here + +error: captured variable cannot escape `FnMut` closure body + --> $DIR/borrowck-describe-lvalue.rs:261:16 + | +LL | let mut x = 0; + | ----- variable defined here +LL | || { + | - inferred to be a `FnMut` closure +LL | / || { +LL | | let y = &mut x; + | | - variable captured here +LL | | &mut x; +LL | | *y = 1; +LL | | drop(y); +LL | | } + | |_________________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape +help: consider adding 'move' keyword before the nested closure + | +LL | move || { + | ++++ + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-describe-lvalue.rs:263:20 + | +LL | let y = &mut x; + | ------ first mutable borrow occurs here +LL | &mut x; + | ^^^^^^ second mutable borrow occurs here +LL | *y = 1; + | ------ first borrow later used here + error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable --> $DIR/borrowck-describe-lvalue.rs:206:29 | diff --git a/tests/ui/borrowck/borrowck-multiple-captures.rs b/tests/ui/borrowck/borrowck-multiple-captures.rs index 57b3819ac5113..fb1aec32c0b1a 100644 --- a/tests/ui/borrowck/borrowck-multiple-captures.rs +++ b/tests/ui/borrowck/borrowck-multiple-captures.rs @@ -47,7 +47,6 @@ fn same_var_after_move() { let x: Box<_> = Box::new(1); drop(x); thread::spawn(move|| { - //~^ ERROR use of moved value: `x` drop(x); drop(x); //~ ERROR use of moved value: `x` }); diff --git a/tests/ui/borrowck/borrowck-multiple-captures.stderr b/tests/ui/borrowck/borrowck-multiple-captures.stderr index 01b648ea64717..b7624052e0c55 100644 --- a/tests/ui/borrowck/borrowck-multiple-captures.stderr +++ b/tests/ui/borrowck/borrowck-multiple-captures.stderr @@ -78,16 +78,6 @@ help: consider cloning the value if the performance cost is acceptable LL | drop(x2.clone()); | ++++++++ -error[E0382]: use of moved value: `x` - --> $DIR/borrowck-multiple-captures.rs:41:14 - | -LL | drop(x); - | - value moved here -LL | drop(x); - | ^ value used here after move - | - = note: move occurs because `x` has type `Box`, which does not implement the `Copy` trait - error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/borrowck-multiple-captures.rs:38:19 | @@ -110,7 +100,7 @@ LL | let p = &x.clone(); | ++++++++ error[E0382]: use of moved value: `x` - --> $DIR/borrowck-multiple-captures.rs:52:14 + --> $DIR/borrowck-multiple-captures.rs:41:14 | LL | drop(x); | - value moved here @@ -120,24 +110,16 @@ LL | drop(x); = note: move occurs because `x` has type `Box`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x` - --> $DIR/borrowck-multiple-captures.rs:49:19 + --> $DIR/borrowck-multiple-captures.rs:51:14 | -LL | let x: Box<_> = Box::new(1); - | - move occurs because `x` has type `Box`, which does not implement the `Copy` trait -LL | drop(x); - | - value moved here -LL | thread::spawn(move|| { - | ^^^^^^ value used here after move -LL | LL | drop(x); - | - use occurs due to use in closure - | -help: consider cloning the value if the performance cost is acceptable + | - value moved here +LL | drop(x); + | ^ value used here after move | -LL | drop(x.clone()); - | ++++++++ + = note: move occurs because `x` has type `Box`, which does not implement the `Copy` trait -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0382, E0505. For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/borrowck/closure-upvar-named-lifetime.stderr b/tests/ui/borrowck/closure-upvar-named-lifetime.stderr index fc7c59fa97c89..e097be2e5cd84 100644 --- a/tests/ui/borrowck/closure-upvar-named-lifetime.stderr +++ b/tests/ui/borrowck/closure-upvar-named-lifetime.stderr @@ -1,3 +1,25 @@ +error[E0700]: hidden type for `impl Fn(RefCell>)` captures lifetime that does not appear in bounds + --> $DIR/closure-upvar-named-lifetime.rs:17:5 + | +LL | fn apply<'a>( + | -- hidden type `{closure@$DIR/closure-upvar-named-lifetime.rs:17:5: 17:15}` captures the lifetime `'a` as defined here +LL | f: Arc) + 'a>, +LL | ) -> impl Fn(RefCell>) + | ----------------------------------------- opaque type defined here +LL | { +LL | / move |map| { +LL | | +LL | | let value = map.borrow_mut().entry("foo".to_string()); +... | +LL | | f(wrapped_value); +LL | | } + | |_____^ + | +help: add a `use<...>` bound to explicitly capture `'a` + | +LL | ) -> impl Fn(RefCell>) + use<'a> + | +++++++++ + error[E0597]: `map` does not live long enough --> $DIR/closure-upvar-named-lifetime.rs:19:21 | @@ -36,11 +58,11 @@ note: requirement that the value outlives `'a` introduced here --> $SRC_DIR/core/src/ops/function.rs:LL:COL error[E0700]: hidden type for `impl Fn(RefCell>)` captures lifetime that does not appear in bounds - --> $DIR/closure-upvar-named-lifetime.rs:17:5 + --> $DIR/closure-upvar-named-lifetime.rs:32:5 | -LL | fn apply<'a>( - | -- hidden type `{closure@$DIR/closure-upvar-named-lifetime.rs:17:5: 17:15}` captures the lifetime `'a` as defined here -LL | f: Arc) + 'a>, +LL | fn apply_box<'a>( + | -- hidden type `{closure@$DIR/closure-upvar-named-lifetime.rs:32:5: 32:15}` captures the lifetime `'a` as defined here +LL | f: Box) + 'a>, LL | ) -> impl Fn(RefCell>) | ----------------------------------------- opaque type defined here LL | { @@ -48,7 +70,7 @@ LL | / move |map| { LL | | LL | | let value = map.borrow_mut().entry("foo".to_string()); ... | -LL | | f(wrapped_value); +LL | | f(value); LL | | } | |_____^ | @@ -88,28 +110,6 @@ LL | let value = map.borrow_mut().entry("foo".to_string()); LL | f(value); | -------- argument requires that borrow lasts for `'a` -error[E0700]: hidden type for `impl Fn(RefCell>)` captures lifetime that does not appear in bounds - --> $DIR/closure-upvar-named-lifetime.rs:32:5 - | -LL | fn apply_box<'a>( - | -- hidden type `{closure@$DIR/closure-upvar-named-lifetime.rs:32:5: 32:15}` captures the lifetime `'a` as defined here -LL | f: Box) + 'a>, -LL | ) -> impl Fn(RefCell>) - | ----------------------------------------- opaque type defined here -LL | { -LL | / move |map| { -LL | | -LL | | let value = map.borrow_mut().entry("foo".to_string()); -... | -LL | | f(value); -LL | | } - | |_____^ - | -help: add a `use<...>` bound to explicitly capture `'a` - | -LL | ) -> impl Fn(RefCell>) + use<'a> - | +++++++++ - error: aborting due to 6 previous errors Some errors have detailed explanations: E0597, E0700, E0716. diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index bd6c1c44bfb36..caae758a48070 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -1,3 +1,22 @@ +error[E0521]: borrowed data escapes outside of method + --> $DIR/issue-103624.rs:14:9 + | +LL | async fn foo(&self) { + | ----- + | | + | `self` is a reference that is only valid in the method body + | let's call the lifetime of this reference `'1` +LL | let bar = self.b.bar().await; +LL | / spawn_blocking(move || { +LL | | +LL | | self.b; +LL | | +LL | | }) + | | ^ + | | | + | |__________`self` escapes the method body here + | argument requires that `'1` must outlive `'static` + error[E0507]: cannot move out of `self.b`, as `self` is a captured variable in an `Fn` closure --> $DIR/issue-103624.rs:16:13 | @@ -27,25 +46,6 @@ LL | self.b; LL | struct StructB {} | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type -error[E0521]: borrowed data escapes outside of method - --> $DIR/issue-103624.rs:14:9 - | -LL | async fn foo(&self) { - | ----- - | | - | `self` is a reference that is only valid in the method body - | let's call the lifetime of this reference `'1` -LL | let bar = self.b.bar().await; -LL | / spawn_blocking(move || { -LL | | -LL | | self.b; -LL | | -LL | | }) - | | ^ - | | | - | |__________`self` escapes the method body here - | argument requires that `'1` must outlive `'static` - error: aborting due to 2 previous errors Some errors have detailed explanations: E0507, E0521. diff --git a/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr b/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr index 96b3ebf1eb490..e62701bf408a7 100644 --- a/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr +++ b/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr @@ -1,12 +1,3 @@ -error: lifetime may not live long enough - --> $DIR/overwrite-anon-late-param-regions.rs:11:9 - | -LL | |x| x - | - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` - | | - | has type `(&str, &'1 str)` - | has type `(&'2 str, &str)` - error[E0792]: expected generic lifetime parameter, found `'a` --> $DIR/overwrite-anon-late-param-regions.rs:11:5 | @@ -16,6 +7,15 @@ LL | type Opaque2<'a> = impl Sized + 'a; LL | |x| x | ^^^^^ +error: lifetime may not live long enough + --> $DIR/overwrite-anon-late-param-regions.rs:11:9 + | +LL | |x| x + | - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | + | has type `(&str, &'1 str)` + | has type `(&'2 str, &str)` + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/closures/aliasability-violation-with-closure-21600.stderr b/tests/ui/closures/aliasability-violation-with-closure-21600.stderr index 2f4135b12fa5a..eb2fe8d7e8180 100644 --- a/tests/ui/closures/aliasability-violation-with-closure-21600.stderr +++ b/tests/ui/closures/aliasability-violation-with-closure-21600.stderr @@ -1,18 +1,3 @@ -error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/aliasability-violation-with-closure-21600.rs:15:20 - | -LL | fn call_it(f: F) where F: Fn() { f(); } - | - change this to accept `FnMut` instead of `Fn` -... -LL | let mut x = A; - | ----- `x` declared here, outside the closure -... -LL | call_it(|| x.gen_mut()); - | ------- -- ^ cannot borrow as mutable - | | | - | | in this closure - | expects `Fn` instead of `FnMut` - error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/aliasability-violation-with-closure-21600.rs:15:17 | @@ -31,6 +16,21 @@ LL | call_it(|| x.gen_mut()); | | | cannot borrow as mutable +error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure + --> $DIR/aliasability-violation-with-closure-21600.rs:15:20 + | +LL | fn call_it(f: F) where F: Fn() { f(); } + | - change this to accept `FnMut` instead of `Fn` +... +LL | let mut x = A; + | ----- `x` declared here, outside the closure +... +LL | call_it(|| x.gen_mut()); + | ------- -- ^ cannot borrow as mutable + | | | + | | in this closure + | expects `Fn` instead of `FnMut` + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr b/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr index 80da4e7145f95..8eb069ce084a1 100644 --- a/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr +++ b/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr @@ -28,15 +28,6 @@ LL | func(|| x = ()) | | in this closure | expects `Fn` instead of `FnMut` -error[E0594]: cannot assign to `self.counter`, as `Fn` closures cannot mutate their captured variables - --> $DIR/wrong-closure-arg-suggestion-125325.rs:46:28 - | -LL | take(|_| to_fn(|_| self.counter += 1)); - | ----- --- ^^^^^^^^^^^^^^^^^ cannot assign - | | | - | | in this closure - | expects `Fn` instead of `FnMut` - error: lifetime may not live long enough --> $DIR/wrong-closure-arg-suggestion-125325.rs:46:18 | @@ -62,14 +53,13 @@ LL | fn take(_: F) | - change this to accept `FnMut` instead of `Fn` error[E0594]: cannot assign to `self.counter`, as `Fn` closures cannot mutate their captured variables - --> $DIR/wrong-closure-arg-suggestion-125325.rs:54:34 + --> $DIR/wrong-closure-arg-suggestion-125325.rs:46:28 | -LL | P.flat_map(|_| P.map(|_| self.counter += 1)); - | --------^^^^^^^^^^^^^^^^^- - | | | | - | | | cannot assign - | | in this closure - | expects `Fn` instead of `FnMut` +LL | take(|_| to_fn(|_| self.counter += 1)); + | ----- --- ^^^^^^^^^^^^^^^^^ cannot assign + | | | + | | in this closure + | expects `Fn` instead of `FnMut` error: lifetime may not live long enough --> $DIR/wrong-closure-arg-suggestion-125325.rs:54:24 @@ -97,6 +87,16 @@ LL | P.flat_map(|_| P.map(|_| self.counter += 1)); | | in this closure | expects `Fn` instead of `FnMut` +error[E0594]: cannot assign to `self.counter`, as `Fn` closures cannot mutate their captured variables + --> $DIR/wrong-closure-arg-suggestion-125325.rs:54:34 + | +LL | P.flat_map(|_| P.map(|_| self.counter += 1)); + | --------^^^^^^^^^^^^^^^^^- + | | | | + | | | cannot assign + | | in this closure + | expects `Fn` instead of `FnMut` + error: aborting due to 8 previous errors Some errors have detailed explanations: E0594, E0596. diff --git a/tests/ui/coroutine/auto-trait-regions.stderr b/tests/ui/coroutine/auto-trait-regions.stderr index 04acddafc414c..75293b2f4a873 100644 --- a/tests/ui/coroutine/auto-trait-regions.stderr +++ b/tests/ui/coroutine/auto-trait-regions.stderr @@ -1,3 +1,15 @@ +error: implementation of `Foo` is not general enough + --> $DIR/auto-trait-regions.rs:31:5 + | +LL | let generator = #[coroutine] move || { + | ------- this coroutine captures a value whose type is not `Foo` +... +LL | assert_foo(generator); + | ^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`... + = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef` + error[E0626]: borrow may still be in use when coroutine yields --> $DIR/auto-trait-regions.rs:45:19 | @@ -30,18 +42,6 @@ help: add `static` to mark this coroutine as unmovable LL | let generator = #[coroutine] static move || { | ++++++ -error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:31:5 - | -LL | let generator = #[coroutine] move || { - | ------- this coroutine captures a value whose type is not `Foo` -... -LL | assert_foo(generator); - | ^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`... - = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef` - error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:51:5 | diff --git a/tests/ui/lifetimes/issue-79187-2.stderr b/tests/ui/lifetimes/issue-79187-2.stderr index 78f6ce882dfab..b3b0f8dd6e89e 100644 --- a/tests/ui/lifetimes/issue-79187-2.stderr +++ b/tests/ui/lifetimes/issue-79187-2.stderr @@ -1,21 +1,3 @@ -error: lifetime may not live long enough - --> $DIR/issue-79187-2.rs:11:24 - | -LL | take_foo(|a: &i32| a); - | - - ^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is &'2 i32 - | let's call the lifetime of this reference `'1` - -error: lifetime may not live long enough - --> $DIR/issue-79187-2.rs:14:34 - | -LL | take_foo(|a: &i32| -> &i32 { a }); - | - - ^ returning this value requires that `'1` must outlive `'2` - | | | - | | let's call the lifetime of this reference `'2` - | let's call the lifetime of this reference `'1` - error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187-2.rs:8:5 | @@ -48,6 +30,15 @@ note: the lifetime requirement is introduced here LL | fn take_foo(_: impl Foo) {} | ^^^ +error: lifetime may not live long enough + --> $DIR/issue-79187-2.rs:11:24 + | +LL | take_foo(|a: &i32| a); + | - - ^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is &'2 i32 + | let's call the lifetime of this reference `'1` + error[E0308]: mismatched types --> $DIR/issue-79187-2.rs:14:5 | @@ -62,6 +53,15 @@ note: the lifetime requirement is introduced here LL | fn take_foo(_: impl Foo) {} | ^^^ +error: lifetime may not live long enough + --> $DIR/issue-79187-2.rs:14:34 + | +LL | take_foo(|a: &i32| -> &i32 { a }); + | - - ^ returning this value requires that `'1` must outlive `'2` + | | | + | | let's call the lifetime of this reference `'2` + | let's call the lifetime of this reference `'1` + error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/macros/return_from_external_macro.stderr b/tests/ui/macros/return_from_external_macro.stderr index 6f707b9f52b1e..5e65ac6486d62 100644 --- a/tests/ui/macros/return_from_external_macro.stderr +++ b/tests/ui/macros/return_from_external_macro.stderr @@ -1,14 +1,3 @@ -error[E0515]: cannot return reference to temporary value - --> $DIR/return_from_external_macro.rs:7:13 - | -LL | drop(|| ret_from_ext::foo!()); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | returns a reference to data owned by the current function - | temporary value created here - | - = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0716]: temporary value dropped while borrowed --> $DIR/return_from_external_macro.rs:10:5 | @@ -23,6 +12,17 @@ LL | } | = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0515]: cannot return reference to temporary value + --> $DIR/return_from_external_macro.rs:7:13 + | +LL | drop(|| ret_from_ext::foo!()); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | returns a reference to data owned by the current function + | temporary value created here + | + = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to 2 previous errors Some errors have detailed explanations: E0515, E0716. diff --git a/tests/ui/nll/closure-captures.stderr b/tests/ui/nll/closure-captures.stderr index 545bb38479abd..cbc332946896c 100644 --- a/tests/ui/nll/closure-captures.stderr +++ b/tests/ui/nll/closure-captures.stderr @@ -74,17 +74,6 @@ LL | || LL | x = 1;}); | - mutable borrow occurs due to use of `x` in closure -error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:40:10 - | -LL | x = 1;} - | ^^^^^ cannot assign - | -help: consider changing this to be mutable - | -LL | fn two_closures_ref(mut x: i32) { - | +++ - error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:39:9 | @@ -103,10 +92,10 @@ LL | x = 1;} | - mutable borrow occurs due to use of `x` in closure error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:44:5 + --> $DIR/closure-captures.rs:40:10 | -LL | x = 1;}); - | ^^^^^ cannot assign +LL | x = 1;} + | ^^^^^ cannot assign | help: consider changing this to be mutable | @@ -128,6 +117,17 @@ LL | || LL | x = 1;}); | - mutable borrow occurs due to use of `x` in closure +error[E0594]: cannot assign to `x`, as it is not declared as mutable + --> $DIR/closure-captures.rs:44:5 + | +LL | x = 1;}); + | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn two_closures_ref(mut x: i32) { + | +++ + error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:49:9 | diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr index 2742162c82119..bcc919ade7526 100644 --- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -13,6 +13,14 @@ LL | let mut closure = expect_sig(|p, y| *p = y); = note: late-bound region is '?2 = note: late-bound region is '?3 +note: no external requirements + --> $DIR/escape-argument-callee.rs:20:1 + | +LL | fn test() { + | ^^^^^^^^^ + | + = note: defining type: test + error: lifetime may not live long enough --> $DIR/escape-argument-callee.rs:26:45 | @@ -22,13 +30,5 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | | has type `&'1 i32` | has type `&'?1 mut &'2 i32` -note: no external requirements - --> $DIR/escape-argument-callee.rs:20:1 - | -LL | fn test() { - | ^^^^^^^^^ - | - = note: defining type: test - error: aborting due to 1 previous error diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index af07745a00af4..f7cbc5b0f68f7 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -11,6 +11,14 @@ LL | foo(cell, |cell_a, cell_x| { ] = note: late-bound region is '?2 +note: no external requirements + --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1 + | +LL | fn case1() { + | ^^^^^^^^^^ + | + = note: defining type: case1 + error[E0521]: borrowed data escapes outside of closure --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:22:9 | @@ -25,14 +33,6 @@ LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance -note: no external requirements - --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1 - | -LL | fn case1() { - | ^^^^^^^^^^ - | - = note: defining type: case1 - note: external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:35:15 | diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 6b04e346c6971..2f27fbe3f2efc 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -17,6 +17,14 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { = note: late-bound region is '?2 = note: late-bound region is '?3 +note: no external requirements + --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1 + | +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: supply + error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9 | @@ -32,13 +40,5 @@ LL | demand_y(x, y, x.get()) = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance -note: no external requirements - --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1 - | -LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: supply - error: aborting due to 1 previous error diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index ae2129c65f2c0..00be8fd7ab5c2 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -18,6 +18,14 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y = note: late-bound region is '?3 = note: late-bound region is '?4 +note: no external requirements + --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1 + | +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: supply + error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | @@ -33,13 +41,5 @@ LL | demand_y(x, y, x.get()) = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance -note: no external requirements - --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1 - | -LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: supply - error: aborting due to 1 previous error diff --git a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 1f1cce1e88546..5f5012a4fbcd2 100644 --- a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -12,6 +12,14 @@ LL | expect_sig(|a, b| b); // ought to return `a` = note: late-bound region is '?1 = note: late-bound region is '?2 +note: no external requirements + --> $DIR/return-wrong-bound-region.rs:10:1 + | +LL | fn test() { + | ^^^^^^^^^ + | + = note: defining type: test + error: lifetime may not live long enough --> $DIR/return-wrong-bound-region.rs:11:23 | @@ -21,13 +29,5 @@ LL | expect_sig(|a, b| b); // ought to return `a` | | has type `&'1 i32` | has type `&'2 i32` -note: no external requirements - --> $DIR/return-wrong-bound-region.rs:10:1 - | -LL | fn test() { - | ^^^^^^^^^ - | - = note: defining type: test - error: aborting due to 1 previous error diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr index 96bac039df723..d6404aff61017 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr @@ -1,22 +1,3 @@ -error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:48:28 - | -LL | let Foo { x, y } = foo.as_mut(); - | - - ^^^^^^^^^^^^ - | | | - | | ...and here - | data moved here - | - = note: move occurs because these variables have types that don't implement the `Copy` trait -help: consider borrowing the pattern binding - | -LL | let Foo { ref x, y } = foo.as_mut(); - | +++ -help: consider borrowing the pattern binding - | -LL | let Foo { x, ref y } = foo.as_mut(); - | +++ - error[E0507]: cannot move out of a shared reference --> $DIR/pattern-matching-deref-pattern.rs:38:24 | @@ -37,9 +18,9 @@ LL | let Foo { x, ref y } = foo.as_mut(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:70:28 + --> $DIR/pattern-matching-deref-pattern.rs:48:28 | -LL | let Foo { x, y } = foo.as_ref(); +LL | let Foo { x, y } = foo.as_mut(); | - - ^^^^^^^^^^^^ | | | | | ...and here @@ -48,11 +29,11 @@ LL | let Foo { x, y } = foo.as_ref(); = note: move occurs because these variables have types that don't implement the `Copy` trait help: consider borrowing the pattern binding | -LL | let Foo { ref x, y } = foo.as_ref(); +LL | let Foo { ref x, y } = foo.as_mut(); | +++ help: consider borrowing the pattern binding | -LL | let Foo { x, ref y } = foo.as_ref(); +LL | let Foo { x, ref y } = foo.as_mut(); | +++ error[E0507]: cannot move out of a shared reference @@ -75,23 +56,23 @@ LL | let Foo { x, ref y } = foo.as_ref(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:92:25 + --> $DIR/pattern-matching-deref-pattern.rs:70:28 | -LL | let Bar(x, y) = bar.as_mut(); - | - - ^^^^^^^^^^^^ - | | | - | | ...and here - | data moved here +LL | let Foo { x, y } = foo.as_ref(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here | = note: move occurs because these variables have types that don't implement the `Copy` trait help: consider borrowing the pattern binding | -LL | let Bar(ref x, y) = bar.as_mut(); - | +++ +LL | let Foo { ref x, y } = foo.as_ref(); + | +++ help: consider borrowing the pattern binding | -LL | let Bar(x, ref y) = bar.as_mut(); - | +++ +LL | let Foo { x, ref y } = foo.as_ref(); + | +++ error[E0507]: cannot move out of a shared reference --> $DIR/pattern-matching-deref-pattern.rs:82:21 @@ -113,9 +94,9 @@ LL | let Bar(x, ref y) = bar.as_mut(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:114:25 + --> $DIR/pattern-matching-deref-pattern.rs:92:25 | -LL | let Bar(x, y) = bar.as_ref(); +LL | let Bar(x, y) = bar.as_mut(); | - - ^^^^^^^^^^^^ | | | | | ...and here @@ -124,11 +105,11 @@ LL | let Bar(x, y) = bar.as_ref(); = note: move occurs because these variables have types that don't implement the `Copy` trait help: consider borrowing the pattern binding | -LL | let Bar(ref x, y) = bar.as_ref(); +LL | let Bar(ref x, y) = bar.as_mut(); | +++ help: consider borrowing the pattern binding | -LL | let Bar(x, ref y) = bar.as_ref(); +LL | let Bar(x, ref y) = bar.as_mut(); | +++ error[E0507]: cannot move out of a shared reference @@ -150,6 +131,25 @@ help: consider borrowing the pattern binding LL | let Bar(x, ref y) = bar.as_ref(); | +++ +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:114:25 + | +LL | let Bar(x, y) = bar.as_ref(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Bar(ref x, y) = bar.as_ref(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Bar(x, ref y) = bar.as_ref(); + | +++ + error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr b/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr index e94074548e95a..2cfc0b8fb4825 100644 --- a/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr +++ b/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr @@ -15,21 +15,6 @@ note: but lifetime parameter must outlive the lifetime `'b` as defined here LL | impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> | ^^ -error: lifetime may not live long enough - --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:23:21 - | -LL | self.enter_scope(|ctx| { - | --- - | | - | has type `&'1 mut FooImpl<'_, '_, T>` - | has type `&mut FooImpl<'2, '_, T>` -LL | BarImpl(ctx); - | ^^^ this usage requires that `'1` must outlive `'2` - | - = note: requirement occurs because of a mutable reference to `FooImpl<'_, '_, T>` - = note: mutable references are invariant over their type parameter - = help: see for more information about variance - error: lifetime may not live long enough --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:22:9 | @@ -48,6 +33,21 @@ LL | | }); = note: mutable references are invariant over their type parameter = help: see for more information about variance +error: lifetime may not live long enough + --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:23:21 + | +LL | self.enter_scope(|ctx| { + | --- + | | + | has type `&'1 mut FooImpl<'_, '_, T>` + | has type `&mut FooImpl<'2, '_, T>` +LL | BarImpl(ctx); + | ^^^ this usage requires that `'1` must outlive `'2` + | + = note: requirement occurs because of a mutable reference to `FooImpl<'_, '_, T>` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0478`. diff --git a/tests/ui/regions/regions-nested-fns.stderr b/tests/ui/regions/regions-nested-fns.stderr index 23b3f78dd4eb5..a911ecf51dc89 100644 --- a/tests/ui/regions/regions-nested-fns.stderr +++ b/tests/ui/regions/regions-nested-fns.stderr @@ -1,15 +1,3 @@ -error[E0521]: borrowed data escapes outside of closure - --> $DIR/regions-nested-fns.rs:12:9 - | -LL | let mut ay = &y; - | ------ `ay` declared here, outside of the closure body -... -LL | ignore:: FnMut(&'z isize)>>(Box::new(|z| { - | - `z` is a reference that is only valid in the closure body -... -LL | ay = z; - | ^^^^^^ `z` escapes the closure body here - error[E0597]: `y` does not live long enough --> $DIR/regions-nested-fns.rs:5:18 | @@ -42,6 +30,18 @@ LL | if false { return ay; } LL | } | - `y` dropped here while still borrowed +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-nested-fns.rs:12:9 + | +LL | let mut ay = &y; + | ------ `ay` declared here, outside of the closure body +... +LL | ignore:: FnMut(&'z isize)>>(Box::new(|z| { + | - `z` is a reference that is only valid in the closure body +... +LL | ay = z; + | ^^^^^^ `z` escapes the closure body here + error: lifetime may not live long enough --> $DIR/regions-nested-fns.rs:17:27 | diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr index 6590ba8a79e01..c26c1dfc0d24b 100644 --- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -32,42 +32,42 @@ help: consider changing this to be a mutable reference LL | fn test4(f: &mut Test) { | +++ -error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure - --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13 +error[E0505]: cannot move out of `f` because it is borrowed + --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16 | LL | let mut f = move |g: Box, b: isize| { - | ----- captured outer variable + | ----- binding `f` declared here ... LL | f(Box::new(|a| { - | --- captured by this `FnMut` closure + | - ^^^ move out of `f` occurs here + | | + | borrow of `f` occurs here LL | LL | foo(f); - | ^ move occurs because `f` has type `{closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58}`, which does not implement the `Copy` trait + | - move occurs due to use in closure | - = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once help: consider cloning the value if the performance cost is acceptable | -LL | foo(f.clone()); - | ++++++++ +LL | f.clone()(Box::new(|a| { + | ++++++++ -error[E0505]: cannot move out of `f` because it is borrowed - --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16 +error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure + --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13 | LL | let mut f = move |g: Box, b: isize| { - | ----- binding `f` declared here + | ----- captured outer variable ... LL | f(Box::new(|a| { - | - ^^^ move out of `f` occurs here - | | - | borrow of `f` occurs here + | --- captured by this `FnMut` closure LL | LL | foo(f); - | - move occurs due to use in closure + | ^ move occurs because `f` has type `{closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58}`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once help: consider cloning the value if the performance cost is acceptable | -LL | f.clone()(Box::new(|a| { - | ++++++++ +LL | foo(f.clone()); + | ++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr index f78d3cf678629..d2623bc589456 100644 --- a/tests/ui/suggestions/option-content-move3.stderr +++ b/tests/ui/suggestions/option-content-move3.stderr @@ -1,28 +1,3 @@ -error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure - --> $DIR/option-content-move3.rs:13:21 - | -LL | let var = NotCopyable; - | --- captured outer variable -... -LL | move || { - | ------- captured by this `FnMut` closure -LL | let x = var; - | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait - | - = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once -note: if `NotCopyable` implemented `Clone`, you could clone the value - --> $DIR/option-content-move3.rs:2:1 - | -LL | struct NotCopyable; - | ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type -... -LL | let x = var; - | --- you could clone this value -help: consider borrowing here - | -LL | let x = &var; - | + - error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure --> $DIR/option-content-move3.rs:12:9 | @@ -53,17 +28,25 @@ LL | let x = var; | --- you could clone this value error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure - --> $DIR/option-content-move3.rs:24:21 + --> $DIR/option-content-move3.rs:13:21 | -LL | let var = NotCopyableButCloneable; +LL | let var = NotCopyable; | --- captured outer variable ... LL | move || { | ------- captured by this `FnMut` closure LL | let x = var; - | ^^^ move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait + | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait | = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once +note: if `NotCopyable` implemented `Clone`, you could clone the value + --> $DIR/option-content-move3.rs:2:1 + | +LL | struct NotCopyable; + | ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = var; + | --- you could clone this value help: consider borrowing here | LL | let x = &var; @@ -100,6 +83,23 @@ LL ~ } LL + } | +error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure + --> $DIR/option-content-move3.rs:24:21 + | +LL | let var = NotCopyableButCloneable; + | --- captured outer variable +... +LL | move || { + | ------- captured by this `FnMut` closure +LL | let x = var; + | ^^^ move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait + | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once +help: consider borrowing here + | +LL | let x = &var; + | + + error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0507`.