Skip to content

Commit 2edb549

Browse files
committed
UseLaterDroped & VarMust
1 parent 3348c6c commit 2edb549

File tree

3 files changed

+95
-53
lines changed

3 files changed

+95
-53
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
@@ -285,3 +285,56 @@ pub(crate) enum BorrowLaterBorrowUsedLaterInLoop<'a> {
285285
span: Span,
286286
},
287287
}
288+
289+
#[derive(SessionSubdiagnostic)]
290+
pub(crate) enum UsedLaterDropped<'a> {
291+
#[label(borrowck::drop_local_might_cause_borrow)]
292+
UsedHere {
293+
borrow_desc: &'a str,
294+
local_name: &'a str,
295+
type_desc: &'a str,
296+
dtor_desc: &'a str,
297+
#[primary_span]
298+
span: Span,
299+
},
300+
#[note(borrowck::var_dropped_in_wrong_order)]
301+
OppositeOrder {},
302+
#[label(borrowck::temporary_access_to_borrow)]
303+
TemporaryCreatedHere {
304+
borrow_desc: &'a str,
305+
#[primary_span]
306+
span: Span,
307+
},
308+
#[label(borrowck::drop_temporary_might_cause_borrow_use)]
309+
MightUsedHere {
310+
borrow_desc: &'a str,
311+
type_desc: &'a str,
312+
dtor_desc: &'a str,
313+
#[primary_span]
314+
span: Span,
315+
},
316+
#[suggestion_verbose(
317+
borrowck::consider_add_semicolon,
318+
applicability = "maybe-incorrect",
319+
code = ";"
320+
)]
321+
AddSemicolon {
322+
#[primary_span]
323+
span: Span,
324+
},
325+
326+
#[note(borrowck::consider_forcing_temporary_drop_sooner)]
327+
ManualDrop {},
328+
}
329+
330+
#[derive(SessionSubdiagnostic)]
331+
pub(crate) enum MustValidFor<'a> {
332+
#[label(borrowck::outlive_constraint_need_borrow_for)]
333+
Borrowed {
334+
category: &'a str,
335+
desc: &'a str,
336+
region_name: &'a RegionName,
337+
#[primary_span]
338+
span: Span,
339+
},
340+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ borrowck_bl_used_borrow_in_later_iteration_loop =
113113
{$borrow_desc}borrow later borrow used here, in later iteration of loop
114114
115115
borrowck_drop_local_might_cause_borrow =
116-
{$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_name} for {$type_name}
116+
{$borrow_desc}borrow might be used here, when `{$local_name}` is dropped and runs the {$dtor_desc} for {$type_desc}
117117
118118
borrowck_var_dropped_in_wrong_order =
119119
values in a scope are dropped in the opposite order they are defined
120120
121121
borrowck_temporary_access_to_borrow =
122122
a temporary with access to the {$borrow_desc}borrow is created here ...
123123
124-
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}
124+
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}
125125
126126
borrowck_consider_add_semicolon =
127127
consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped

0 commit comments

Comments
 (0)