Skip to content

Commit d920dd8

Browse files
Remove Upvar duplication
This cuts out an extra allocation and copying over from the already cached closure capture information.
1 parent 3166210 commit d920dd8

File tree

10 files changed

+35
-50
lines changed

10 files changed

+35
-50
lines changed

Diff for: compiler/rustc_borrowck/src/diagnostics/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
217217
projection: place.projection.split_at(index + 1).0,
218218
}) {
219219
let var_index = field.index();
220-
buf = self.upvars[var_index].place.to_string(self.infcx.tcx);
220+
buf = self.upvars[var_index].to_string(self.infcx.tcx);
221221
ok = Ok(());
222-
if !self.upvars[var_index].by_ref {
222+
if !self.upvars[var_index].is_by_ref() {
223223
buf.insert(0, '*');
224224
}
225225
} else {
@@ -250,7 +250,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
250250
local,
251251
projection: place.projection.split_at(index + 1).0,
252252
}) {
253-
buf = self.upvars[field.index()].place.to_string(self.infcx.tcx);
253+
buf = self.upvars[field.index()].to_string(self.infcx.tcx);
254254
ok = Ok(());
255255
} else {
256256
let field_name = self.describe_field(

Diff for: compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
363363
format!("captured variable in an `{closure_kind}` closure");
364364

365365
let upvar = &self.upvars[upvar_field.unwrap().index()];
366-
let upvar_hir_id = upvar.place.get_root_variable();
367-
let upvar_name = upvar.place.to_string(self.infcx.tcx);
366+
let upvar_hir_id = upvar.get_root_variable();
367+
let upvar_name = upvar.to_string(self.infcx.tcx);
368368
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
369369

370370
let place_name = self.describe_any_place(move_place.as_ref());

Diff for: compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
6666
));
6767

6868
let imm_borrow_derefed = self.upvars[upvar_index.index()]
69-
.place
7069
.place
7170
.deref_tys()
7271
.any(|ty| matches!(ty.kind(), ty::Ref(.., hir::Mutability::Not)));
@@ -85,7 +84,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
8584
if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
8685
reason = ", as it is not declared as mutable".to_string();
8786
} else {
88-
let name = self.upvars[upvar_index.index()].place.to_string(self.infcx.tcx);
87+
let name = self.upvars[upvar_index.index()].to_string(self.infcx.tcx);
8988
reason = format!(", as `{name}` is not declared as mutable");
9089
}
9190
}
@@ -388,7 +387,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
388387
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty
389388
));
390389

391-
let captured_place = &self.upvars[upvar_index.index()].place;
390+
let captured_place = self.upvars[upvar_index.index()];
392391

393392
err.span_label(span, format!("cannot {act}"));
394393

Diff for: compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
605605
};
606606

