Skip to content

Commit c480d9a

Browse files
committed
explain_borrow need help
1 parent 19269fe commit c480d9a

File tree

3 files changed

+96
-54
lines changed

3 files changed

+96
-54
lines changed

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// #![deny(rustc::untranslatable_diagnostic)]
2+
// #![deny(rustc::diagnostic_outside_of_impl)]
3+
14
//! Print diagnostics to explain why values are borrowed.
25
36
use std::collections::VecDeque;
@@ -18,6 +21,7 @@ use rustc_span::{sym, DesugaringKind, Span};
1821
use crate::region_infer::BlameConstraint;
1922
use crate::session_diagnostics::{
2023
BorrowLaterBorrowUsedLaterInLoop, BorrowUsedHere, BorrowUsedLater, BorrowUsedLaterInLoop,
24+
MustValidFor, UsedLaterDropped,
2125
};
2226
use crate::{
2327
borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt,
@@ -220,41 +224,33 @@ impl<'tcx> BorrowExplanation<'tcx> {
220224

221225
match local_names[dropped_local] {
222226
Some(local_name) if !local_decl.from_compiler_desugaring() => {
223-
let message = format!(
224-
"{B}borrow might be used here, when `{LOC}` is dropped \
225-
and runs the {DTOR} for {TYPE}",
226-
B = borrow_desc,
227-
LOC = local_name,
228-
TYPE = type_desc,
229-
DTOR = dtor_desc
230-
);
231-
err.span_label(body.source_info(drop_loc).span, message);
227+
let sub_label = UsedLaterDropped::UsedHere {
228+
borrow_desc,
229+
local_name: &local_name.to_ident_string(),
230+
type_desc: &type_desc,
231+
dtor_desc,
232+
span: body.source_info(drop_loc).span,
233+
};
234+
err.subdiagnostic(sub_label);
232235

233236
if should_note_order {
234-
err.note(
235-
"values in a scope are dropped \
236-
in the opposite order they are defined",
237-
);
237+
let sub_note = UsedLaterDropped::OppositeOrder {};
238+
err.subdiagnostic(sub_note);
238239
}
239240
}
240241
_ => {
241-
err.span_label(
242-
local_decl.source_info.span,
243-
format!(
244-
"a temporary with access to the {B}borrow \
245-
is created here ...",
246-
B = borrow_desc
247-
),
248-
);
249-
let message = format!(
250-
"... and the {B}borrow might be used here, \
251-
when that temporary is dropped \
252-
and runs the {DTOR} for {TYPE}",
253-
B = borrow_desc,
254-
TYPE = type_desc,
255-
DTOR = dtor_desc
256-
);
257-
err.span_label(body.source_info(drop_loc).span, message);
242+
let sub_label = UsedLaterDropped::TemporaryCreatedHere {
243+
borrow_desc,
244+
span: local_decl.source_info.span,
245+
};
246+
err.subdiagnostic(sub_label);
247+
let sub_label_2 = UsedLaterDropped::MightUsedHere {
248+
borrow_desc,
249+
type_desc: &type_desc,
250+
dtor_desc,
251+
span: body.source_info(drop_loc).span,
252+
};
253+
err.subdiagnostic(sub_label_2);
258254

259255
if let Some(info) = &local_decl.is_block_tail {
260256
if info.tail_result_is_ignored {
@@ -266,21 +262,16 @@ impl<'tcx> BorrowExplanation<'tcx> {
266262
})
267263
.unwrap_or(false)
268264
{
269-
err.span_suggestion_verbose(
270-
info.span.shrink_to_hi(),
271-
"consider adding semicolon after the expression so its \
272-
temporaries are dropped sooner, before the local variables \
273-
declared by the block are dropped",
274-
";",
275-
Applicability::MaybeIncorrect,
276-
);
265+
let sub_suggest = UsedLaterDropped::AddSemicolon {
266+
span: info.span.shrink_to_hi(),
267+
};
268+
err.subdiagnostic(sub_suggest);
277269
}
278270
} else {
279-
err.note(
280-
"the temporary is part of an expression at the end of a \
281-
block;\nconsider forcing this temporary to be dropped sooner, \
282-
before the block's local variables are dropped",
283-
);
271+
let sub_note = UsedLaterDropped::ManualDrop {};
272+
err.subdiagnostic(sub_note);
273+
274+
//FIXME: waiting for multipart suggestion derive
284275
err.multipart_suggestion(
285276
"for example, you could save the expression's value in a new \
286277
local variable `x` and then make `x` be the expression at the \
@@ -306,15 +297,13 @@ impl<'tcx> BorrowExplanation<'tcx> {
306297
region_name.highlight_region_name(err);
307298

308299
if let Some(desc) = opt_place_desc {
309-
err.span_label(
300+
let sub_label = MustValidFor::Borrowed {
301+
category: category.description(),
302+
desc,
303+
region_name,
310304
span,
311-
format!(
312-
"{}requires that `{}` is borrowed for `{}`",
313-
category.description(),
314-
desc,
315-
region_name,
316-
),
317-
);
305+
};
306+
err.subdiagnostic(sub_label);
318307
} else {
319308
err.span_label(
320309
span,

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,56 @@ pub(crate) enum BorrowLaterBorrowUsedLaterInLoop<'a> {
269269
span: Span,
270270
},
271271
}
272+
273+
#[derive(SessionSubdiagnostic)]
274+
pub(crate) enum UsedLaterDropped<'a> {
275+
#[label(borrowck::drop_local_might_cause_borrow)]
276+
UsedHere {
277+
borrow_desc: &'a str,
278+
local_name: &'a str,
279+
type_desc: &'a str,
280+
dtor_desc: &'a str,
281+
#[primary_span]
282+
span: Span,
283+
},
284+
#[note(borrowck::var_dropped_in_wrong_order)]
285+
OppositeOrder {},
286+
#[label(borrowck::temporary_access_to_borrow)]
287+
TemporaryCreatedHere {
288+
borrow_desc: &'a str,
289+
#[primary_span]
290+
span: Span,
291+
},
292+
#[label(borrowck::drop_temporary_might_cause_borrow_use)]
293+
MightUsedHere {
294+
borrow_desc: &'a str,
295+
type_desc: &'a str,
296+
dtor_desc: &'a str,
297+
#[primary_span]
298+
span: Span,
299+
},
300+
#[suggestion_verbose(
301+
borrowck::consider_add_semicolon,
302+
applicability = "maybe-incorrect",
303+
code = ";"
304+
)]
305+
AddSemicolon {
306+
#[primary_span]
307+
span: Span,
308+
},
309+
310+
#[note(borrowck::consider_forcing_temporary_drop_sooner)]
311+
ManualDrop {},
312+
}
313+
314+
#[derive(SessionSubdiagnostic)]
315+
pub(crate) enum MustValidFor<'a> {
316+
#[label(borrowck::outlive_constraint_need_borrow_for)]
317+
Borrowed {
318+
category: &'a str,
319+
desc: &'a str,
320+
region_name: &'a RegionName,
321+
#[primary_span]
322+
span: Span,
323+
},
324+
}

compiler/rustc_error_messages/locales/en-US/borrowck.ftl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,15 @@ borrowck_bl_used_borrow_in_later_iteration_loop =
105105
{$borrow_desc}borrow later borrow used here, in later iteration of loop
106106
107107
borrowck_drop_local_might_cause_borrow =
108-
{$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_name} for {$type_name}
108+
{$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_desc} for {$type_desc}
109109
110110
borrowck_var_dropped_in_wrong_order =
111111
values in a scope are dropped in the opposite order they are defined
112112
113113
borrowck_temporary_access_to_borrow =
114114
a temporary with access to the {$borrow_desc}borrow is created here ...
115115
116-
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}
116+
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}
117117
118118
borrowck_consider_add_semicolon =
119119
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 =
128128
borrowck_outlive_constraint_need_borrow_for =
129129
{$category}requires that `{$desc}` is borrowed for `{$region_name}`
130130
131-
borrowck_outlive_constraint_need_borrow_lasts =
131+
borrowck_outlive_constraint_need_borrow_lasts_for =
132132
{$category}requires that `{$borrow_desc}` lasts for `{$region_name}`

0 commit comments

Comments
 (0)