Skip to content

Commit 961fe54

Browse files
committed
rustc: use indexmap instead of a plain vector for upvars.
1 parent 9fe0052 commit 961fe54

File tree

26 files changed

+198
-115
lines changed

26 files changed

+198
-115
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,11 @@ dependencies = [
11831183
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
11841184
]
11851185

1186+
[[package]]
1187+
name = "indexmap"
1188+
version = "1.0.2"
1189+
source = "registry+https://github.com/rust-lang/crates.io-index"
1190+
11861191
[[package]]
11871192
name = "installer"
11881193
version = "0.0.0"
@@ -2719,6 +2724,7 @@ dependencies = [
27192724
"cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
27202725
"ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
27212726
"graphviz 0.0.0",
2727+
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
27222728
"jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
27232729
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
27242730
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2970,6 +2976,7 @@ version = "0.0.0"
29702976
dependencies = [
29712977
"arena 0.0.0",
29722978
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
2979+
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
29732980
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
29742981
"rustc 0.0.0",
29752982
"rustc_data_structures 0.0.0",
@@ -3236,6 +3243,7 @@ dependencies = [
32363243
name = "serialize"
32373244
version = "0.0.0"
32383245
dependencies = [
3246+
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
32393247
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
32403248
]
32413249

@@ -4199,6 +4207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
41994207
"checksum if_chain 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d"
42004208
"checksum ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002"
42014209
"checksum im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0197597d095c0d11107975d3175173f810ee572c2501ff4de64f4f3f119806"
4210+
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
42024211
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
42034212
"checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
42044213
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"

src/librustc/hir/mod.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use syntax::util::parser::ExprPrecedence;
3030
use crate::ty::AdtKind;
3131
use crate::ty::query::Providers;
3232

33+
use rustc_data_structures::fx::FxIndexMap;
3334
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
3435
use rustc_data_structures::thin_vec::ThinVec;
3536
use rustc_macros::HashStable;
@@ -2493,28 +2494,15 @@ impl ForeignItemKind {
24932494

24942495
/// A variable captured by a closure.
24952496
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
2496-
pub struct Upvar<Id = HirId> {
2497-
/// The variable being captured.
2498-
pub var_id: Id,
2499-
2497+
pub struct Upvar {
25002498
/// Whether this is not a direct capture (comes from parent closure).
25012499
pub has_parent: bool,
25022500

25032501
// First span where it is accessed (there can be multiple).
25042502
pub span: Span
25052503
}
25062504

2507-
impl<Id: fmt::Debug + Copy> Upvar<Id> {
2508-
pub fn map_id<R>(self, map: impl FnOnce(Id) -> R) -> Upvar<R> {
2509-
Upvar {
2510-
var_id: map(self.var_id),
2511-
has_parent: self.has_parent,
2512-
span: self.span,
2513-
}
2514-
}
2515-
}
2516-
2517-
pub type UpvarMap = NodeMap<Vec<Upvar<ast::NodeId>>>;
2505+
pub type UpvarMap = NodeMap<FxIndexMap<ast::NodeId, Upvar>>;
25182506

25192507
pub type CaptureModeMap = NodeMap<CaptureClause>;
25202508

src/librustc/middle/expr_use_visitor.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -924,14 +924,15 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
924924

925925
let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id);
926926
if let Some(upvars) = self.tcx().upvars(closure_def_id) {
927-
for upvar in upvars.iter() {
927+
for (&var_id, upvar) in upvars.iter() {
928928
let upvar_id = ty::UpvarId {
929-
var_path: ty::UpvarPath { hir_id: upvar.var_id },
929+
var_path: ty::UpvarPath { hir_id: var_id },
930930
closure_expr_id: closure_def_id.to_local(),
931931
};
932932
let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
933933
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.hir_id,
934934
fn_decl_span,
935+
var_id,
935936
upvar));
936937
match upvar_capture {
937938
ty::UpvarCapture::ByValue => {
@@ -957,6 +958,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
957958
fn cat_captured_var(&mut self,
958959
closure_hir_id: hir::HirId,
959960
closure_span: Span,
961+
var_id: hir::HirId,
960962
upvar: &hir::Upvar)
961963
-> mc::McResult<mc::cmt_<'tcx>> {
962964
// Create the cmt for the variable being borrowed, from the
@@ -965,11 +967,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
965967
let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_hir_id);
966968
let parent_def_id = self.tcx().parent(closure_def_id).unwrap();
967969
assert!(self.tcx().is_closure(parent_def_id));
968-
let var_nid = self.tcx().hir().hir_to_node_id(upvar.var_id);
970+
let var_nid = self.tcx().hir().hir_to_node_id(var_id);
969971
self.mc.cat_upvar(closure_hir_id, closure_span, var_nid, parent_def_id)
970972
} else {
971-
let var_ty = self.mc.node_ty(upvar.var_id)?;
972-
self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(upvar.var_id))
973+
let var_ty = self.mc.node_ty(var_id)?;
974+
self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(var_id))
973975
}
974976
}
975977
}

src/librustc/middle/liveness.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,10 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
485485
let mut call_caps = Vec::new();
486486
let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
487487
if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
488-
call_caps.extend(upvars.iter().filter_map(|upvar| {
488+
call_caps.extend(upvars.iter().filter_map(|(&var_id, upvar)| {
489489
if !upvar.has_parent {
490490
let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
491-
Some(CaptureInfo { ln: upvar_ln, var_hid: upvar.var_id })
491+
Some(CaptureInfo { ln: upvar_ln, var_hid: var_id })
492492
} else {
493493
None
494494
}

src/librustc/mir/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,8 +2562,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
25622562
let mut struct_fmt = fmt.debug_struct(&name);
25632563

25642564
if let Some(upvars) = tcx.upvars(def_id) {
2565-
for (upvar, place) in upvars.iter().zip(places) {
2566-
let var_name = tcx.hir().name_by_hir_id(upvar.var_id);
2565+
for (&var_id, place) in upvars.keys().zip(places) {
2566+
let var_name = tcx.hir().name_by_hir_id(var_id);
25672567
struct_fmt.field(&var_name.as_str(), place);
25682568
}
25692569
}
@@ -2581,8 +2581,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
25812581
let mut struct_fmt = fmt.debug_struct(&name);
25822582

25832583
if let Some(upvars) = tcx.upvars(def_id) {
2584-
for (upvar, place) in upvars.iter().zip(places) {
2585-
let var_name = tcx.hir().name_by_hir_id(upvar.var_id);
2584+
for (&var_id, place) in upvars.keys().zip(places) {
2585+
let var_name = tcx.hir().name_by_hir_id(var_id);
25862586
struct_fmt.field(&var_name.as_str(), place);
25872587
}
25882588
}

src/librustc/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,7 @@ rustc_queries! {
826826
desc { "generating a postorder list of CrateNums" }
827827
}
828828

829-
query upvars(_: DefId) -> Option<&'tcx [hir::Upvar]> {
829+
query upvars(_: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
830830
eval_always
831831
}
832832
query maybe_unused_trait_import(_: DefId) -> bool {

src/librustc/ty/context.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5454
StableHasher, StableHasherResult,
5555
StableVec};
5656
use arena::SyncDroplessArena;
57+
use rustc_data_structures::fx::FxIndexMap;
5758
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
5859
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
5960
use std::any::Any;
@@ -1065,7 +1066,7 @@ pub struct GlobalCtxt<'tcx> {
10651066
// Records the captured variables referenced by every closure
10661067
// expression. Do not track deps for this, just recompute it from
10671068
// scratch every time.
1068-
upvars: FxHashMap<DefId, Vec<hir::Upvar>>,
1069+
upvars: FxHashMap<DefId, FxIndexMap<hir::HirId, hir::Upvar>>,
10691070

10701071
maybe_unused_trait_imports: FxHashSet<DefId>,
10711072
maybe_unused_extern_crates: Vec<(DefId, Span)>,
@@ -1297,11 +1298,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12971298
}).collect();
12981299
(k, exports)
12991300
}).collect(),
1300-
upvars: resolutions.upvars.into_iter().map(|(k, v)| {
1301-
let vars: Vec<_> = v.into_iter().map(|e| {
1302-
e.map_id(|id| hir.node_to_hir_id(id))
1301+
upvars: resolutions.upvars.into_iter().map(|(k, upvars)| {
1302+
let upvars: FxIndexMap<_, _> = upvars.into_iter().map(|(var_id, upvar)| {
1303+
(hir.node_to_hir_id(var_id), upvar)
13031304
}).collect();
1304-
(hir.local_def_id(k), vars)
1305+
(hir.local_def_id(k), upvars)
13051306
}).collect(),
13061307
maybe_unused_trait_imports:
13071308
resolutions.maybe_unused_trait_imports
@@ -3023,7 +3024,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
30233024
assert_eq!(id, LOCAL_CRATE);
30243025
tcx.arena.alloc(middle::lang_items::collect(tcx))
30253026
};
3026-
providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).map(|v| &v[..]);
3027+
providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id);
30273028
providers.maybe_unused_trait_import = |tcx, id| {
30283029
tcx.maybe_unused_trait_imports.contains(&id)
30293030
};

src/librustc/ty/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
5151
use syntax_pos::Span;
5252

5353
use smallvec;
54+
use rustc_data_structures::fx::FxIndexMap;
5455
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
5556
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
5657
HashStable};
@@ -808,7 +809,7 @@ pub struct UpvarBorrow<'tcx> {
808809
pub region: ty::Region<'tcx>,
809810
}
810811

811-
pub type UpvarListMap = FxHashMap<DefId, Vec<UpvarId>>;
812+
pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
812813
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
813814

814815
#[derive(Copy, Clone)]

src/librustc/ty/print/pretty.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -585,16 +585,16 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
585585
if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
586586
p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
587587
let mut sep = " ";
588-
for (upvar, upvar_ty) in self.tcx().upvars(did)
588+
for (&var_id, upvar_ty) in self.tcx().upvars(did)
589589
.as_ref()
590-
.map_or(&[][..], |v| &v[..])
591590
.iter()
591+
.flat_map(|v| v.keys())
592592
.zip(upvar_tys)
593593
{
594594
p!(
595595
write("{}{}:",
596596
sep,
597-
self.tcx().hir().name_by_hir_id(upvar.var_id)),
597+
self.tcx().hir().name_by_hir_id(var_id)),
598598
print(upvar_ty));
599599
sep = ", ";
600600
}
@@ -628,16 +628,16 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
628628
p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
629629
}
630630
let mut sep = " ";
631-
for (upvar, upvar_ty) in self.tcx().upvars(did)
631+
for (&var_id, upvar_ty) in self.tcx().upvars(did)
632632
.as_ref()
633-
.map_or(&[][..], |v| &v[..])
634633
.iter()
634+
.flat_map(|v| v.keys())
635635
.zip(upvar_tys)
636636
{
637637
p!(
638638
write("{}{}:",
639639
sep,
640-
self.tcx().hir().name_by_hir_id(upvar.var_id)),
640+
self.tcx().hir().name_by_hir_id(var_id)),
641641
print(upvar_ty));
642642
sep = ", ";
643643
}

src/librustc/ty/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::util::profiling::ProfileCategory::*;
4545
use rustc_data_structures::svh::Svh;
4646
use rustc_data_structures::bit_set::BitSet;
4747
use rustc_data_structures::indexed_vec::IndexVec;
48-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
48+
use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet};
4949
use rustc_data_structures::stable_hasher::StableVec;
5050
use rustc_data_structures::sync::Lrc;
5151
use rustc_data_structures::fingerprint::Fingerprint;

