diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e22c0b40d5a53067abb7c1c81ffc7791921e7cb0..7c28779ef0b7366be2af556d7f0d6e1262b70ce6 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -683,6 +683,15 @@ pub fn allows_two_phase_borrow(&self) -> bool { BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow, } } + + pub fn describe_mutability(&self) -> String { + match *self { + BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => { + "immutable".to_string() + } + BorrowKind::Mut { .. } => "mutable".to_string(), + } + } } /////////////////////////////////////////////////////////////////////////// @@ -2369,6 +2378,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { }; let mut struct_fmt = fmt.debug_struct(&name); + // FIXME: This should be a list of capture names/places if let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { let var_name = tcx.hir().name(var_id); @@ -2388,6 +2398,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { let name = format!("[generator@{:?}]", tcx.hir().span(hir_id)); let mut struct_fmt = fmt.debug_struct(&name); + // FIXME: This should be a list of capture names/places if let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { let var_name = tcx.hir().name(var_id); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 887a5831cd720e3a4971b877d137d1d9ff82369b..7790369af7fef9fdb7d17727868a318a9e8d347d 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -151,6 +151,10 @@ pub struct CapturedPlace<'tcx> { } impl CapturedPlace<'tcx> { + pub fn to_string(&self, tcx: TyCtxt<'tcx>) -> String { + place_to_string_for_capture(tcx, &self.place) + } + /// Returns the hir-id of the root variable for the captured place. /// e.g., if `a.b.c` was captured, would return the hir-id for `a`. pub fn get_root_variable(&self) -> hir::HirId { @@ -168,6 +172,22 @@ pub fn get_closure_local_def_id(&self) -> LocalDefId { } } + /// Return span pointing to use that resulted in selecting the captured path + pub fn get_path_span(&self, tcx: TyCtxt<'tcx>) -> Span { + if let Some(path_expr_id) = self.info.path_expr_id { + tcx.hir().span(path_expr_id) + } else if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id { + tcx.hir().span(capture_kind_expr_id) + } else { + // Fallback on upvars mentioned if neither path or capture expr id is captured + + // Safe to unwrap since we know this place is captured by the closure, therefore the closure must have upvars. + tcx.upvars_mentioned(self.get_closure_local_def_id()).unwrap() + [&self.get_root_variable()] + .span + } + } + /// Return span pointing to use that resulted in selecting the current capture kind pub fn get_capture_kind_span(&self, tcx: TyCtxt<'tcx>) -> Span { if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 9f19a474ca38bdf9809915f61590294211d4a9cb..30e0b293ffb2f0840acce9f6f8ad7d879a4b4104 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -99,7 +99,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized( ); err.span_label(span, format!("use of possibly-uninitialized {}", item_msg)); - use_spans.var_span_label( + use_spans.var_span_label_path_only( &mut err, format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), ); @@ -255,6 +255,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized( partially_str, move_spans.describe() ), + "moved", ); } } @@ -304,7 +305,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized( } } - use_spans.var_span_label( + use_spans.var_span_label_path_only( &mut err, format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), ); @@ -434,13 +435,16 @@ pub(in crate::borrow_check) fn report_move_out_while_borrowed( err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); err.span_label(span, format!("move out of {} occurs here", value_msg)); - borrow_spans.var_span_label( + borrow_spans.var_span_label_path_only( &mut err, format!("borrow occurs due to use{}", borrow_spans.describe()), ); - move_spans - .var_span_label(&mut err, format!("move occurs due to use{}", move_spans.describe())); + move_spans.var_span_label( + &mut err, + format!("move occurs due to use{}", move_spans.describe()), + "moved", + ); self.explain_why_borrow_contains_point(location, borrow, None) .add_explanation_to_diagnostic( @@ -468,6 +472,8 @@ pub(in crate::borrow_check) fn report_use_while_mutably_borrowed( let use_spans = self.move_spans(place.as_ref(), location); let span = use_spans.var_or_use(); + // If the attempted use is in a closure then we do not care about the path span of the place we are currently trying to use + // we call `var_span_label` on `borrow_spans` to annotate if the existing borrow was in a closure let mut err = self.cannot_use_when_mutably_borrowed( span, &self.describe_any_place(place.as_ref()), @@ -475,11 +481,15 @@ pub(in crate::borrow_check) fn report_use_while_mutably_borrowed( &self.describe_any_place(borrow.borrowed_place.as_ref()), ); - borrow_spans.var_span_label(&mut err, { - let place = &borrow.borrowed_place; - let desc_place = self.describe_any_place(place.as_ref()); - format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe()) - }); + borrow_spans.var_span_label( + &mut err, + { + let place = &borrow.borrowed_place; + let desc_place = self.describe_any_place(place.as_ref()); + format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe()) + }, + "mutable", + ); self.explain_why_borrow_contains_point(location, borrow, None) .add_explanation_to_diagnostic( @@ -591,6 +601,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow( desc_place, borrow_spans.describe(), ), + "immutable", ); return err; @@ -667,7 +678,8 @@ pub(in crate::borrow_check) fn report_conflicting_borrow( if issued_spans == borrow_spans { borrow_spans.var_span_label( &mut err, - format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe()), + format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe(),), + gen_borrow_kind.describe_mutability(), ); } else { let borrow_place = &issued_borrow.borrowed_place; @@ -679,6 +691,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow( borrow_place_desc, issued_spans.describe(), ), + issued_borrow.kind.describe_mutability(), ); borrow_spans.var_span_label( @@ -688,6 +701,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow( desc_place, borrow_spans.describe(), ), + gen_borrow_kind.describe_mutability(), ); } @@ -847,7 +861,7 @@ pub(in crate::borrow_check) fn report_borrowed_value_does_not_live_long_enough( self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap(); let borrow_spans = self.retrieve_borrow_spans(borrow); - let borrow_span = borrow_spans.var_or_use(); + let borrow_span = borrow_spans.var_or_use_path_span(); assert!(root_place.projection.is_empty()); let proper_span = self.body.local_decls[root_place.local].source_info.span; @@ -987,7 +1001,7 @@ fn report_local_value_does_not_live_long_enough( location, name, borrow, drop_span, borrow_spans ); - let borrow_span = borrow_spans.var_or_use(); + let borrow_span = borrow_spans.var_or_use_path_span(); if let BorrowExplanation::MustBeValidFor { category, span, @@ -1575,6 +1589,7 @@ pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed( loan_spans.var_span_label( &mut err, format!("borrow occurs due to use{}", loan_spans.describe()), + loan.kind.describe_mutability(), ); err.buffer(&mut self.errors_buffer); @@ -1585,8 +1600,11 @@ pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed( let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place); - loan_spans - .var_span_label(&mut err, format!("borrow occurs due to use{}", loan_spans.describe())); + loan_spans.var_span_label( + &mut err, + format!("borrow occurs due to use{}", loan_spans.describe()), + loan.kind.describe_mutability(), + ); self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic( self.infcx.tcx, diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index 2a388b8a72bb05b4aa3ff9a7099ccfcae3850e85..3ebf23c99a904b62b43cfd71f6dcdb22a2491359 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs @@ -24,8 +24,8 @@ #[derive(Debug)] pub(in crate::borrow_check) enum BorrowExplanation { - UsedLater(LaterUseKind, Span), - UsedLaterInLoop(LaterUseKind, Span), + UsedLater(LaterUseKind, Span, Option), + UsedLaterInLoop(LaterUseKind, Span, Option), UsedLaterWhenDropped { drop_loc: Location, dropped_local: Local, @@ -67,7 +67,7 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>( borrow_span: Option, ) { match *self { - BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => { + 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", @@ -75,14 +75,31 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>( LaterUseKind::FakeLetRead => "stored here", LaterUseKind::Other => "used here", }; - if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) { - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, message), - ); + // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same + if path_span.map_or(true, |path_span| path_span == var_or_use_span) { + if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) { + err.span_label( + var_or_use_span, + format!("{}borrow later {}", 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_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); + } } } - BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => { + 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" @@ -94,7 +111,24 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>( LaterUseKind::FakeLetRead => "borrow later stored here", LaterUseKind::Other => "borrow used here, in later iteration of loop", }; - err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message)); + // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same + if path_span.map_or(true, |path_span| path_span == var_or_use_span) { + 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_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); + } + } } BorrowExplanation::UsedLaterWhenDropped { drop_loc, @@ -311,13 +345,13 @@ pub(in crate::borrow_check) fn explain_why_borrow_contains_point( let borrow_location = location; if self.is_use_in_later_iteration_of_loop(borrow_location, location) { let later_use = self.later_use_kind(borrow, spans, location); - BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1) + BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1, later_use.2) } else { // Check if the location represents a `FakeRead`, and adapt the error // message to the `FakeReadCause` it is from: in particular, // the ones inserted in optimized `let var = ` patterns. let later_use = self.later_use_kind(borrow, spans, location); - BorrowExplanation::UsedLater(later_use.0, later_use.1) + BorrowExplanation::UsedLater(later_use.0, later_use.1, later_use.2) } } @@ -498,16 +532,19 @@ fn is_back_edge(&self, source: Location, target: Location) -> bool { } /// Determine how the borrow was later used. + /// First span returned points to the location of the conflicting use + /// Second span if `Some` is returned in the case of closures and points + /// to the use of the path fn later_use_kind( &self, borrow: &BorrowData<'tcx>, use_spans: UseSpans<'tcx>, location: Location, - ) -> (LaterUseKind, Span) { + ) -> (LaterUseKind, Span, Option) { match use_spans { - UseSpans::ClosureUse { var_span, .. } => { + UseSpans::ClosureUse { capture_kind_span, path_span, .. } => { // Used in a closure. - (LaterUseKind::ClosureCapture, var_span) + (LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span)) } UseSpans::PatUse(span) | UseSpans::OtherUse(span) @@ -542,7 +579,7 @@ fn later_use_kind( } } }; - return (LaterUseKind::Call, function_span); + return (LaterUseKind::Call, function_span, None); } else { LaterUseKind::Other } @@ -550,7 +587,7 @@ fn later_use_kind( LaterUseKind::Other }; - (kind, span) + (kind, span, None) } } } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index aa9f18d99962892334fb16c6bcbcb466b15094b7..3a80bc3d1813891ea3cf83c1e341b757ec9f56a2 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -18,7 +18,6 @@ Span, }; use rustc_target::abi::VariantIdx; -use std::iter; use super::borrow_set::BorrowData; use super::MirBorrowckCtxt; @@ -216,11 +215,10 @@ fn append_place_to_string( PlaceRef { local, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { - // FIXME(project-rfc_2229#36): print capture precisely here. let upvar_field_projection = self.is_upvar_field_projection(place); if let Some(field) = upvar_field_projection { let var_index = field.index(); - let name = self.upvars[var_index].name.to_string(); + let name = self.upvars[var_index].place.to_string(self.infcx.tcx); if self.upvars[var_index].by_ref { buf.push_str(&name); } else { @@ -265,7 +263,7 @@ fn append_place_to_string( let upvar_field_projection = self.is_upvar_field_projection(place); if let Some(field) = upvar_field_projection { let var_index = field.index(); - let name = self.upvars[var_index].name.to_string(); + let name = self.upvars[var_index].place.to_string(self.infcx.tcx); buf.push_str(&name); } else { let field_name = self @@ -550,8 +548,12 @@ pub(super) enum UseSpans<'tcx> { /// The span of the args of the closure, including the `move` keyword if /// it's present. args_span: Span, - /// The span of the first use of the captured variable inside the closure. - var_span: Span, + /// The span of the use resulting in capture kind + /// Check `ty::CaptureInfo` for more details + capture_kind_span: Span, + /// The span of the use resulting in the captured path + /// Check `ty::CaptureInfo` for more details + path_span: Span, }, /// The access is caused by using a variable as the receiver of a method /// that takes 'self' @@ -606,9 +608,21 @@ pub(super) fn args_or_use(self) -> Span { } } + pub(super) fn var_or_use_path_span(self) -> Span { + match self { + UseSpans::ClosureUse { path_span: span, .. } + | UseSpans::PatUse(span) + | UseSpans::OtherUse(span) => span, + UseSpans::FnSelfUse { + fn_call_span, kind: FnSelfUseKind::DerefCoercion { .. }, .. + } => fn_call_span, + UseSpans::FnSelfUse { var_span, .. } => var_span, + } + } + pub(super) fn var_or_use(self) -> Span { match self { - UseSpans::ClosureUse { var_span: span, .. } + UseSpans::ClosureUse { capture_kind_span: span, .. } | UseSpans::PatUse(span) | UseSpans::OtherUse(span) => span, UseSpans::FnSelfUse { @@ -636,14 +650,35 @@ pub(super) fn args_span_label( } } + // Add a span label to the use of the captured variable, if it exists. + // only adds label to the `path_span` + pub(super) fn var_span_label_path_only( + self, + err: &mut DiagnosticBuilder<'_>, + message: impl Into, + ) { + if let UseSpans::ClosureUse { path_span, .. } = self { + err.span_label(path_span, message); + } + } + // Add a span label to the use of the captured variable, if it exists. pub(super) fn var_span_label( self, err: &mut DiagnosticBuilder<'_>, message: impl Into, + kind_desc: impl Into, ) { - if let UseSpans::ClosureUse { var_span, .. } = self { - err.span_label(var_span, message); + if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self { + if capture_kind_span == path_span { + err.span_label(capture_kind_span, message); + } else { + let capture_kind_label = + format!("capture is {} because of use here", kind_desc.into()); + let path_label = message; + err.span_label(capture_kind_span, capture_kind_label); + err.span_label(path_span, path_label); + } } } @@ -791,10 +826,15 @@ pub(super) fn move_spans( box AggregateKind::Closure(def_id, _) | box AggregateKind::Generator(def_id, _, _) => { debug!("move_spans: def_id={:?} places={:?}", def_id, places); - if let Some((args_span, generator_kind, var_span)) = + if let Some((args_span, generator_kind, capture_kind_span, path_span)) = self.closure_span(*def_id, moved_place, places) { - return ClosureUse { generator_kind, args_span, var_span }; + return ClosureUse { + generator_kind, + args_span, + capture_kind_span, + path_span, + }; } } _ => {} @@ -809,10 +849,15 @@ pub(super) fn move_spans( | FakeReadCause::ForLet(Some(closure_def_id)) => { debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place); let places = &[Operand::Move(*place)]; - if let Some((args_span, generator_kind, var_span)) = + if let Some((args_span, generator_kind, capture_kind_span, path_span)) = self.closure_span(closure_def_id, moved_place, places) { - return ClosureUse { generator_kind, args_span, var_span }; + return ClosureUse { + generator_kind, + args_span, + capture_kind_span, + path_span, + }; } } _ => {} @@ -972,10 +1017,10 @@ pub(super) fn borrow_spans(&self, use_span: Span, location: Location) -> UseSpan "borrow_spans: def_id={:?} is_generator={:?} places={:?}", def_id, is_generator, places ); - if let Some((args_span, generator_kind, var_span)) = + if let Some((args_span, generator_kind, capture_kind_span, path_span)) = self.closure_span(*def_id, Place::from(target).as_ref(), places) { - return ClosureUse { generator_kind, args_span, var_span }; + return ClosureUse { generator_kind, args_span, capture_kind_span, path_span }; } else { return OtherUse(use_span); } @@ -989,13 +1034,15 @@ pub(super) fn borrow_spans(&self, use_span: Span, location: Location) -> UseSpan OtherUse(use_span) } - /// Finds the span of a captured variable within a closure or generator. + /// Finds the spans of a captured place within a closure or generator. + /// The first span is the location of the use resulting in the capture kind of the capture + /// The second span is the location the use resulting in the captured path of the capture fn closure_span( &self, def_id: DefId, target_place: PlaceRef<'tcx>, places: &[Operand<'tcx>], - ) -> Option<(Span, Option, Span)> { + ) -> Option<(Span, Option, Span, Span)> { debug!( "closure_span: def_id={:?} target_place={:?} places={:?}", def_id, target_place, places @@ -1005,13 +1052,13 @@ fn closure_span( let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr { - for (captured_place, place) in iter::zip( - self.infcx.tcx.typeck(def_id.expect_local()).closure_min_captures_flattened(def_id), - places, - ) { - let upvar_hir_id = captured_place.get_root_variable(); - //FIXME(project-rfc-2229#8): Use better span from captured_place - let span = self.infcx.tcx.upvars_mentioned(local_did)?[&upvar_hir_id].span; + for (captured_place, place) in self + .infcx + .tcx + .typeck(def_id.expect_local()) + .closure_min_captures_flattened(def_id) + .zip(places) + { match place { Operand::Copy(place) | Operand::Move(place) if target_place == place.as_ref() => @@ -1020,18 +1067,12 @@ fn closure_span( let body = self.infcx.tcx.hir().body(*body_id); let generator_kind = body.generator_kind(); - // If we have a more specific span available, point to that. - // We do this even though this span might be part of a borrow error - // message rather than a move error message. Our goal is to point - // to a span that shows why the upvar is used in the closure, - // so a move-related span is as good as any (and potentially better, - // if the overall error is due to a move of the upvar). - - let usage_span = match captured_place.info.capture_kind { - ty::UpvarCapture::ByValue(Some(span)) => span, - _ => span, - }; - return Some((*args_span, generator_kind, usage_span)); + return Some(( + *args_span, + generator_kind, + captured_place.get_capture_kind_span(self.infcx.tcx), + captured_place.get_path_span(self.infcx.tcx), + )); } _ => {} } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs index fb7694b7d88e969ce71641a8ae982d71cd1e9dc5..3f87d9c7ac94811ebb95ba53e97bed6b7e8bfcea 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs @@ -345,10 +345,8 @@ fn report_cannot_move_from_borrowed_content( }; let upvar = &self.upvars[upvar_field.unwrap().index()]; - // FIXME(project-rfc-2229#8): Improve borrow-check diagnostics in case of precise - // capture. let upvar_hir_id = upvar.place.get_root_variable(); - let upvar_name = upvar.name; + let upvar_name = upvar.place.to_string(self.infcx.tcx); let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id); let place_name = self.describe_any_place(move_place.as_ref()); @@ -478,8 +476,11 @@ fn add_move_hints( self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), ""); use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc)); - use_spans - .var_span_label(err, format!("move occurs due to use{}", use_spans.describe())); + use_spans.var_span_label( + err, + format!("move occurs due to use{}", use_spans.describe()), + "moved", + ); } } } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index d1fb999e518ca59b46dda2ce97d4193e2a51f0a8..88122777d2e67e2d32e9e939594b855f0d488dba 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -85,7 +85,7 @@ pub(crate) fn report_mutability_error( if self.is_upvar_field_projection(access_place.as_ref()).is_some() { reason = ", as it is not declared as mutable".to_string(); } else { - let name = self.upvars[upvar_index.index()].name; + let name = self.upvars[upvar_index.index()].place.to_string(self.infcx.tcx); reason = format!(", as `{}` is not declared as mutable", name); } } @@ -195,6 +195,7 @@ pub(crate) fn report_mutability_error( "mutable borrow occurs due to use of {} in closure", self.describe_any_place(access_place.as_ref()), ), + "mutable", ); borrow_span } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs index 058986593a41b9759c4c7f8c3e66a60cf2700361..c3f781c0e9e305efd4eed5c670562c0ea47eb55f 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs @@ -385,6 +385,7 @@ fn report_fnmut_error( diag.span_label(*span, message); + // FIXME: This should store a captured_place not a hir id if let ReturnConstraint::ClosureUpvar(upvar) = kind { let def_id = match self.regioncx.universal_regions().defining_ty { DefiningTy::Closure(def_id, _) => def_id, diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 2d1d83b1655aa7b0bf3f2106bcb9c644871ae201..4c35be39a3d3389215fc9f005052a2ca7c98e069 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -74,9 +74,6 @@ // FIXME(eddyb) perhaps move this somewhere more centrally. #[derive(Debug)] crate struct Upvar<'tcx> { - // FIXME(project-rfc_2229#36): print capture precisely here. - name: Symbol, - place: CapturedPlace<'tcx>, /// If true, the capture is behind a reference. @@ -159,13 +156,12 @@ fn do_mir_borrowck<'a, 'tcx>( let upvars: Vec<_> = tables .closure_min_captures_flattened(def.did.to_def_id()) .map(|captured_place| { - let var_hir_id = captured_place.get_root_variable(); let capture = captured_place.info.capture_kind; let by_ref = match capture { ty::UpvarCapture::ByValue(_) => false, ty::UpvarCapture::ByRef(..) => true, }; - Upvar { name: tcx.hir().name(var_hir_id), place: captured_place.clone(), by_ref } + Upvar { place: captured_place.clone(), by_ref } }) .collect(); diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 532ee00daf8a0a306aa62ab1d79455a2287371b1..f17494127948414f1c363abde40bf5878701c439 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -763,7 +763,9 @@ fn upvar_is_local_variable( PlaceBase::Local(*var_hir_id) }; let place_with_id = PlaceWithHirId::new( - capture_info.path_expr_id.unwrap_or(closure_expr.hir_id), + capture_info.path_expr_id.unwrap_or( + capture_info.capture_kind_expr_id.unwrap_or(closure_expr.hir_id), + ), place.base_ty, place_base, place.projections.clone(), diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr index 193026541d073433629c5f00547375cff6cc1110..599d0e135579090cbed9568ec2044dc373c6855f 100644 --- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr @@ -21,9 +21,9 @@ error[E0373]: async block may outlive the current function, but it borrows `x`, --> $DIR/async-borrowck-escaping-block-error.rs:11:11 | LL | async { *x } - | ^^^-^^ - | | | - | | `x` is borrowed here + | ^^--^^ + | | | + | | `x` is borrowed here | may outlive borrowed value `x` | note: async block is returned here diff --git a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr index edeb21c16d3c88e6296d111342494f371a40cfe6..fadcd11a592aa7444c98852e6d9ce31b28f1a35a 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr @@ -73,7 +73,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/borrowck-closures-mut-and-imm.rs:57:5 | LL | let c1 = || get(&*x); - | -- - borrow occurs due to use in closure + | -- -- borrow occurs due to use in closure | | | borrow of `*x` occurs here LL | *x = 5; @@ -86,7 +86,7 @@ error[E0506]: cannot assign to `*x.f` because it is borrowed --> $DIR/borrowck-closures-mut-and-imm.rs:69:5 | LL | let c1 = || get(&*x.f); - | -- - borrow occurs due to use in closure + | -- ---- borrow occurs due to use in closure | | | borrow of `*x.f` occurs here LL | *x.f = 5; @@ -99,11 +99,11 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/borrowck-closures-mut-and-imm.rs:81:14 | LL | let c1 = || get(&*x.f); - | -- - first borrow occurs due to use of `x` in closure + | -- ---- first borrow occurs due to use of `x` in closure | | | immutable borrow occurs here LL | let c2 = || *x.f = 5; - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ ---- second borrow occurs due to use of `x` in closure | | | mutable borrow occurs here LL | diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr index 784b903a5896acd1eb37d8ee87ecbfe50714fe37..537ec9895e106eb203b5e3cf94d6549ff07c94f3 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr @@ -14,12 +14,12 @@ error[E0524]: two closures require unique access to `x` at the same time --> $DIR/borrowck-closures-mut-of-imm.rs:11:18 | LL | let mut c1 = || set(&mut *x); - | -- - first borrow occurs due to use of `x` in closure + | -- -- first borrow occurs due to use of `x` in closure | | | first closure is constructed here LL | LL | let mut c2 = || set(&mut *x); - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ -- second borrow occurs due to use of `x` in closure | | | second closure is constructed here ... diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr b/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr index 471173e595f4793cf3eec4844783c114a18d600f..e5ee5a401050a35049c9eaaa7fcfd2f3e24eb33e 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr @@ -2,11 +2,11 @@ error[E0524]: two closures require unique access to `x` at the same time --> $DIR/borrowck-closures-mut-of-mut.rs:14:18 | LL | let mut c1 = || set(&mut *x); - | -- - first borrow occurs due to use of `x` in closure + | -- -- first borrow occurs due to use of `x` in closure | | | first closure is constructed here LL | let mut c2 = || set(&mut *x); - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ -- second borrow occurs due to use of `x` in closure | | | second closure is constructed here LL | diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr index 9e1e47a92412a4f21ac457fe90061100a8cf9bca..411d85b8e0562c7d1c18c17c13cd3c4d064bb986 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr @@ -45,7 +45,7 @@ error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immut LL | let f = || { | -- immutable borrow occurs here LL | let [ref y, ref z @ ..] = *x; - | - first borrow occurs due to use of `x` in closure + | -- first borrow occurs due to use of `x` in closure LL | }; LL | let r = &mut *x; | ^^^^^^^ mutable borrow occurs here @@ -59,7 +59,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u LL | let mut f = || { | -- closure construction occurs here LL | let [ref mut y, ref mut z @ ..] = *x; - | - first borrow occurs due to use of `x` in closure + | -- first borrow occurs due to use of `x` in closure LL | }; LL | let r = &x; | ^^ second borrow occurs here @@ -86,7 +86,7 @@ error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immut LL | let f = || { | -- immutable borrow occurs here LL | if let [ref y, ref z @ ..] = *x {} - | - first borrow occurs due to use of `x` in closure + | -- first borrow occurs due to use of `x` in closure LL | }; LL | let r = &mut *x; | ^^^^^^^ mutable borrow occurs here @@ -100,7 +100,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u LL | let mut f = || { | -- closure construction occurs here LL | if let [ref mut y, ref mut z @ ..] = *x {} - | - first borrow occurs due to use of `x` in closure + | -- first borrow occurs due to use of `x` in closure LL | }; LL | let r = &x; | ^^ second borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr index 07f477d17868f8a4689f108eafcbe04989524c61..fe8e7a29e2486fba8f9a0491113561a3a558cd29 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr @@ -59,11 +59,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/borrowck-closures-two-mut-fail.rs:53:24 | LL | let c1 = to_fn_mut(|| set(&mut *x.f)); - | -- - first borrow occurs due to use of `x` in closure + | -- ---- first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| set(&mut *x.f)); - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ ---- second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here LL | diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr index bffb11640744c6bf7b06d900b28db9dbb7dd690b..21e329f432939fabb7a1e4ec44279a7d4b25286b 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr @@ -59,11 +59,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/borrowck-closures-two-mut.rs:49:24 | LL | let c1 = to_fn_mut(|| set(&mut *x.f)); - | -- - first borrow occurs due to use of `x` in closure + | -- ---- first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| set(&mut *x.f)); - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ ---- second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here LL | diff --git a/src/test/ui/borrowck/borrowck-closures-unique.stderr b/src/test/ui/borrowck/borrowck-closures-unique.stderr index 64c2f419ffa65eff5ce39c68f257e55a3fcf8795..23d3cc0e76ff71dccb83d7d359942df2e7b11fd9 100644 --- a/src/test/ui/borrowck/borrowck-closures-unique.stderr +++ b/src/test/ui/borrowck/borrowck-closures-unique.stderr @@ -20,7 +20,7 @@ LL | let c1 = || get(x); | | | borrow occurs here LL | let c2 = || { get(x); set(x); }; - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | closure construction occurs here LL | c1; diff --git a/src/test/ui/borrowck/borrowck-closures-use-after-free.stderr b/src/test/ui/borrowck/borrowck-closures-use-after-free.stderr index f22b7da811949293aaea9b318b6dbdede47f29a0..a6dbcf36077a728b704effd7ccff75c735edcb37 100644 --- a/src/test/ui/borrowck/borrowck-closures-use-after-free.stderr +++ b/src/test/ui/borrowck/borrowck-closures-use-after-free.stderr @@ -4,7 +4,7 @@ error[E0502]: cannot borrow `*ptr` as immutable because it is also borrowed as m LL | let mut test = |foo: &Foo| { | ----------- mutable borrow occurs here LL | ptr = box Foo { x: ptr.x + 1 }; - | --- first borrow occurs due to use of `ptr` in closure + | --- first borrow occurs due to use of `ptr` in closure LL | }; LL | test(&*ptr); | ---- ^^^^^ immutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-insert-during-each.stderr b/src/test/ui/borrowck/borrowck-insert-during-each.stderr index 796390c093b1037817c8b377bec889c1be2a0195..a1ac45795fae2e4206d2adba477bc50e81b78d20 100644 --- a/src/test/ui/borrowck/borrowck-insert-during-each.stderr +++ b/src/test/ui/borrowck/borrowck-insert-during-each.stderr @@ -9,7 +9,7 @@ LL | | LL | | |a| { | | --- closure construction occurs here LL | | f.n.insert(*a); - | | - first borrow occurs due to use of `f` in closure + | | --- first borrow occurs due to use of `f` in closure LL | | }) | |__________^ second borrow occurs here @@ -24,7 +24,7 @@ LL | LL | |a| { | ^^^ closure construction occurs here LL | f.n.insert(*a); - | - second borrow occurs due to use of `f` in closure + | --- second borrow occurs due to use of `f` in closure error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr b/src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr index 2acbcd94f8bbf027e4e4d4c31922e7b5994c90d4..ac25502ad053c052f96705f5b5223ce170da10e3 100644 --- a/src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr +++ b/src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr @@ -7,7 +7,7 @@ LL | thread::spawn(move|| { | ^^^^^^ move out of `v` occurs here LL | LL | println!("v={}", *v); - | - move occurs due to use in closure + | -- move occurs due to use in closure LL | }); LL | w.use_ref(); | - borrow later used here @@ -21,7 +21,7 @@ LL | thread::spawn(move|| { | ^^^^^^ move out of `v` occurs here LL | LL | println!("v={}", *v); - | - move occurs due to use in closure + | -- move occurs due to use in closure LL | }); LL | w.use_ref(); | - borrow later used here diff --git a/src/test/ui/borrowck/borrowck-loan-rcvr.stderr b/src/test/ui/borrowck/borrowck-loan-rcvr.stderr index ec3edc80323f526400cc594d1857179ed0330256..489ec7d04ed1d1791e227932db4b760e029e100c 100644 --- a/src/test/ui/borrowck/borrowck-loan-rcvr.stderr +++ b/src/test/ui/borrowck/borrowck-loan-rcvr.stderr @@ -7,7 +7,7 @@ LL | p.blockm(|| { | | immutable borrow later used by call | immutable borrow occurs here LL | p.x = 10; - | - second borrow occurs due to use of `p` in closure + | --- second borrow occurs due to use of `p` in closure error[E0502]: cannot borrow `p` as immutable because it is also borrowed as mutable --> $DIR/borrowck-loan-rcvr.rs:34:5 diff --git a/src/test/ui/borrowck/borrowck-move-by-capture.stderr b/src/test/ui/borrowck/borrowck-move-by-capture.stderr index 837bd08253b3bab6b207778dc89560c85ab4f384..628f206e0a89616cf7629b0ce1f6d5269c124820 100644 --- a/src/test/ui/borrowck/borrowck-move-by-capture.stderr +++ b/src/test/ui/borrowck/borrowck-move-by-capture.stderr @@ -5,10 +5,10 @@ LL | let bar: Box<_> = box 3; | --- captured outer variable LL | let _g = to_fn_mut(|| { LL | let _h = to_fn_once(move || -> isize { *bar }); - | ^^^^^^^^^^^^^^^^ --- - | | | - | | move occurs because `bar` has type `Box`, which does not implement the `Copy` trait - | | move occurs due to use in closure + | ^^^^^^^^^^^^^^^^ ---- + | | | + | | move occurs because `bar` has type `Box`, which does not implement the `Copy` trait + | | move occurs due to use in closure | move out of `bar` occurs here error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr index 44f423c2bd9360a34c008b6dae688f4d5564b57c..1ac4999e6e11d8d78144fbfa8f79eb2ddca652b9 100644 --- a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr +++ b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr @@ -5,11 +5,11 @@ LL | let t: Box<_> = box 3; | - move occurs because `t` has type `Box`, which does not implement the `Copy` trait LL | LL | call_f(move|| { *t + 1 }); - | ------ - variable moved due to use in closure + | ------ -- variable moved due to use in closure | | | value moved into closure here LL | call_f(move|| { *t + 1 }); - | ^^^^^^ - use occurs due to use in closure + | ^^^^^^ -- use occurs due to use in closure | | | value used here after move diff --git a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr index f0a3151f4e12f149f1e37af4c23ba34bf0294ce7..dd46308d140045cf48328185d283b5d2c4243e6e 100644 --- a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr +++ b/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr @@ -5,7 +5,7 @@ LL | match x { | - value is immutable in match guard ... LL | (|| { *x = None; drop(force_fn_once); })(); - | ^^ - borrow occurs due to use of `x` in closure + | ^^ -- borrow occurs due to use of `x` in closure | | | cannot mutably borrow diff --git a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr index f0264b56ea569fdd8fe252fe63f7205d734d59e2..48433432de1bd7ccccf307f0230a603257778528 100644 --- a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr +++ b/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern g --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25 | LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); - | ^^ - mutable borrow occurs due to use of `r` in closure + | ^^ -- mutable borrow occurs due to use of `r` in closure | | | cannot borrow as mutable | diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f3358dcd8db71d3d8749dffd35348aa0ad9bdb6 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs @@ -0,0 +1,20 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} +fn main() { + let mut p = Point {x: 1, y: 2 }; + + let y = &mut p.y; + let mut c = || { + //~^ ERROR cannot borrow `p` as mutable more than once at a time + let x = &mut p.x; + println!("{:?}", p); + }; + c(); + *y+=1; +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e15067b264d63af8e850c67b9dc122c9ddb4dfbc --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr @@ -0,0 +1,28 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/borrowck-1.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0499]: cannot borrow `p` as mutable more than once at a time + --> $DIR/borrowck-1.rs:13:17 + | +LL | let y = &mut p.y; + | -------- first mutable borrow occurs here +LL | let mut c = || { + | ^^ second mutable borrow occurs here +LL | +LL | let x = &mut p.x; + | --- capture is mutable because of use here +LL | println!("{:?}", p); + | - second borrow occurs due to use of `p` in closure +... +LL | *y+=1; + | ----- first borrow later used here + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs new file mode 100644 index 0000000000000000000000000000000000000000..06c6a87eb105dd0170001930a8e9b6ec688fd43b --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs @@ -0,0 +1,20 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} +fn main() { + let mut p = Point {x: 1, y: 2 }; + + let y = &p.y; + let mut c = || { + //~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable + println!("{:?}", p); + let x = &mut p.x; + }; + c(); + println!("{}", y); +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr new file mode 100644 index 0000000000000000000000000000000000000000..a195b981eaadd416aaaa4497f3a5d45911dd1199 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr @@ -0,0 +1,28 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/borrowck-2.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-2.rs:13:17 + | +LL | let y = &p.y; + | ---- immutable borrow occurs here +LL | let mut c = || { + | ^^ mutable borrow occurs here +LL | +LL | println!("{:?}", p); + | - second borrow occurs due to use of `p` in closure +LL | let x = &mut p.x; + | --- capture is mutable because of use here +... +LL | println!("{}", y); + | - immutable borrow later used here + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba998f78c87acb68f7ce3383b61879198d349454 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs @@ -0,0 +1,19 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +#[derive(Debug)] +struct Point { + x: String, + y: String, +} +fn main() { + let mut c = { + let mut p = Point {x: "1".to_string(), y: "2".to_string() }; + || { + let x = &mut p.x; + println!("{:?}", p); + //~^ ERROR `p` does not live long enough + } + }; + c(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr new file mode 100644 index 0000000000000000000000000000000000000000..b54c729a307c0c61b19c46a99bbe1c2d8438a3cf --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr @@ -0,0 +1,27 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/borrowck-3.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0597]: `p` does not live long enough + --> $DIR/borrowck-3.rs:14:29 + | +LL | let mut c = { + | ----- borrow later stored here +LL | let mut p = Point {x: "1".to_string(), y: "2".to_string() }; +LL | || { + | -- value captured here +LL | let x = &mut p.x; +LL | println!("{:?}", p); + | ^ borrowed value does not live long enough +... +LL | }; + | - `p` dropped here while still borrowed + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs new file mode 100644 index 0000000000000000000000000000000000000000..4fab0189c27f8df4de52b4f9866184bd9299dbe2 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs @@ -0,0 +1,21 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} +fn foo () -> impl FnMut()->() { + let mut p = Point {x: 1, y: 2 }; + let mut c = || { + //~^ ERROR closure may outlive the current function, but it borrows `p` + p.x+=5; + println!("{:?}", p); + }; + c +} +fn main() { + let c = foo(); + c(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr new file mode 100644 index 0000000000000000000000000000000000000000..905fa3475edd86644f148570208ad6ca2f159dee --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr @@ -0,0 +1,31 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/borrowck-4.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0373]: closure may outlive the current function, but it borrows `p`, which is owned by the current function + --> $DIR/borrowck-4.rs:11:17 + | +LL | let mut c = || { + | ^^ may outlive borrowed value `p` +... +LL | println!("{:?}", p); + | - `p` is borrowed here + | +note: closure is returned here + --> $DIR/borrowck-4.rs:9:14 + | +LL | fn foo () -> impl FnMut()->() { + | ^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword + | +LL | let mut c = move || { + | ^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs new file mode 100644 index 0000000000000000000000000000000000000000..b23947ad5d1bff38b74c1f3cdc473f9e39de3a83 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs @@ -0,0 +1,26 @@ +// Tests that two closures cannot simultaneously have mutable +// and immutable access to the variable. Issue #6801. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +#![feature(box_syntax)] + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} + +fn a() { + let mut p = Point {x: 3, y:4}; + let c2 = || p.y * 5; + let c1 = || { + //~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable + dbg!(&p); + p.x = 4; + }; + drop(c2); +} + +fn main() { +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr new file mode 100644 index 0000000000000000000000000000000000000000..58975c6f46fe49fa8671c901312862bfd1b700ef --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr @@ -0,0 +1,30 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/borrowck-closures-mut-and-imm.rs:4:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-closures-mut-and-imm.rs:17:14 + | +LL | let c2 = || p.y * 5; + | -- --- first borrow occurs due to use of `p.y` in closure + | | + | immutable borrow occurs here +LL | let c1 = || { + | ^^ mutable borrow occurs here +LL | +LL | dbg!(&p); + | - second borrow occurs due to use of `p` in closure +LL | p.x = 4; + | --- capture is mutable because of use here +LL | }; +LL | drop(c2); + | -- immutable borrow later used here + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr index 17a9332fb3e6c6b53c572477884c531c564a7de9..174faa33c49ab53b2cf8d3f8b16620b7548a4d20 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr @@ -13,7 +13,7 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed LL | let mut c = || { | -- borrow of `e.0.0.m.x` occurs here LL | e.0.0.m.x = format!("not-x"); - | - borrow occurs due to use in closure + | --------- borrow occurs due to use in closure ... LL | e.0.0.m.x = format!("not-x"); | ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here @@ -27,7 +27,7 @@ error[E0502]: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed LL | let mut c = || { | -- mutable borrow occurs here LL | e.0.0.m.x = format!("not-x"); - | - first borrow occurs due to use of `e.0.0.m.x` in closure + | --------- first borrow occurs due to use of `e.0.0.m.x` in closure ... LL | println!("{}", e.0.0.m.x); | ^^^^^^^^^ immutable borrow occurs here @@ -41,7 +41,7 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed LL | let c = || { | -- borrow of `e.0.0.m.x` occurs here LL | println!("{}", e.0.0.m.x); - | - borrow occurs due to use in closure + | --------- borrow occurs due to use in closure ... LL | e.0.0.m.x = format!("not-x"); | ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr index 861bc44b78ded3a7c08c554d2796ec5e6546ee0c..39a11fb332725881392d25e0e4a4306a72bb2d2a 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr @@ -14,7 +14,7 @@ LL | let mut c = || { | ^^ cannot borrow as mutable LL | LL | z.0.0.0 = format!("X1"); - | - mutable borrow occurs due to use of `z.0.0.0` in closure + | ------- mutable borrow occurs due to use of `z.0.0.0` in closure error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs index 997ecc7ddddf1eb33048f08f50c2a8c48aa28205..928c866726f71db5085b60093332ab695ad9a2bd 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs @@ -11,7 +11,7 @@ fn mut_error_struct() { let mut c = || { z.0.0.0 = 20; - //~^ ERROR: cannot assign to `z`, as it is not declared as mutable + //~^ ERROR: cannot assign to `z.0.0.0`, as it is not declared as mutable }; c(); @@ -23,7 +23,7 @@ fn mut_error_box() { let mut c = || { bx.0 = 20; - //~^ ERROR: cannot assign to `bx`, as it is not declared as mutable + //~^ ERROR: cannot assign to `*bx.0`, as it is not declared as mutable }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr index 5e15635ac6e1bf38f7c651c31aa06fd406e2e742..9fb8dd4a1c36e350bc414eebbf730262a51db7e2 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr @@ -7,7 +7,7 @@ LL | #![feature(capture_disjoint_fields)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #53488 for more information -error[E0594]: cannot assign to `z`, as it is not declared as mutable +error[E0594]: cannot assign to `z.0.0.0`, as it is not declared as mutable --> $DIR/cant-mutate-imm.rs:13:9 | LL | let z = (y, 10); @@ -16,7 +16,7 @@ LL | let z = (y, 10); LL | z.0.0.0 = 20; | ^^^^^^^^^^^^ cannot assign -error[E0594]: cannot assign to `bx`, as it is not declared as mutable +error[E0594]: cannot assign to `*bx.0`, as it is not declared as mutable --> $DIR/cant-mutate-imm.rs:25:9 | LL | let bx = Box::new(x); diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr index e5a396c4e98aed0233ba36c49c0eeebecba22e37..a3d1f550557affc7c7721d9a80f4b3d926e08097 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr @@ -13,7 +13,7 @@ error[E0499]: cannot borrow `w.p.x` as mutable more than once at a time LL | let mut c = || { | -- first mutable borrow occurs here LL | w.p.x += 20; - | - first borrow occurs due to use of `w.p.x` in closure + | ----- first borrow occurs due to use of `w.p.x` in closure ... LL | let py = &mut w.p.x; | ^^^^^^^^^^ second mutable borrow occurs here diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr index 8cb2ed2235d55395f2945d8e58b338e0c42226b1..831e486db82af60e5c01d39d943641b8ee3675b2 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr @@ -17,7 +17,7 @@ LL | let c = || { | ^^ `ref_mref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable LL | LL | **ref_mref_x = y; - | ---------- mutable borrow occurs due to use of `**ref_mref_x` in closure + | ------------ mutable borrow occurs due to use of `**ref_mref_x` in closure error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference --> $DIR/mut_ref.rs:27:13 @@ -26,7 +26,7 @@ LL | let c = || { | ^^ cannot borrow as mutable LL | LL | **mref_ref_x = y; - | ---------- mutable borrow occurs due to use of `**mref_ref_x` in closure + | ------------ mutable borrow occurs due to use of `**mref_ref_x` in closure error: aborting due to 2 previous errors; 1 warning emitted diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr index 45a61cd98b101d30e6a0596231a55c9ac5ffd943..f1748fda151c51a5ed52c81e0e78e1fc4ccd3ab8 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr @@ -13,7 +13,9 @@ error[E0502]: cannot borrow `p` as immutable because it is also borrowed as muta LL | let mut c = || { | -- mutable borrow occurs here LL | p.x += 10; - | - first borrow occurs due to use of `p` in closure + | --- capture is mutable because of use here +LL | println!("{:?}", p); + | - first borrow occurs due to use of `p` in closure ... LL | println!("{:?}", p); | ^ immutable borrow occurs here diff --git a/src/test/ui/error-codes/E0504.stderr b/src/test/ui/error-codes/E0504.stderr index 1f2a0407a39637fac1fcfe4b9c7c14bcc411c239..04811721aa521e6ceb82be56595e152b1d372290 100644 --- a/src/test/ui/error-codes/E0504.stderr +++ b/src/test/ui/error-codes/E0504.stderr @@ -7,7 +7,7 @@ LL | LL | let x = move || { | ^^^^^^^ move out of `fancy_num` occurs here LL | println!("child function: {}", fancy_num.num); - | --------- move occurs due to use in closure + | ------------- move occurs due to use in closure ... LL | println!("main function: {}", fancy_ref.num); | ------------- borrow later used here diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.stderr index fd885660d092758f61ff23236596e98bbb5a8ec1..68d785efcfe5d5620fa1e6c89604c92a74fd8d9f 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.stderr @@ -4,7 +4,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u LL | let mut b = || { | -- generator construction occurs here LL | let a = &mut *x; - | - first borrow occurs due to use of `x` in generator + | -- first borrow occurs due to use of `x` in generator ... LL | println!("{}", x); | ^ second borrow occurs here diff --git a/src/test/ui/issues/issue-11192.stderr b/src/test/ui/issues/issue-11192.stderr index dfe7b3f6b5f9c74262ad17deb52589e915479832..2a9d913171c3eed222679f0fd42f7de0919c80d0 100644 --- a/src/test/ui/issues/issue-11192.stderr +++ b/src/test/ui/issues/issue-11192.stderr @@ -5,7 +5,7 @@ LL | let mut test = |foo: &Foo| { | ----------- mutable borrow occurs here LL | println!("access {}", foo.x); LL | ptr = box Foo { x: ptr.x + 1 }; - | --- first borrow occurs due to use of `ptr` in closure + | --- first borrow occurs due to use of `ptr` in closure ... LL | test(&*ptr); | ---- ^^^^^ immutable borrow occurs here diff --git a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr index 188f0b25c30842494452728aa5e7f25b533bb7fd..a1f973e0fdf5a292d54ce23bc2b8b52f8d4a71bc 100644 --- a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr +++ b/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr @@ -5,7 +5,7 @@ LL | match x { | - value is immutable in match guard ... LL | (|| { *x = None; drop(force_fn_once); })(); - | ^^ - borrow occurs due to use of `x` in closure + | ^^ -- borrow occurs due to use of `x` in closure | | | cannot mutably borrow diff --git a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr b/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr index f46a42d7508176853d3c7e07edc9abd4b075008c..4a4a25790b985f516a1a658b86bbb37f31683c77 100644 --- a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr +++ b/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr @@ -5,7 +5,7 @@ LL | match **x { | --- value is immutable in match guard ... LL | (|| { *x = &None; drop(force_fn_once); })(); - | ^^ - borrow occurs due to use of `x` in closure + | ^^ -- borrow occurs due to use of `x` in closure | | | cannot mutably borrow diff --git a/src/test/ui/issues/issue-61623.stderr b/src/test/ui/issues/issue-61623.stderr index 883a1c441d6bbb6cb36281f7858792b54566f25c..901c75981768e63481afacd505435e4f9890c2fd 100644 --- a/src/test/ui/issues/issue-61623.stderr +++ b/src/test/ui/issues/issue-61623.stderr @@ -10,7 +10,7 @@ error[E0502]: cannot borrow `*x.1` as mutable because it is also borrowed as imm --> $DIR/issue-61623.rs:6:19 | LL | f2(|| x.0, f1(x.1)) - | -- -- - ^^^ mutable borrow occurs here + | -- -- --- ^^^ mutable borrow occurs here | | | | | | | first borrow occurs due to use of `x` in closure | | immutable borrow occurs here diff --git a/src/test/ui/issues/issue-6801.stderr b/src/test/ui/issues/issue-6801.stderr index dbb8e6530c0534d0e5288ee82ffce66930591501..48c6acd1f49e44a7e6447df407ce4be6fede7816 100644 --- a/src/test/ui/issues/issue-6801.stderr +++ b/src/test/ui/issues/issue-6801.stderr @@ -2,7 +2,7 @@ error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/issue-6801.rs:19:13 | LL | let sq = || { *x * *x }; - | -- - borrow occurs due to use in closure + | -- -- borrow occurs due to use in closure | | | borrow of `x` occurs here LL | diff --git a/src/test/ui/nll/closure-access-spans.stderr b/src/test/ui/nll/closure-access-spans.stderr index ccc043a189059240a05620e5921354fadfe98aaf..8eded8f28572e1fe3c322fd494a56fc36becc00f 100644 --- a/src/test/ui/nll/closure-access-spans.stderr +++ b/src/test/ui/nll/closure-access-spans.stderr @@ -28,7 +28,7 @@ error[E0500]: closure requires unique access to `x` but it is already borrowed LL | let r = &mut x; | ------ borrow occurs here LL | || *x = 2; - | ^^ - second borrow occurs due to use of `x` in closure + | ^^ -- second borrow occurs due to use of `x` in closure | | | closure construction occurs here LL | r.use_mut(); @@ -88,7 +88,7 @@ LL | fn closure_unique_capture_moved(x: &mut String) { LL | let r = x; | - value moved here LL | || *x = String::new(); - | ^^ - borrow occurs due to use in closure + | ^^ -- borrow occurs due to use in closure | | | value borrowed here after move diff --git a/src/test/ui/nll/closure-borrow-spans.stderr b/src/test/ui/nll/closure-borrow-spans.stderr index a3bcbbab3ec691214aaf7f9e946362a9b6683d8a..fffbee4d4a8e1218dc501721d182f4e06188cbb6 100644 --- a/src/test/ui/nll/closure-borrow-spans.stderr +++ b/src/test/ui/nll/closure-borrow-spans.stderr @@ -110,7 +110,7 @@ error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/closure-borrow-spans.rs:65:13 | LL | let f = || *x = 0; - | -- - borrow occurs due to use in closure + | -- -- borrow occurs due to use in closure | | | borrow of `x` occurs here LL | let y = x; @@ -122,7 +122,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u --> $DIR/closure-borrow-spans.rs:71:13 | LL | let f = || *x = 0; - | -- - first borrow occurs due to use of `x` in closure + | -- -- first borrow occurs due to use of `x` in closure | | | closure construction occurs here LL | let y = &x; @@ -134,7 +134,7 @@ error[E0501]: cannot borrow `x` as mutable because previous closure requires uni --> $DIR/closure-borrow-spans.rs:77:13 | LL | let f = || *x = 0; - | -- - first borrow occurs due to use of `x` in closure + | -- -- first borrow occurs due to use of `x` in closure | | | closure construction occurs here LL | let y = &mut x; @@ -143,10 +143,10 @@ LL | f.use_ref(); | - first borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:86:17 + --> $DIR/closure-borrow-spans.rs:86:16 | LL | f = || *x = 0; - | -- ^ borrowed value does not live long enough + | -- ^^ borrowed value does not live long enough | | | value captured here LL | } @@ -158,7 +158,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/closure-borrow-spans.rs:93:5 | LL | let f = || *x = 0; - | -- - borrow occurs due to use in closure + | -- -- borrow occurs due to use in closure | | | borrow of `*x` occurs here LL | *x = 1; diff --git a/src/test/ui/nll/closure-captures.stderr b/src/test/ui/nll/closure-captures.stderr index dd5f32ef4f5818ada0ebca63c9fea0f43ef8ec7b..a59e553315ae68f2be162c465120c804091d7ab6 100644 --- a/src/test/ui/nll/closure-captures.stderr +++ b/src/test/ui/nll/closure-captures.stderr @@ -133,9 +133,9 @@ LL | fn_ref(|| { LL | | || | | ^^ cannot borrow as mutable LL | | *x = 1;}); - | |__________-_____- in this closure - | | - | mutable borrow occurs due to use of `x` in closure + | |_________--_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:51:9 @@ -150,9 +150,9 @@ LL | fn_ref(move || { LL | | || | | ^^ cannot borrow as mutable LL | | *x = 1;}); - | |__________-_____- in this closure - | | - | mutable borrow occurs due to use of `x` in closure + | |_________--_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error: aborting due to 12 previous errors diff --git a/src/test/ui/nll/closure-use-spans.stderr b/src/test/ui/nll/closure-use-spans.stderr index ec7e0f308557db1530cce191ae9a46bd8fe1af0e..87162904ba6cd9c171756563d40a916ccf4dfa6a 100644 --- a/src/test/ui/nll/closure-use-spans.stderr +++ b/src/test/ui/nll/closure-use-spans.stderr @@ -6,7 +6,7 @@ LL | let y = &x; LL | x = 0; | ^^^^^ assignment to borrowed `x` occurs here LL | || *y; - | - borrow later captured here by closure + | -- borrow later captured here by closure error[E0506]: cannot assign to `x` because it is borrowed --> $DIR/closure-use-spans.rs:11:5 @@ -16,7 +16,7 @@ LL | let y = &mut x; LL | x = 0; | ^^^^^ assignment to borrowed `x` occurs here LL | || *y = 1; - | - borrow later captured here by closure + | -- borrow later captured here by closure error[E0506]: cannot assign to `x` because it is borrowed --> $DIR/closure-use-spans.rs:17:5 diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 2f134f83ced193ff188cdca97145dc8ad10830cc..2be0460df1fc67eaae9b4c1b1c4c758c058c4772 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -21,7 +21,7 @@ error[E0524]: two closures require unique access to `x` at the same time --> $DIR/closures-in-loops.rs:20:16 | LL | v.push(|| *x = String::new()); - | ^^ - borrows occur due to use of `x` in closure + | ^^ -- borrows occur due to use of `x` in closure | | | closures are constructed here in different iterations of loop diff --git a/src/test/ui/nll/issue-51268.stderr b/src/test/ui/nll/issue-51268.stderr index e6dadc9f6ce3c9c746e8d45d2b53d678336ac481..0483bda6379fd5ad332818e66f342128a060cc80 100644 --- a/src/test/ui/nll/issue-51268.stderr +++ b/src/test/ui/nll/issue-51268.stderr @@ -8,7 +8,7 @@ LL | self.thing.bar(|| { | | LL | | LL | | &self.number; - | | ---- first borrow occurs due to use of `self` in closure + | | ----------- first borrow occurs due to use of `self` in closure LL | | }); | |__________^ mutable borrow occurs here