Skip to content

Commit 920fe63

Browse files
committed
Auto merge of #142882 - kornelski:var-debug-info-lazy, r=<try>
Lazy init diagnostics-only local_names in borrowck `local_names` is not used during successful compilation, so not initializing it saves a little bit of work. I've also made it accessible only from the diagnostics module to make it clearer that the names are from `var_debug_info` which is technically optional and could be absent.
2 parents ae2fc97 + d18a43c commit 920fe63

File tree

7 files changed

+63
-45
lines changed

7 files changed

+63
-45
lines changed

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ impl<'tcx> BorrowExplanation<'tcx> {
7171
) {
7272
let tcx = cx.infcx.tcx;
7373
let body = cx.body;
74-
let local_names = &cx.local_names;
7574

7675
if let Some(span) = borrow_span {
7776
let def_id = body.source.def_id();
@@ -220,7 +219,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
220219
_ => ("destructor", format!("type `{}`", local_decl.ty)),
221220
};
222221

223-
match local_names[dropped_local] {
222+
match cx.local_name(dropped_local) {
224223
Some(local_name) if !local_decl.from_compiler_desugaring() => {
225224
let message = format!(
226225
"{borrow_desc}borrow might be used here, when `{local_name}` is dropped \
@@ -670,10 +669,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
670669

671670
Some(Cause::DropVar(local, location)) => {
672671
let mut should_note_order = false;
673-
if self.local_names[local].is_some()
672+
if self.local_name(local).is_some()
674673
&& let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place
675674
&& let Some(borrowed_local) = place.as_local()
676-
&& self.local_names[borrowed_local].is_some()
675+
&& self.local_name(borrowed_local).is_some()
677676
&& local != borrowed_local
678677
{
679678
should_note_order = true;
@@ -748,7 +747,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
748747
Operand::Copy(place) | Operand::Move(place) => {
749748
if let Some(l) = place.as_local() {
750749
let local_decl = &self.body.local_decls[l];
751-
if self.local_names[l].is_none() {
750+
if self.local_name(l).is_none() {
752751
local_decl.source_info.span
753752
} else {
754753
span
@@ -793,7 +792,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
793792
Operand::Copy(place) | Operand::Move(place) => {
794793
if let Some(l) = place.as_local() {
795794
let local_decl = &self.body.local_decls[l];
796-
if self.local_names[l].is_none() {
795+
if self.local_name(l).is_none() {
797796
local_decl.source_info.span
798797
} else {
799798
span

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ use rustc_data_structures::fx::FxIndexMap;
77
use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify};
88
use rustc_hir::def::{CtorKind, Namespace};
99
use rustc_hir::{self as hir, CoroutineKind, LangItem};
10-
use rustc_index::IndexSlice;
10+
use rustc_index::{IndexSlice, IndexVec};
1111
use rustc_infer::infer::{BoundRegionConversionTime, NllRegionVariableOrigin};
1212
use rustc_infer::traits::SelectionError;
13-
use rustc_middle::bug;
1413
use rustc_middle::mir::{
1514
AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo,
1615
LocalKind, Location, Operand, Place, PlaceRef, PlaceTy, ProjectionElem, Rvalue, Statement,
17-
StatementKind, Terminator, TerminatorKind, find_self_call,
16+
StatementKind, Terminator, TerminatorKind, VarDebugInfoContents, find_self_call,
1817
};
1918
use rustc_middle::ty::print::Print;
2019
use rustc_middle::ty::{self, Ty, TyCtxt};
20+
use rustc_middle::{bug, span_bug};
2121
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex};
2222
use rustc_span::def_id::LocalDefId;
2323
use rustc_span::source_map::Spanned;
@@ -190,6 +190,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
190190
) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
191191
self.diags_buffer.buffered_move_errors.get(move_out_indices)
192192
}
193+
194+
/// Uses `body.var_debug_info` to find the symbol
195+
fn local_name(&self, index: Local) -> Option<Symbol> {
196+
*self.local_names().get(index)?
197+
}
198+
199+
fn local_names(&self) -> &IndexSlice<Local, Option<Symbol>> {
200+
self.local_names.get_or_init(|| {
201+
let mut local_names = IndexVec::from_elem(None, &self.body.local_decls);
202+
for var_debug_info in &self.body.var_debug_info {
203+
if let VarDebugInfoContents::Place(place) = var_debug_info.value {
204+
if let Some(local) = place.as_local() {
205+
if let Some(prev_name) = local_names[local]
206+
&& var_debug_info.name != prev_name
207+
{
208+
span_bug!(
209+
var_debug_info.source_info.span,
210+
"local {:?} has many names (`{}` vs `{}`)",
211+
local,
212+
prev_name,
213+
var_debug_info.name
214+
);
215+
}
216+
local_names[local] = Some(var_debug_info.name);
217+
}
218+
}
219+
}
220+
local_names
221+
})
222+
}
193223
}
194224

195225
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
@@ -430,7 +460,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
430460
/// a name, or its name was generated by the compiler, then `Err` is returned
431461
fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), ()> {
432462
let decl = &self.body.local_decls[local];
433-
match self.local_names[local] {
463+
match self.local_name(local) {
434464
Some(name) if !decl.from_compiler_desugaring() => {
435465
buf.push_str(name.as_str());
436466
Ok(())
@@ -1500,4 +1530,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
15001530
}
15011531
}
15021532
}
1533+
1534+
/// Skip over locals that begin with an underscore or have no name
1535+
pub(crate) fn local_excluded_from_unused_mut_lint(&self, index: Local) -> bool {
1536+
self.local_name(index).is_none_or(|name| name.as_str().starts_with('_'))
1537+
}
15031538
}

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
465465

466466
if let PlaceRef { local, projection: [] } = deref_base {
467467
let decl = &self.body.local_decls[local];
468+
let local_name = self.local_name(local).map(|sym| format!("`{sym}`"));
468469
if decl.is_ref_for_guard() {
469470
return self
470471
.cannot_move_out_of(
471472
span,
472-
&format!("`{}` in pattern guard", self.local_names[local].unwrap()),
473+
&format!(
474+
"{} in pattern guard",
475+
local_name.as_deref().unwrap_or("the place")
476+
),
473477
)
474478
.with_note(
475479
"variables bound in patterns cannot be moved from \
@@ -825,7 +829,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
825829
}
826830

827831
if binds_to.len() == 1 {
828-
let place_desc = &format!("`{}`", self.local_names[*local].unwrap());
832+
let place_desc = self.local_name(*local).map(|sym| format!("`{sym}`"));
829833

830834
if let Some(expr) = self.find_expr(binding_span) {
831835
self.suggest_cloning(err, bind_to.ty, expr, None);
@@ -834,7 +838,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
834838
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
835839
is_partial_move: false,
836840
ty: bind_to.ty,
837-
place: place_desc,
841+
place: place_desc.as_deref().unwrap_or("the place"),
838842
span: binding_span,
839843
});
840844
}

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
6060
if access_place.as_local().is_some() {
6161
reason = ", as it is not declared as mutable".to_string();
6262
} else {
63-
let name = self.local_names[local].expect("immutable unnamed local");
63+
let name = self.local_name(local).expect("immutable unnamed local");
6464
reason = format!(", as `{name}` is not declared as mutable");
6565
}
6666
}
@@ -285,7 +285,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
285285
.body
286286
.local_decls
287287
.get(local)
288-
.is_some_and(|l| mut_borrow_of_mutable_ref(l, self.local_names[local])) =>
288+
.is_some_and(|l| mut_borrow_of_mutable_ref(l, self.local_name(local))) =>
289289
{
290290
let decl = &self.body.local_decls[local];
291291
err.span_label(span, format!("cannot {act}"));
@@ -481,7 +481,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
481481
let (pointer_sigil, pointer_desc) =
482482
if local_decl.ty.is_ref() { ("&", "reference") } else { ("*const", "pointer") };
483483

484-
match self.local_names[local] {
484+
match self.local_name(local) {
485485
Some(name) if !local_decl.from_compiler_desugaring() => {
486486
err.span_label(
487487
span,

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,14 +664,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
664664
let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
665665
self.infcx.tcx,
666666
self.body,
667-
&self.local_names,
667+
&self.local_names(),
668668
&self.upvars,
669669
errci.fr,
670670
);
671671
let outlived_fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
672672
self.infcx.tcx,
673673
self.body,
674-
&self.local_names,
674+
&self.local_names(),
675675
&self.upvars,
676676
errci.outlived_fr,
677677
);

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
399399
[implicit_inputs + argument_index];
400400
let (_, span) = self.regioncx.get_argument_name_and_span_for_region(
401401
self.body,
402-
&self.local_names,
402+
self.local_names(),
403403
argument_index,
404404
);
405405

@@ -973,7 +973,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
973973
{
974974
let (arg_name, arg_span) = self.regioncx.get_argument_name_and_span_for_region(
975975
self.body,
976-
&self.local_names,
976+
self.local_names(),
977977
arg_index,
978978
);
979979
let region_name = self.synthesize_region_name();

compiler/rustc_borrowck/src/lib.rs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// tidy-alphabetical-end
1717

1818
use std::borrow::Cow;
19-
use std::cell::RefCell;
19+
use std::cell::{OnceCell, RefCell};
2020
use std::marker::PhantomData;
2121
use std::ops::{ControlFlow, Deref};
2222

@@ -391,7 +391,7 @@ fn do_mir_borrowck<'tcx>(
391391
used_mut_upvars: SmallVec::new(),
392392
borrow_set: &borrow_set,
393393
upvars: &[],
394-
local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
394+
local_names: OnceCell::from(IndexVec::from_elem(None, &promoted_body.local_decls)),
395395
region_names: RefCell::default(),
396396
next_region_name: RefCell::new(1),
397397
polonius_output: None,
@@ -414,26 +414,6 @@ fn do_mir_borrowck<'tcx>(
414414
promoted_mbcx.report_move_errors();
415415
}
416416

417-
let mut local_names = IndexVec::from_elem(None, &body.local_decls);
418-
for var_debug_info in &body.var_debug_info {
419-
if let VarDebugInfoContents::Place(place) = var_debug_info.value {
420-
if let Some(local) = place.as_local() {
421-
if let Some(prev_name) = local_names[local]
422-
&& var_debug_info.name != prev_name
423-
{
424-
span_bug!(
425-
var_debug_info.source_info.span,
426-
"local {:?} has many names (`{}` vs `{}`)",
427-
local,
428-
prev_name,
429-
var_debug_info.name
430-
);
431-
}
432-
local_names[local] = Some(var_debug_info.name);
433-
}
434-
}
435-
}
436-
437417
let mut mbcx = MirBorrowckCtxt {
438418
root_cx,
439419
infcx: &infcx,
@@ -450,7 +430,7 @@ fn do_mir_borrowck<'tcx>(
450430
used_mut_upvars: SmallVec::new(),
451431
borrow_set: &borrow_set,
452432
upvars: tcx.closure_captures(def),
453-
local_names,
433+
local_names: OnceCell::new(),
454434
region_names: RefCell::default(),
455435
next_region_name: RefCell::new(1),
456436
move_errors: Vec::new(),
@@ -682,7 +662,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
682662
upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
683663

684664
/// Names of local (user) variables (extracted from `var_debug_info`).
685-
local_names: IndexVec<Local, Option<Symbol>>,
665+
local_names: OnceCell<IndexVec<Local, Option<Symbol>>>,
686666

687667
/// Record the region names generated for each region in the given
688668
/// MIR def so that we can reuse them later in help/error messages.
@@ -2610,7 +2590,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
26102590
};
26112591

26122592
// Skip over locals that begin with an underscore or have no name
2613-
if self.local_names[local].is_none_or(|name| name.as_str().starts_with('_')) {
2593+
if self.local_excluded_from_unused_mut_lint(local) {
26142594
continue;
26152595
}
26162596

0 commit comments

Comments
 (0)