Skip to content
Permalink
Browse files

rustc: use indexmap instead of a plain vector for upvars.

  • Loading branch information...
eddyb committed May 14, 2019
1 parent 9fe0052 commit 961fe5479f3e981aafb4f8f957faea52ec295365
@@ -1183,6 +1183,11 @@ dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "indexmap"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "installer"
version = "0.0.0"
@@ -2719,6 +2724,7 @@ dependencies = [
"cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2970,6 +2976,7 @@ version = "0.0.0"
dependencies = [
"arena 0.0.0",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
@@ -3236,6 +3243,7 @@ dependencies = [
name = "serialize"
version = "0.0.0"
dependencies = [
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

@@ -4199,6 +4207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum if_chain 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d"
"checksum ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002"
"checksum im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0197597d095c0d11107975d3175173f810ee572c2501ff4de64f4f3f119806"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
@@ -30,6 +30,7 @@ use syntax::util::parser::ExprPrecedence;
use crate::ty::AdtKind;
use crate::ty::query::Providers;

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

/// A variable captured by a closure.
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
pub struct Upvar<Id = HirId> {
/// The variable being captured.
pub var_id: Id,

pub struct Upvar {
/// Whether this is not a direct capture (comes from parent closure).
pub has_parent: bool,

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

impl<Id: fmt::Debug + Copy> Upvar<Id> {
pub fn map_id<R>(self, map: impl FnOnce(Id) -> R) -> Upvar<R> {
Upvar {
var_id: map(self.var_id),
has_parent: self.has_parent,
span: self.span,
}
}
}

pub type UpvarMap = NodeMap<Vec<Upvar<ast::NodeId>>>;
pub type UpvarMap = NodeMap<FxIndexMap<ast::NodeId, Upvar>>;

pub type CaptureModeMap = NodeMap<CaptureClause>;

@@ -924,14 +924,15 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {

let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id);
if let Some(upvars) = self.tcx().upvars(closure_def_id) {
for upvar in upvars.iter() {
for (&var_id, upvar) in upvars.iter() {
let upvar_id = ty::UpvarId {
var_path: ty::UpvarPath { hir_id: upvar.var_id },
var_path: ty::UpvarPath { hir_id: var_id },
closure_expr_id: closure_def_id.to_local(),
};
let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.hir_id,
fn_decl_span,
var_id,
upvar));
match upvar_capture {
ty::UpvarCapture::ByValue => {
@@ -957,6 +958,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
fn cat_captured_var(&mut self,
closure_hir_id: hir::HirId,
closure_span: Span,
var_id: hir::HirId,
upvar: &hir::Upvar)
-> mc::McResult<mc::cmt_<'tcx>> {
// Create the cmt for the variable being borrowed, from the
@@ -965,11 +967,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_hir_id);
let parent_def_id = self.tcx().parent(closure_def_id).unwrap();
assert!(self.tcx().is_closure(parent_def_id));
let var_nid = self.tcx().hir().hir_to_node_id(upvar.var_id);
let var_nid = self.tcx().hir().hir_to_node_id(var_id);
self.mc.cat_upvar(closure_hir_id, closure_span, var_nid, parent_def_id)
} else {
let var_ty = self.mc.node_ty(upvar.var_id)?;
self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(upvar.var_id))
let var_ty = self.mc.node_ty(var_id)?;
self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(var_id))
}
}
}
@@ -485,10 +485,10 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
let mut call_caps = Vec::new();
let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
call_caps.extend(upvars.iter().filter_map(|upvar| {
call_caps.extend(upvars.iter().filter_map(|(&var_id, upvar)| {
if !upvar.has_parent {
let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
Some(CaptureInfo { ln: upvar_ln, var_hid: upvar.var_id })
Some(CaptureInfo { ln: upvar_ln, var_hid: var_id })
} else {
None
}
@@ -2562,8 +2562,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
let mut struct_fmt = fmt.debug_struct(&name);

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

if let Some(upvars) = tcx.upvars(def_id) {
for (upvar, place) in upvars.iter().zip(places) {
let var_name = tcx.hir().name_by_hir_id(upvar.var_id);
for (&var_id, place) in upvars.keys().zip(places) {
let var_name = tcx.hir().name_by_hir_id(var_id);
struct_fmt.field(&var_name.as_str(), place);
}
}
@@ -826,7 +826,7 @@ rustc_queries! {
desc { "generating a postorder list of CrateNums" }
}

query upvars(_: DefId) -> Option<&'tcx [hir::Upvar]> {
query upvars(_: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
eval_always
}
query maybe_unused_trait_import(_: DefId) -> bool {
@@ -54,6 +54,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
StableHasher, StableHasherResult,
StableVec};
use arena::SyncDroplessArena;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
use std::any::Any;
@@ -1065,7 +1066,7 @@ pub struct GlobalCtxt<'tcx> {
// Records the captured variables referenced by every closure
// expression. Do not track deps for this, just recompute it from
// scratch every time.
upvars: FxHashMap<DefId, Vec<hir::Upvar>>,
upvars: FxHashMap<DefId, FxIndexMap<hir::HirId, hir::Upvar>>,

maybe_unused_trait_imports: FxHashSet<DefId>,
maybe_unused_extern_crates: Vec<(DefId, Span)>,
@@ -1297,11 +1298,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}).collect();
(k, exports)
}).collect(),
upvars: resolutions.upvars.into_iter().map(|(k, v)| {
let vars: Vec<_> = v.into_iter().map(|e| {
e.map_id(|id| hir.node_to_hir_id(id))
upvars: resolutions.upvars.into_iter().map(|(k, upvars)| {
let upvars: FxIndexMap<_, _> = upvars.into_iter().map(|(var_id, upvar)| {
(hir.node_to_hir_id(var_id), upvar)
}).collect();
(hir.local_def_id(k), vars)
(hir.local_def_id(k), upvars)
}).collect(),
maybe_unused_trait_imports:
resolutions.maybe_unused_trait_imports
@@ -3023,7 +3024,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
assert_eq!(id, LOCAL_CRATE);
tcx.arena.alloc(middle::lang_items::collect(tcx))
};
providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).map(|v| &v[..]);
providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id);
providers.maybe_unused_trait_import = |tcx, id| {
tcx.maybe_unused_trait_imports.contains(&id)
};
@@ -51,6 +51,7 @@ use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
use syntax_pos::Span;

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

pub type UpvarListMap = FxHashMap<DefId, Vec<UpvarId>>;
pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;

#[derive(Copy, Clone)]
@@ -585,16 +585,16 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
let mut sep = " ";
for (upvar, upvar_ty) in self.tcx().upvars(did)
for (&var_id, upvar_ty) in self.tcx().upvars(did)
.as_ref()
.map_or(&[][..], |v| &v[..])
.iter()
.flat_map(|v| v.keys())
.zip(upvar_tys)
{
p!(
write("{}{}:",
sep,
self.tcx().hir().name_by_hir_id(upvar.var_id)),
self.tcx().hir().name_by_hir_id(var_id)),
print(upvar_ty));
sep = ", ";
}
@@ -628,16 +628,16 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
}
let mut sep = " ";
for (upvar, upvar_ty) in self.tcx().upvars(did)
for (&var_id, upvar_ty) in self.tcx().upvars(did)
.as_ref()
.map_or(&[][..], |v| &v[..])
.iter()
.flat_map(|v| v.keys())
.zip(upvar_tys)
{
p!(
write("{}{}:",
sep,
self.tcx().hir().name_by_hir_id(upvar.var_id)),
self.tcx().hir().name_by_hir_id(var_id)),
print(upvar_ty));
sep = ", ";
}
@@ -45,7 +45,7 @@ use crate::util::profiling::ProfileCategory::*;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::bit_set::BitSet;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::StableVec;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::fingerprint::Fingerprint;
@@ -11,6 +11,7 @@ crate-type = ["dylib"]

[dependencies]
ena = "0.13"
indexmap = "1"
log = "0.4"
jobserver_crate = { version = "0.1.13", package = "jobserver" }
lazy_static = "1"
@@ -1 +1,6 @@
use std::hash::BuildHasherDefault;

pub use rustc_hash::{FxHasher, FxHashMap, FxHashSet};

pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
@@ -323,6 +323,37 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
}
}

impl<K, V, R, CTX> HashStable<CTX> for indexmap::IndexMap<K, V, R>
where K: HashStable<CTX> + Eq + Hash,
V: HashStable<CTX>,
R: BuildHasher,
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
self.len().hash_stable(ctx, hasher);
for kv in self {
kv.hash_stable(ctx, hasher);
}
}
}