src/librustc_data_structures/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ crate-type = ["dylib"]
1111

1212
[dependencies]
1313
ena = "0.13"
14+
indexmap = "1"
1415
log = "0.4"
1516
jobserver_crate = { version = "0.1.13", package = "jobserver" }
1617
lazy_static = "1"

src/librustc_data_structures/fx.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
use std::hash::BuildHasherDefault;
2+
13
pub use rustc_hash::{FxHasher, FxHashMap, FxHashSet};
4+
5+
pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
6+
pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;

src/librustc_data_structures/stable_hasher.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,37 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
323323
}
324324
}
325325

326+
impl<K, V, R, CTX> HashStable<CTX> for indexmap::IndexMap<K, V, R>
327+
where K: HashStable<CTX> + Eq + Hash,
328+
V: HashStable<CTX>,
329+
R: BuildHasher,
330+
{
331+
#[inline]
332+
fn hash_stable<W: StableHasherResult>(&self,
333+
ctx: &mut CTX,
334+
hasher: &mut StableHasher<W>) {
335+
self.len().hash_stable(ctx, hasher);
336+
for kv in self {
337+
kv.hash_stable(ctx, hasher);
338+
}
339+
}
340+
}
341+
342+
impl<K, R, CTX> HashStable<CTX> for indexmap::IndexSet<K, R>
343+
where K: HashStable<CTX> + Eq + Hash,
344+
R: BuildHasher,
345+
{
346+
#[inline]
347+
fn hash_stable<W: StableHasherResult>(&self,
348+
ctx: &mut CTX,
349+
hasher: &mut StableHasher<W>) {
350+
self.len().hash_stable(ctx, hasher);
351+
for key in self {
352+
key.hash_stable(ctx, hasher);
353+
}
354+
}
355+
}
356+
326357
impl<A, CTX> HashStable<CTX> for SmallVec<[A; 1]> where A: HashStable<CTX> {
327358
#[inline]
328359
fn hash_stable<W: StableHasherResult>(&self,

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
348348
// `tcx.upvars(def_id)` returns an `Option`, which is `None` in case
349349
// the closure comes from another crate. But in that case we wouldn't
350350
// be borrowck'ing it, so we can just unwrap:
351-
let upvar = self.infcx.tcx.upvars(def_id).unwrap()[field.index()];
351+
let (&var_id, _) = self.infcx.tcx.upvars(def_id).unwrap()
352+
.get_index(field.index()).unwrap();
352353

353-
self.infcx.tcx.hir().name_by_hir_id(upvar.var_id).to_string()
354+
self.infcx.tcx.hir().name_by_hir_id(var_id).to_string()
354355
}
355356
_ => {
356357
// Might need a revision when the fields in trait RFC is implemented
@@ -645,12 +646,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
645646
if let hir::ExprKind::Closure(
646647
.., args_span, _
647648
) = expr {
648-
for (v, place) in self.infcx.tcx.upvars(def_id)?.iter().zip(places) {
649+
for (upvar, place) in self.infcx.tcx.upvars(def_id)?.values().zip(places) {
649650
match place {
650651
Operand::Copy(place) |
651652
Operand::Move(place) if target_place == place => {
652653
debug!("closure_span: found captured local {:?}", place);
653-
return Some((*args_span, v.span));
654+
return Some((*args_span, upvar.span));
654655
},
655656
_ => {}
656657
}

src/librustc_mir/borrow_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
149149
.upvar_list
150150
.get(&def_id)
151151
.into_iter()
152-
.flatten()
152+
.flat_map(|v| v.values())
153153
.map(|upvar_id| {
154154
let var_hir_id = upvar_id.var_path.hir_id;
155155
let var_node_id = tcx.hir().hir_to_node_id(var_hir_id);

src/librustc_mir/build/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
651651
.get(&fn_def_id)
652652
.into_iter()
653653
.flatten()
654-
.map(|upvar_id| {
655-
let var_hir_id = upvar_id.var_path.hir_id;
654+
.map(|(&var_hir_id, &upvar_id)| {
656655
let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
657-
let capture = hir_tables.upvar_capture(*upvar_id);
656+
let capture = hir_tables.upvar_capture(upvar_id);
658657
let by_ref = match capture {
659658
ty::UpvarCapture::ByValue => false,
660659
ty::UpvarCapture::ByRef(..) => true,

0 commit comments

Comments
 (0)