607607
let captured_place = &self.upvars[upvar_field.index()].place;
608-
let defined_hir = match captured_place.place.base {
608+
let defined_hir = match captured_place.base {
609609
PlaceBase::Local(hirid) => Some(hirid),
610610
PlaceBase::Upvar(upvar) => Some(upvar.var_path.hir_id),
611611
_ => None,

Diff for: compiler/rustc_borrowck/src/diagnostics/var_name.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
#![deny(rustc::diagnostic_outside_of_impl)]
33

44
use crate::region_infer::RegionInferenceContext;
5-
use crate::Upvar;
65
use rustc_index::IndexSlice;
76
use rustc_middle::mir::{Body, Local};
8-
use rustc_middle::ty::{RegionVid, TyCtxt};
7+
use rustc_middle::ty::{self, RegionVid, TyCtxt};
98
use rustc_span::symbol::Symbol;
109
use rustc_span::Span;
1110

@@ -15,7 +14,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1514
tcx: TyCtxt<'tcx>,
1615
body: &Body<'tcx>,
1716
local_names: &IndexSlice<Local, Option<Symbol>>,
18-
upvars: &[Upvar<'tcx>],
17+
upvars: &[&ty::CapturedPlace<'tcx>],
1918
fr: RegionVid,
2019
) -> Option<(Option<Symbol>, Span)> {
2120
debug!("get_var_name_and_span_for_region(fr={fr:?})");
@@ -66,10 +65,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
6665
pub(crate) fn get_upvar_name_and_span_for_region(
6766
&self,
6867
tcx: TyCtxt<'tcx>,
69-
upvars: &[Upvar<'tcx>],
68+
upvars: &[&ty::CapturedPlace<'tcx>],
7069
upvar_index: usize,
7170
) -> (Symbol, Span) {
72-
let upvar_hir_id = upvars[upvar_index].place.get_root_variable();
71+
let upvar_hir_id = upvars[upvar_index].get_root_variable();
7372
debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}");
7473

7574
let upvar_name = tcx.hir().name(upvar_hir_id);

Diff for: compiler/rustc_borrowck/src/lib.rs

+9-28
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_middle::mir::tcx::PlaceTy;
3535
use rustc_middle::mir::*;
3636
use rustc_middle::query::Providers;
3737
use rustc_middle::traits::DefiningAnchor;
38-
use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt};
38+
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt};
3939
use rustc_session::lint::builtin::UNUSED_MUT;
4040
use rustc_span::{Span, Symbol};
4141
use rustc_target::abi::FieldIdx;
@@ -100,15 +100,6 @@ use renumber::RegionCtxt;
100100

101101
fluent_messages! { "../messages.ftl" }
102102

103-
// FIXME(eddyb) perhaps move this somewhere more centrally.
104-
#[derive(Debug)]
105-
struct Upvar<'tcx> {
106-
place: CapturedPlace<'tcx>,
107-
108-
/// If true, the capture is behind a reference.
109-
by_ref: bool,
110-
}
111-
112103
/// Associate some local constants with the `'tcx` lifetime
113104
struct TyCtxtConsts<'tcx>(TyCtxt<'tcx>);
114105
impl<'tcx> TyCtxtConsts<'tcx> {
@@ -193,18 +184,6 @@ fn do_mir_borrowck<'tcx>(
193184
infcx.set_tainted_by_errors(e);
194185
errors.set_tainted_by_errors(e);
195186
}
196-
let upvars: Vec<_> = tcx
197-
.closure_captures(def)
198-
.iter()
199-
.map(|&captured_place| {
200-
let capture = captured_place.info.capture_kind;
201-
let by_ref = match capture {
202-
ty::UpvarCapture::ByValue => false,
203-
ty::UpvarCapture::ByRef(..) => true,
204-
};
205-
Upvar { place: captured_place.clone(), by_ref }
206-
})
207-
.collect();
208187

209188
// Replace all regions with fresh inference variables. This
210189
// requires first making our own copy of the MIR. This copy will
@@ -254,7 +233,7 @@ fn do_mir_borrowck<'tcx>(
254233
&mut flow_inits,
255234
&mdpe.move_data,
256235
&borrow_set,
257-
&upvars,
236+
tcx.closure_captures(def),
258237
consumer_options,
259238
);
260239

@@ -324,7 +303,7 @@ fn do_mir_borrowck<'tcx>(
324303
used_mut: Default::default(),
325304
used_mut_upvars: SmallVec::new(),
326305
borrow_set: Rc::clone(&borrow_set),
327-
upvars: Vec::new(),
306+
upvars: &[],
328307
local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
329308
region_names: RefCell::default(),
330309
next_region_name: RefCell::new(1),
@@ -365,7 +344,7 @@ fn do_mir_borrowck<'tcx>(
365344
used_mut: Default::default(),
366345
used_mut_upvars: SmallVec::new(),
367346
borrow_set: Rc::clone(&borrow_set),
368-
upvars,
347+
upvars: tcx.closure_captures(def),
369348
local_names,
370349
region_names: RefCell::default(),
371350
next_region_name: RefCell::new(1),
@@ -584,7 +563,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
584563
borrow_set: Rc<BorrowSet<'tcx>>,
585564

586565
/// Information about upvars not necessarily preserved in types or MIR
587-
upvars: Vec<Upvar<'tcx>>,
566+
upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
588567

589568
/// Names of local (user) variables (extracted from `var_debug_info`).
590569
local_names: IndexVec<Local, Option<Symbol>>,
@@ -2294,7 +2273,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
22942273
// unique path to the `&mut`
22952274
hir::Mutability::Mut => {
22962275
let mode = match self.is_upvar_field_projection(place) {
2297-
Some(field) if self.upvars[field.index()].by_ref => {
2276+
Some(field)
2277+
if self.upvars[field.index()].is_by_ref() =>
2278+
{
22982279
is_local_mutation_allowed
22992280
}
23002281
_ => LocalMutationIsAllowed::Yes,
@@ -2342,7 +2323,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
23422323
place={:?}, place_base={:?}",
23432324
upvar, is_local_mutation_allowed, place, place_base
23442325
);
2345-
match (upvar.place.mutability, is_local_mutation_allowed) {
2326+
match (upvar.mutability, is_local_mutation_allowed) {
23462327
(
23472328
Mutability::Not,
23482329
LocalMutationIsAllowed::No

Diff for: compiler/rustc_borrowck/src/nll.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::{
3737
renumber,
3838
type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
3939
universal_regions::UniversalRegions,
40-
BorrowckInferCtxt, Upvar,
40+
BorrowckInferCtxt,
4141
};
4242

4343
pub type PoloniusOutput = Output<RustcFacts>;
@@ -166,7 +166,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
166166
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
167167
move_data: &MoveData<'tcx>,
168168
borrow_set: &BorrowSet<'tcx>,
169-
upvars: &[Upvar<'tcx>],
169+
upvars: &[&ty::CapturedPlace<'tcx>],
170170
consumer_options: Option<ConsumerOptions>,
171171
) -> NllOutput<'tcx> {
172172
let is_polonius_legacy_enabled = infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled();

Diff for: compiler/rustc_borrowck/src/path_utils.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
44
use crate::places_conflict;
55
use crate::AccessDepth;
66
use crate::BorrowIndex;
7-
use crate::Upvar;
87
use rustc_data_structures::graph::dominators::Dominators;
98
use rustc_middle::mir::BorrowKind;
109
use rustc_middle::mir::{BasicBlock, Body, Location, Place, PlaceRef, ProjectionElem};
@@ -150,7 +149,7 @@ pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool {
150149
/// of a closure type.
151150
pub(crate) fn is_upvar_field_projection<'tcx>(
152151
tcx: TyCtxt<'tcx>,
153-
upvars: &[Upvar<'tcx>],
152+
upvars: &[&rustc_middle::ty::CapturedPlace<'tcx>],
154153
place_ref: PlaceRef<'tcx>,
155154
body: &Body<'tcx>,
156155
) -> Option<FieldIdx> {
@@ -166,7 +165,7 @@ pub(crate) fn is_upvar_field_projection<'tcx>(
166165
Some((place_base, ProjectionElem::Field(field, _ty))) => {
167166
let base_ty = place_base.ty(body, tcx).ty;
168167
if (base_ty.is_closure() || base_ty.is_coroutine())
169-
&& (!by_ref || upvars[field.index()].by_ref)
168+
&& (!by_ref || upvars[field.index()].is_by_ref())
170169
{
171170
Some(field)
172171
} else {

Diff for: compiler/rustc_borrowck/src/type_check/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use crate::{
6868
region_infer::TypeTest,
6969
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
7070
universal_regions::{DefiningTy, UniversalRegions},
71-
BorrowckInferCtxt, Upvar,
71+
BorrowckInferCtxt,
7272
};
7373

7474
macro_rules! span_mirbug {
@@ -138,7 +138,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
138138
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
139139
move_data: &MoveData<'tcx>,
140140
elements: &Rc<RegionValueElements>,
141-
upvars: &[Upvar<'tcx>],
141+
upvars: &[&ty::CapturedPlace<'tcx>],
142142
use_polonius: bool,
143143
) -> MirTypeckResults<'tcx> {
144144
let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
@@ -857,7 +857,7 @@ struct BorrowCheckContext<'a, 'tcx> {
857857
all_facts: &'a mut Option<AllFacts>,
858858
borrow_set: &'a BorrowSet<'tcx>,
859859
pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
860-
upvars: &'a [Upvar<'tcx>],
860+
upvars: &'a [&'a ty::CapturedPlace<'tcx>],
861861

862862
/// The set of loans that are live at a given point in the CFG, filled in by `liveness::trace`,
863863
/// when using `-Zpolonius=next`.

Diff for: compiler/rustc_middle/src/ty/closure.rs

+7
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,13 @@ impl<'tcx> CapturedPlace<'tcx> {
247247
.span
248248
}
249249
}
250+
251+
pub fn is_by_ref(&self) -> bool {
252+
match self.info.capture_kind {
253+
ty::UpvarCapture::ByValue => false,
254+
ty::UpvarCapture::ByRef(..) => true,
255+
}
256+
}
250257
}
251258

252259
#[derive(Copy, Clone, Debug, HashStable)]

0 commit comments

Comments
 (0)