impl<K, R, CTX> HashStable<CTX> for indexmap::IndexSet<K, R>
where K: HashStable<CTX> + Eq + Hash,
R: BuildHasher,
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
self.len().hash_stable(ctx, hasher);
for key in self {
key.hash_stable(ctx, hasher);
}
}
}

impl<A, CTX> HashStable<CTX> for SmallVec<[A; 1]> where A: HashStable<CTX> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
@@ -348,9 +348,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// `tcx.upvars(def_id)` returns an `Option`, which is `None` in case
// the closure comes from another crate. But in that case we wouldn't
// be borrowck'ing it, so we can just unwrap:
let upvar = self.infcx.tcx.upvars(def_id).unwrap()[field.index()];
let (&var_id, _) = self.infcx.tcx.upvars(def_id).unwrap()
.get_index(field.index()).unwrap();

self.infcx.tcx.hir().name_by_hir_id(upvar.var_id).to_string()
self.infcx.tcx.hir().name_by_hir_id(var_id).to_string()
}
_ => {
// Might need a revision when the fields in trait RFC is implemented
@@ -645,12 +646,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
if let hir::ExprKind::Closure(
.., args_span, _
) = expr {
for (v, place) in self.infcx.tcx.upvars(def_id)?.iter().zip(places) {
for (upvar, place) in self.infcx.tcx.upvars(def_id)?.values().zip(places) {
match place {
Operand::Copy(place) |
Operand::Move(place) if target_place == place => {
debug!("closure_span: found captured local {:?}", place);
return Some((*args_span, v.span));
return Some((*args_span, upvar.span));
},
_ => {}
}
@@ -149,7 +149,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
.upvar_list
.get(&def_id)
.into_iter()
.flatten()
.flat_map(|v| v.values())
.map(|upvar_id| {
let var_hir_id = upvar_id.var_path.hir_id;
let var_node_id = tcx.hir().hir_to_node_id(var_hir_id);
@@ -651,10 +651,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
.get(&fn_def_id)
.into_iter()
.flatten()
.map(|upvar_id| {
let var_hir_id = upvar_id.var_path.hir_id;
.map(|(&var_hir_id, &upvar_id)| {
let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
let capture = hir_tables.upvar_capture(*upvar_id);
let capture = hir_tables.upvar_capture(upvar_id);
let by_ref = match capture {
ty::UpvarCapture::ByValue => false,
ty::UpvarCapture::ByRef(..) => true,

0 comments on commit 961fe54

Please sign in to comment.
You can’t perform that action at this time.