From 6a3897f023e9824ddfe05657d3447b0fb64d4202 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Sun, 28 Aug 2022 16:23:59 +0800 Subject: [PATCH 1/6] pass without effor --- compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs | 3 +++ compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs | 3 +++ compiler/rustc_borrowck/src/diagnostics/find_use.rs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index b1def189230f..12f2b31addda 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; diff --git a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs index b3edc35dc364..498e9834354b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::BTreeSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index b5a3081e56a7..15f42e26cbf4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::VecDeque; use std::rc::Rc; From 877d3390d7ebe167977cd9f6f572787747a7dc4d Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Thu, 1 Sep 2022 12:35:10 +0800 Subject: [PATCH 2/6] BorrowUsedHere|Later --- .../src/diagnostics/explain_borrow.rs | 59 +++++++++++++------ .../rustc_borrowck/src/session_diagnostics.rs | 49 +++++++++++++++ .../locales/en-US/borrowck.ftl | 57 ++++++++++++++++++ 3 files changed, 147 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 2f61849c383c..b165297ad30f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -16,6 +16,7 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, DesugaringKind, Span}; use crate::region_infer::BlameConstraint; +use crate::session_diagnostics::{BorrowUsedHere, BorrowUsedLater}; use crate::{ borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, WriteKind, @@ -67,20 +68,28 @@ impl<'tcx> BorrowExplanation<'tcx> { ) { match *self { BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => { - let message = match later_use_kind { - LaterUseKind::TraitCapture => "captured here by trait object", - LaterUseKind::ClosureCapture => "captured here by closure", - LaterUseKind::Call => "used by call", - LaterUseKind::FakeLetRead => "stored here", - LaterUseKind::Other => "used here", - }; // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) { if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) { - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, message), - ); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => { + BorrowUsedLater::TraitCapture { borrow_desc, span: var_or_use_span } + } + LaterUseKind::ClosureCapture => BorrowUsedLater::ClosureCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Call => { + BorrowUsedLater::Call { borrow_desc, span: var_or_use_span } + } + LaterUseKind::FakeLetRead => { + BorrowUsedLater::FakeLetRead { borrow_desc, span: var_or_use_span } + } + LaterUseKind::Other => { + BorrowUsedLater::Other { borrow_desc, span: var_or_use_span } + } + }; + err.subdiagnostic(sub_err); } } else { // path_span must be `Some` as otherwise the if condition is true @@ -88,13 +97,27 @@ impl<'tcx> BorrowExplanation<'tcx> { // path_span is only present in the case of closure capture assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture)); if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) { - let path_label = "used here by closure"; - let capture_kind_label = message; - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, capture_kind_label), - ); - err.span_label(path_span, path_label); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => { + BorrowUsedLater::TraitCapture { borrow_desc, span: var_or_use_span } + } + LaterUseKind::ClosureCapture => BorrowUsedLater::ClosureCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Call => { + BorrowUsedLater::Call { borrow_desc, span: var_or_use_span } + } + LaterUseKind::FakeLetRead => { + BorrowUsedLater::FakeLetRead { borrow_desc, span: var_or_use_span } + } + LaterUseKind::Other => { + BorrowUsedLater::Other { borrow_desc, span: var_or_use_span } + } + }; + err.subdiagnostic(sub_err); + let sub_label = BorrowUsedHere::ByClosure { path_span }; + err.subdiagnostic(sub_label); } } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 5d750c6ca8c7..c322289d7bc6 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -157,3 +157,52 @@ pub(crate) enum RequireStaticErr { multi_span: MultiSpan, }, } + +//explain_borrow.rs + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowUsedHere { + #[label(borrowck::used_here_by_closure)] + ByClosure { + #[primary_span] + path_span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowUsedLater<'a> { + #[label(borrowck::borrow_later_captured_by_trait_object)] + TraitCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + + #[label(borrowck::borrow_later_captured_by_closure)] + ClosureCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + + #[label(borrowck::borrow_later_used_by_call)] + Call { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + + #[label(borrowck::borrow_later_stored_here)] + FakeLetRead { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + + #[label(borrowck::borrow_later_used_here)] + Other { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 67f2156f32e5..0505e3cbaa37 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -58,3 +58,60 @@ borrowck_returned_lifetime_short = borrowck_used_impl_require_static = the used `impl` has a `'static` requirement + +borrowck_borrow_later_captured_by_trait_object = + {$borrow_desc}borrow later captured here by trait object + +borrowck_borrow_later_captured_by_closure = + {$borrow_desc}borrow later captured here by closure + +borrowck_borrow_later_used_by_call = + {$borrow_desc}borrow later used by call + +borrowck_borrow_later_stored_here = + {$borrow_desc}borrow later stored here + +borrowck_borrow_later_used_here = + {$borrow_desc}borrow later used here + +borrowck_used_here_by_closure = + used here by closure + +borrowck_trait_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow captured here by trait object, in later iteration of loop + +borrowck_closure_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow captured here by closure, in later iteration of loop + +borrowck_call_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow used by call, in later iteration of loop + +borrowck_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow used here, in later iteration of loop + +borrowck_drop_local_might_cause_borrow = + {$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_name} for {$type_name} + +borrowck_var_dropped_in_wrong_order = + values in a scope are dropped in the opposite order they are defined + +borrowck_temporary_access_to_borrow = + a temporary with access to the {$borrow_desc}borrow is created here ... + +borrowck_drop_temporary_might_cause_borrow = ... and the {$borrow_desc}borrow might be used here, when that temporary is dropped and runs the {$dtor_name} for {$type_name} + +borrowck_consider_add_semicolon = + consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped + +borrowck_consider_forcing_temporary_drop_sooner = + the temporary is part of an expression at the end of a block; + consider forcing this temporary to be dropped sooner, before the block's local variables are dropped + +borrowck_perhaps_save_in_new_local_to_drop = + for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block + +borrowck_outlive_constraint_need_borrow_for = + {$category}requires that `{$desc}` is borrowed for `{$region_name}` + +borrowck_outlive_constraint_need_borrow_lasts = + {$category}requires that `{$borrow_desc}` lasts for `{$region_name}` From 19269fef0a7ec464d09a7ff970697d166c2a5dcf Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Thu, 1 Sep 2022 12:51:02 +0800 Subject: [PATCH 3/6] BLBLinloop --- .../src/diagnostics/explain_borrow.rs | 76 ++++++++++++++----- .../rustc_borrowck/src/session_diagnostics.rs | 71 ++++++++++++++++- .../locales/en-US/borrowck.ftl | 21 ++++- 3 files changed, 141 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index b165297ad30f..f4f12cf9fadb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -16,7 +16,9 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, DesugaringKind, Span}; use crate::region_infer::BlameConstraint; -use crate::session_diagnostics::{BorrowUsedHere, BorrowUsedLater}; +use crate::session_diagnostics::{ + BorrowLaterBorrowUsedLaterInLoop, BorrowUsedHere, BorrowUsedLater, BorrowUsedLaterInLoop, +}; use crate::{ borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, WriteKind, @@ -122,33 +124,67 @@ impl<'tcx> BorrowExplanation<'tcx> { } } BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span) => { - let message = match later_use_kind { - LaterUseKind::TraitCapture => { - "borrow captured here by trait object, in later iteration of loop" - } - LaterUseKind::ClosureCapture => { - "borrow captured here by closure, in later iteration of loop" - } - LaterUseKind::Call => "borrow used by call, in later iteration of loop", - LaterUseKind::FakeLetRead => "borrow later stored here", - LaterUseKind::Other => "borrow used here, in later iteration of loop", - }; // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) { - err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message)); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => BorrowUsedLaterInLoop::TraitCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::ClosureCapture => BorrowUsedLaterInLoop::ClosureCapture { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Call => { + BorrowUsedLaterInLoop::Call { borrow_desc, span: var_or_use_span } + } + LaterUseKind::FakeLetRead => BorrowUsedLaterInLoop::FakeLetRead { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::Other => { + BorrowUsedLaterInLoop::Other { borrow_desc, span: var_or_use_span } + } + }; + err.subdiagnostic(sub_err); + // err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message)); } else { // path_span must be `Some` as otherwise the if condition is true let path_span = path_span.unwrap(); // path_span is only present in the case of closure capture assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture)); if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) { - let path_label = "used here by closure"; - let capture_kind_label = message; - err.span_label( - var_or_use_span, - format!("{}borrow later {}", borrow_desc, capture_kind_label), - ); - err.span_label(path_span, path_label); + let sub_err = match later_use_kind { + LaterUseKind::TraitCapture => { + BorrowLaterBorrowUsedLaterInLoop::TraitCapture { + borrow_desc, + span: var_or_use_span, + } + } + LaterUseKind::ClosureCapture => { + BorrowLaterBorrowUsedLaterInLoop::ClosureCapture { + borrow_desc, + span: var_or_use_span, + } + } + LaterUseKind::Call => BorrowLaterBorrowUsedLaterInLoop::Call { + borrow_desc, + span: var_or_use_span, + }, + LaterUseKind::FakeLetRead => { + BorrowLaterBorrowUsedLaterInLoop::FakeLetRead { + borrow_desc, + span: var_or_use_span, + } + } + LaterUseKind::Other => BorrowLaterBorrowUsedLaterInLoop::Other { + borrow_desc, + span: var_or_use_span, + }, + }; + err.subdiagnostic(sub_err); + let sub_label = BorrowUsedHere::ByClosure { path_span }; + err.subdiagnostic(sub_label); } } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index c322289d7bc6..3f6c4401bc22 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -177,28 +177,24 @@ pub(crate) enum BorrowUsedLater<'a> { #[primary_span] span: Span, }, - #[label(borrowck::borrow_later_captured_by_closure)] ClosureCapture { borrow_desc: &'a str, #[primary_span] span: Span, }, - #[label(borrowck::borrow_later_used_by_call)] Call { borrow_desc: &'a str, #[primary_span] span: Span, }, - #[label(borrowck::borrow_later_stored_here)] FakeLetRead { borrow_desc: &'a str, #[primary_span] span: Span, }, - #[label(borrowck::borrow_later_used_here)] Other { borrow_desc: &'a str, @@ -206,3 +202,70 @@ pub(crate) enum BorrowUsedLater<'a> { span: Span, }, } + +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowUsedLaterInLoop<'a> { + #[label(borrowck::trait_capture_borrow_in_later_iteration_loop)] + TraitCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::closure_capture_borrow_in_later_iteration_loop)] + ClosureCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::call_used_borrow_in_later_iteration_loop)] + Call { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::borrow_later_stored_here)] + FakeLetRead { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::used_borrow_in_later_iteration_loop)] + Other { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, +} +#[derive(SessionSubdiagnostic)] +pub(crate) enum BorrowLaterBorrowUsedLaterInLoop<'a> { + #[label(borrowck::bl_trait_capture_borrow_in_later_iteration_loop)] + TraitCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::bl_closure_capture_borrow_in_later_iteration_loop)] + ClosureCapture { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::call_used_borrow_in_later_iteration_loop)] + Call { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::bl_borrow_later_stored_here)] + FakeLetRead { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::bl_used_borrow_in_later_iteration_loop)] + Other { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 0505e3cbaa37..e3d0d68115fb 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -78,15 +78,30 @@ borrowck_used_here_by_closure = used here by closure borrowck_trait_capture_borrow_in_later_iteration_loop = - {$borrow_desc}borrow later borrow captured here by trait object, in later iteration of loop + {$borrow_desc}borrow captured here by trait object, in later iteration of loop borrowck_closure_capture_borrow_in_later_iteration_loop = - {$borrow_desc}borrow later borrow captured here by closure, in later iteration of loop + {$borrow_desc}borrow captured here by closure, in later iteration of loop borrowck_call_used_borrow_in_later_iteration_loop = - {$borrow_desc}borrow later borrow used by call, in later iteration of loop + {$borrow_desc}borrow used by call, in later iteration of loop borrowck_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow used here, in later iteration of loop + +borrowck_bl_trait_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow captured here by trait object, in later iteration of loop + +borrowck_bl_closure_capture_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow captured here by closure, in later iteration of loop + +borrowck_bl_call_used_borrow_in_later_iteration_loop = + {$borrow_desc}borrow later borrow used by call, in later iteration of loop + +borrowck_bl_borrow_later_stored_here = + {$borrow_desc}borrow later borrow later stored here + +borrowck_bl_used_borrow_in_later_iteration_loop = {$borrow_desc}borrow later borrow used here, in later iteration of loop borrowck_drop_local_might_cause_borrow = From c480d9a18ef4250a8cfd3604ddeece75c8c7a37c Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Thu, 1 Sep 2022 14:28:13 +0800 Subject: [PATCH 4/6] explain_borrow need help --- .../src/diagnostics/explain_borrow.rs | 91 ++++++++----------- .../rustc_borrowck/src/session_diagnostics.rs | 53 +++++++++++ .../locales/en-US/borrowck.ftl | 6 +- 3 files changed, 96 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index f4f12cf9fadb..1ade0eb2e04c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + //! Print diagnostics to explain why values are borrowed. use std::collections::VecDeque; @@ -18,6 +21,7 @@ use rustc_span::{sym, DesugaringKind, Span}; use crate::region_infer::BlameConstraint; use crate::session_diagnostics::{ BorrowLaterBorrowUsedLaterInLoop, BorrowUsedHere, BorrowUsedLater, BorrowUsedLaterInLoop, + MustValidFor, UsedLaterDropped, }; use crate::{ borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, @@ -220,41 +224,33 @@ impl<'tcx> BorrowExplanation<'tcx> { match local_names[dropped_local] { Some(local_name) if !local_decl.from_compiler_desugaring() => { - let message = format!( - "{B}borrow might be used here, when `{LOC}` is dropped \ - and runs the {DTOR} for {TYPE}", - B = borrow_desc, - LOC = local_name, - TYPE = type_desc, - DTOR = dtor_desc - ); - err.span_label(body.source_info(drop_loc).span, message); + let sub_label = UsedLaterDropped::UsedHere { + borrow_desc, + local_name: &local_name.to_ident_string(), + type_desc: &type_desc, + dtor_desc, + span: body.source_info(drop_loc).span, + }; + err.subdiagnostic(sub_label); if should_note_order { - err.note( - "values in a scope are dropped \ - in the opposite order they are defined", - ); + let sub_note = UsedLaterDropped::OppositeOrder {}; + err.subdiagnostic(sub_note); } } _ => { - err.span_label( - local_decl.source_info.span, - format!( - "a temporary with access to the {B}borrow \ - is created here ...", - B = borrow_desc - ), - ); - let message = format!( - "... and the {B}borrow might be used here, \ - when that temporary is dropped \ - and runs the {DTOR} for {TYPE}", - B = borrow_desc, - TYPE = type_desc, - DTOR = dtor_desc - ); - err.span_label(body.source_info(drop_loc).span, message); + let sub_label = UsedLaterDropped::TemporaryCreatedHere { + borrow_desc, + span: local_decl.source_info.span, + }; + err.subdiagnostic(sub_label); + let sub_label_2 = UsedLaterDropped::MightUsedHere { + borrow_desc, + type_desc: &type_desc, + dtor_desc, + span: body.source_info(drop_loc).span, + }; + err.subdiagnostic(sub_label_2); if let Some(info) = &local_decl.is_block_tail { if info.tail_result_is_ignored { @@ -266,21 +262,16 @@ impl<'tcx> BorrowExplanation<'tcx> { }) .unwrap_or(false) { - err.span_suggestion_verbose( - info.span.shrink_to_hi(), - "consider adding semicolon after the expression so its \ - temporaries are dropped sooner, before the local variables \ - declared by the block are dropped", - ";", - Applicability::MaybeIncorrect, - ); + let sub_suggest = UsedLaterDropped::AddSemicolon { + span: info.span.shrink_to_hi(), + }; + err.subdiagnostic(sub_suggest); } } else { - err.note( - "the temporary is part of an expression at the end of a \ - block;\nconsider forcing this temporary to be dropped sooner, \ - before the block's local variables are dropped", - ); + let sub_note = UsedLaterDropped::ManualDrop {}; + err.subdiagnostic(sub_note); + + //FIXME: waiting for multipart suggestion derive err.multipart_suggestion( "for example, you could save the expression's value in a new \ local variable `x` and then make `x` be the expression at the \ @@ -306,15 +297,13 @@ impl<'tcx> BorrowExplanation<'tcx> { region_name.highlight_region_name(err); if let Some(desc) = opt_place_desc { - err.span_label( + let sub_label = MustValidFor::Borrowed { + category: category.description(), + desc, + region_name, span, - format!( - "{}requires that `{}` is borrowed for `{}`", - category.description(), - desc, - region_name, - ), - ); + }; + err.subdiagnostic(sub_label); } else { err.span_label( span, diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 3f6c4401bc22..d826a5dfff99 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -269,3 +269,56 @@ pub(crate) enum BorrowLaterBorrowUsedLaterInLoop<'a> { span: Span, }, } + +#[derive(SessionSubdiagnostic)] +pub(crate) enum UsedLaterDropped<'a> { + #[label(borrowck::drop_local_might_cause_borrow)] + UsedHere { + borrow_desc: &'a str, + local_name: &'a str, + type_desc: &'a str, + dtor_desc: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck::var_dropped_in_wrong_order)] + OppositeOrder {}, + #[label(borrowck::temporary_access_to_borrow)] + TemporaryCreatedHere { + borrow_desc: &'a str, + #[primary_span] + span: Span, + }, + #[label(borrowck::drop_temporary_might_cause_borrow_use)] + MightUsedHere { + borrow_desc: &'a str, + type_desc: &'a str, + dtor_desc: &'a str, + #[primary_span] + span: Span, + }, + #[suggestion_verbose( + borrowck::consider_add_semicolon, + applicability = "maybe-incorrect", + code = ";" + )] + AddSemicolon { + #[primary_span] + span: Span, + }, + + #[note(borrowck::consider_forcing_temporary_drop_sooner)] + ManualDrop {}, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum MustValidFor<'a> { + #[label(borrowck::outlive_constraint_need_borrow_for)] + Borrowed { + category: &'a str, + desc: &'a str, + region_name: &'a RegionName, + #[primary_span] + span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index e3d0d68115fb..c57bd0f3e3c9 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -105,7 +105,7 @@ borrowck_bl_used_borrow_in_later_iteration_loop = {$borrow_desc}borrow later borrow used here, in later iteration of loop borrowck_drop_local_might_cause_borrow = - {$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_name} for {$type_name} + {$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_desc} for {$type_desc} borrowck_var_dropped_in_wrong_order = values in a scope are dropped in the opposite order they are defined @@ -113,7 +113,7 @@ borrowck_var_dropped_in_wrong_order = borrowck_temporary_access_to_borrow = a temporary with access to the {$borrow_desc}borrow is created here ... -borrowck_drop_temporary_might_cause_borrow = ... and the {$borrow_desc}borrow might be used here, when that temporary is dropped and runs the {$dtor_name} for {$type_name} +borrowck_drop_temporary_might_cause_borrow_use = ... and the {$borrow_desc}borrow might be used here, when that temporary is dropped and runs the {$dtor_desc} for {$type_desc} borrowck_consider_add_semicolon = consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped @@ -128,5 +128,5 @@ borrowck_perhaps_save_in_new_local_to_drop = borrowck_outlive_constraint_need_borrow_for = {$category}requires that `{$desc}` is borrowed for `{$region_name}` -borrowck_outlive_constraint_need_borrow_lasts = +borrowck_outlive_constraint_need_borrow_lasts_for = {$category}requires that `{$borrow_desc}` lasts for `{$region_name}` From 71d17621cf65dbba0c9b3497fa7317e8558c54eb Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:25:58 +0800 Subject: [PATCH 5/6] How to call this bug? --- .../src/diagnostics/explain_borrow.rs | 15 +++++++-------- .../rustc_borrowck/src/session_diagnostics.rs | 9 +++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 1ade0eb2e04c..40a1ebd3f77f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -305,15 +305,14 @@ impl<'tcx> BorrowExplanation<'tcx> { }; err.subdiagnostic(sub_label); } else { - err.span_label( + //FIXME: src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.rs + let sub_label = MustValidFor::Lasts { + category: category.description(), + borrow_desc, + region_name, span, - format!( - "{}requires that {}borrow lasts for `{}`", - category.description(), - borrow_desc, - region_name, - ), - ); + }; + err.subdiagnostic(sub_label); }; self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index d826a5dfff99..8131e40b721d 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -321,4 +321,13 @@ pub(crate) enum MustValidFor<'a> { #[primary_span] span: Span, }, + + #[label(borrowck::outlive_constraint_need_borrow_lasts_for)] + Lasts { + category: &'a str, + borrow_desc: &'a str, + region_name: &'a RegionName, + #[primary_span] + span: Span, + }, } From 2cab61d2e6b2949145eec73ac8fec3a3215d0966 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Thu, 1 Sep 2022 17:06:23 +0800 Subject: [PATCH 6/6] MutatingUpvar --- .../src/diagnostics/mutability_errors.rs | 15 +++++++-------- .../rustc_borrowck/src/session_diagnostics.rs | 14 +++++++++----- .../locales/en-US/borrowck.ftl | 3 +++ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index dd9590016b99..a9f6a4df9209 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{ Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, }; @@ -19,6 +22,7 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, BytePos, Span}; use crate::diagnostics::BorrowedContentSource; +use crate::session_diagnostics::ShowMutatingUpvar; use crate::MirBorrowckCtxt; use rustc_const_eval::util::collect_writes::FindAssignments; @@ -864,14 +868,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { bug!("not an upvar") }; - err.span_label( - *span, - format!( - "calling `{}` requires mutable binding due to {}", - self.describe_place(the_place_err).unwrap(), - reason - ), - ); + let place = self.describe_place(the_place_err).unwrap(); + let sub_label = ShowMutatingUpvar::RequireMutableBinding { place, reason, span: *span }; + err.subdiagnostic(sub_label); } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 8131e40b721d..ec4b1cffa96f 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -321,12 +321,16 @@ pub(crate) enum MustValidFor<'a> { #[primary_span] span: Span, }, +} - #[label(borrowck::outlive_constraint_need_borrow_lasts_for)] - Lasts { - category: &'a str, - borrow_desc: &'a str, - region_name: &'a RegionName, +//mutability_errors.rs + +#[derive(SessionSubdiagnostic)] +pub(crate) enum ShowMutatingUpvar { + #[label(borrowck::require_mutable_binding)] + RequireMutableBinding { + place: String, + reason: String, #[primary_span] span: Span, }, diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index c57bd0f3e3c9..2ac71d29cc25 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -130,3 +130,6 @@ borrowck_outlive_constraint_need_borrow_for = borrowck_outlive_constraint_need_borrow_lasts_for = {$category}requires that `{$borrow_desc}` lasts for `{$region_name}` + +borrowck_require_mutable_binding = + calling `{$place}` requires mutable binding due to {$reason}