Skip to content

Commit 0d12553

Browse files
committed
Auto merge of #43740 - michaelwoerister:local-id-in-typecktables, r=arielb1
Use hir::ItemLocalId as keys in TypeckTables. This PR makes `TypeckTables` use `ItemLocalId` instead of `NodeId` as key. This is needed for incremental compilation -- for stable hashing and for being able to persist and reload these tables. The PR implements the most important part of #40303. Some notes on the implementation: * The PR adds the `HirId` to HIR nodes where needed (`Expr`, `Local`, `Block`, `Pat`) which obviates the need to store a `NodeId -> HirId` mapping in crate metadata. Thanks @eddyb for the suggestion! In the future the `HirId` should completely replace the `NodeId` in HIR nodes. * Before something is read or stored in one of the various `TypeckTables` subtables, the entry's key is validated via the new `TypeckTables::validate_hir_id()` method. This makes sure that we are not mixing information from different items in a single table. That last part could be made a bit nicer by either (a) new-typing the table-key and making `validate_hir_id()` the only way to convert a `HirId` to the new-typed key, or (b) just encapsulate sub-table access a little better. This PR, however, contents itself with not making things significantly worse. Also, there's quite a bit of switching around between `NodeId`, `HirId`, and `DefIndex`. These conversions are cheap except for `HirId -> NodeId`, so if the valued reviewer finds such an instance in a performance critical place, please let me know. Ideally we convert more and more code from `NodeId` to `HirId` in the future so that there are no more `NodeId`s after HIR lowering anywhere. Then the amount of switching should be minimal again. r? @eddyb, maybe?
2 parents d49b730 + 3b92b97 commit 0d12553

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1222
-544
lines changed

src/librustc/hir/lowering.rs

+118-62
Large diffs are not rendered by default.

src/librustc/hir/map/definitions.rs

+21
Original file line numberDiff line numberDiff line change
@@ -434,18 +434,22 @@ impl Definitions {
434434
DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
435435
}
436436

437+
#[inline]
437438
pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
438439
self.node_to_def_index.get(&node).cloned()
439440
}
440441

442+
#[inline]
441443
pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
442444
self.opt_def_index(node).map(DefId::local)
443445
}
444446

447+
#[inline]
445448
pub fn local_def_id(&self, node: ast::NodeId) -> DefId {
446449
self.opt_local_def_id(node).unwrap()
447450
}
448451

452+
#[inline]
449453
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
450454
if def_id.krate == LOCAL_CRATE {
451455
let space_index = def_id.index.address_space().index();
@@ -461,10 +465,27 @@ impl Definitions {
461465
}
462466
}
463467

468+
#[inline]
464469
pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
465470
self.node_to_hir_id[node_id]
466471
}
467472

473+
pub fn find_node_for_hir_id(&self, hir_id: hir::HirId) -> ast::NodeId {
474+
self.node_to_hir_id
475+
.iter()
476+
.position(|x| *x == hir_id)
477+
.map(|idx| ast::NodeId::new(idx))
478+
.unwrap()
479+
}
480+
481+
#[inline]
482+
pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
483+
let space_index = def_index.address_space().index();
484+
let array_index = def_index.as_array_index();
485+
let node_id = self.def_index_to_node[space_index][array_index];
486+
self.node_to_hir_id[node_id]
487+
}
488+
468489
/// Add a definition with a parent definition.
469490
pub fn create_root_def(&mut self,
470491
crate_name: &str,

src/librustc/hir/map/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ impl<'hir> Map<'hir> {
357357
}
358358
}
359359

360+
#[inline]
360361
pub fn definitions(&self) -> &Definitions {
361362
&self.definitions
362363
}
@@ -377,21 +378,39 @@ impl<'hir> Map<'hir> {
377378
self.definitions.def_path(def_id.index)
378379
}
379380

381+
#[inline]
380382
pub fn local_def_id(&self, node: NodeId) -> DefId {
381383
self.opt_local_def_id(node).unwrap_or_else(|| {
382384
bug!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
383385
node, self.find_entry(node))
384386
})
385387
}
386388

389+
#[inline]
387390
pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
388391
self.definitions.opt_local_def_id(node)
389392
}
390393

394+
#[inline]
391395
pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
392396
self.definitions.as_local_node_id(def_id)
393397
}
394398

399+
#[inline]
400+
pub fn node_to_hir_id(&self, node_id: NodeId) -> HirId {
401+
self.definitions.node_to_hir_id(node_id)
402+
}
403+
404+
#[inline]
405+
pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> HirId {
406+
self.definitions.def_index_to_hir_id(def_index)
407+
}
408+
409+
#[inline]
410+
pub fn def_index_to_node_id(&self, def_index: DefIndex) -> NodeId {
411+
self.definitions.as_local_node_id(DefId::local(def_index)).unwrap()
412+
}
413+
395414
fn entry_count(&self) -> usize {
396415
self.map.len()
397416
}

src/librustc/hir/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,11 @@ pub const CRATE_HIR_ID: HirId = HirId {
129129

130130
pub const DUMMY_HIR_ID: HirId = HirId {
131131
owner: CRATE_DEF_INDEX,
132-
local_id: ItemLocalId(!0)
132+
local_id: DUMMY_ITEM_LOCAL_ID,
133133
};
134134

135+
pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId(!0);
136+
135137
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
136138
pub struct Lifetime {
137139
pub id: NodeId,
@@ -547,6 +549,7 @@ pub struct Block {
547549
/// without a semicolon, if any
548550
pub expr: Option<P<Expr>>,
549551
pub id: NodeId,
552+
pub hir_id: HirId,
550553
/// Distinguishes between `unsafe { ... }` and `{ ... }`
551554
pub rules: BlockCheckMode,
552555
pub span: Span,
@@ -560,6 +563,7 @@ pub struct Block {
560563
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
561564
pub struct Pat {
562565
pub id: NodeId,
566+
pub hir_id: HirId,
563567
pub node: PatKind,
564568
pub span: Span,
565569
}
@@ -897,6 +901,7 @@ pub struct Local {
897901
/// Initializer expression to set the value, if any
898902
pub init: Option<P<Expr>>,
899903
pub id: NodeId,
904+
pub hir_id: HirId,
900905
pub span: Span,
901906
pub attrs: ThinVec<Attribute>,
902907
pub source: LocalSource,
@@ -986,6 +991,7 @@ pub struct Expr {
986991
pub span: Span,
987992
pub node: Expr_,
988993
pub attrs: ThinVec<Attribute>,
994+
pub hir_id: HirId,
989995
}
990996

991997
impl fmt::Debug for Expr {
@@ -1423,6 +1429,7 @@ pub struct InlineAsm {
14231429
pub struct Arg {
14241430
pub pat: P<Pat>,
14251431
pub id: NodeId,
1432+
pub hir_id: HirId,
14261433
}
14271434

14281435
/// Represents the header (not the body) of a function declaration

src/librustc/ich/hcx.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use hir::map::DefPathHash;
1414
use ich::{self, CachingCodemapView};
1515
use session::config::DebugInfoLevel::NoDebugInfo;
1616
use ty;
17-
use util::nodemap::NodeMap;
17+
use util::nodemap::{NodeMap, ItemLocalMap};
1818

1919
use std::hash as std_hash;
2020
use std::collections::{HashMap, HashSet, BTreeMap};
@@ -358,6 +358,18 @@ pub fn hash_stable_nodemap<'a, 'tcx, 'gcx, V, W>(
358358
});
359359
}
360360

361+
pub fn hash_stable_itemlocalmap<'a, 'tcx, 'gcx, V, W>(
362+
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
363+
hasher: &mut StableHasher<W>,
364+
map: &ItemLocalMap<V>)
365+
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
366+
W: StableHasherResult,
367+
{
368+
hash_stable_hashmap(hcx, hasher, map, |_, local_id| {
369+
*local_id
370+
});
371+
}
372+
361373

362374
pub fn hash_stable_btreemap<'a, 'tcx, 'gcx, K, V, SK, F, W>(
363375
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,

src/librustc/ich/impls_hir.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B
359359
ref stmts,
360360
ref expr,
361361
id,
362+
hir_id: _,
362363
rules,
363364
span,
364365
targeted_by_break,
@@ -423,6 +424,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P
423424

424425
let hir::Pat {
425426
id,
427+
hir_id: _,
426428
ref node,
427429
ref span
428430
} = *self;
@@ -504,6 +506,7 @@ impl_stable_hash_for!(struct hir::Local {
504506
ty,
505507
init,
506508
id,
509+
hir_id,
507510
span,
508511
attrs,
509512
source
@@ -551,6 +554,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E
551554
hcx.while_hashing_hir_bodies(true, |hcx| {
552555
let hir::Expr {
553556
id,
557+
hir_id: _,
554558
ref span,
555559
ref node,
556560
ref attrs
@@ -1021,7 +1025,8 @@ impl_stable_hash_for!(enum hir::Stmt_ {
10211025

10221026
impl_stable_hash_for!(struct hir::Arg {
10231027
pat,
1024-
id
1028+
id,
1029+
hir_id
10251030
});
10261031

10271032
impl_stable_hash_for!(struct hir::Body {

src/librustc/ich/impls_ty.rs

+1-59
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! This module contains `HashStable` implementations for various data types
1212
//! from rustc::ty in no particular order.
1313
14-
use ich::{self, StableHashingContext, NodeIdHashingMode};
14+
use ich::StableHashingContext;
1515
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
1616
StableHasherResult};
1717
use std::hash as std_hash;
@@ -611,64 +611,6 @@ impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
611611
ty
612612
});
613613

614-
615-
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
616-
for ty::TypeckTables<'gcx> {
617-
fn hash_stable<W: StableHasherResult>(&self,
618-
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
619-
hasher: &mut StableHasher<W>) {
620-
let ty::TypeckTables {
621-
ref type_dependent_defs,
622-
ref node_types,
623-
ref node_substs,
624-
ref adjustments,
625-
ref pat_binding_modes,
626-
ref upvar_capture_map,
627-
ref closure_tys,
628-
ref closure_kinds,
629-
ref liberated_fn_sigs,
630-
ref fru_field_types,
631-
632-
ref cast_kinds,
633-
634-
ref used_trait_imports,
635-
tainted_by_errors,
636-
ref free_region_map,
637-
} = *self;
638-
639-
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
640-
ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs);
641-
ich::hash_stable_nodemap(hcx, hasher, node_types);
642-
ich::hash_stable_nodemap(hcx, hasher, node_substs);
643-
ich::hash_stable_nodemap(hcx, hasher, adjustments);
644-
ich::hash_stable_nodemap(hcx, hasher, pat_binding_modes);
645-
ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
646-
let ty::UpvarId {
647-
var_id,
648-
closure_expr_id
649-
} = *up_var_id;
650-
651-
let var_def_id = hcx.tcx().hir.local_def_id(var_id);
652-
let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id);
653-
(hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
654-
});
655-
656-
ich::hash_stable_nodemap(hcx, hasher, closure_tys);
657-
ich::hash_stable_nodemap(hcx, hasher, closure_kinds);
658-
ich::hash_stable_nodemap(hcx, hasher, liberated_fn_sigs);
659-
ich::hash_stable_nodemap(hcx, hasher, fru_field_types);
660-
ich::hash_stable_nodemap(hcx, hasher, cast_kinds);
661-
662-
ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
663-
hcx.def_path_hash(*def_id)
664-
});
665-
666-
tainted_by_errors.hash_stable(hcx, hasher);
667-
free_region_map.hash_stable(hcx, hasher);
668-
})
669-
}
670-
}
671-
672614
impl_stable_hash_for!(enum ty::fast_reject::SimplifiedType {
673615
BoolSimplifiedType,
674616
CharSimplifiedType,

src/librustc/ich/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use self::fingerprint::Fingerprint;
1414
pub use self::caching_codemap_view::CachingCodemapView;
1515
pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_hashmap,
1616
hash_stable_hashset, hash_stable_nodemap,
17-
hash_stable_btreemap};
17+
hash_stable_btreemap, hash_stable_itemlocalmap};
1818
mod fingerprint;
1919
mod caching_codemap_view;
2020
mod hcx;

src/librustc/infer/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
913913
}
914914
infer::UpvarRegion(ref upvar_id, _) => {
915915
format!(" for capture of `{}` by closure",
916-
self.tcx.local_var_name_str(upvar_id.var_id).to_string())
916+
self.tcx.local_var_name_str_def_index(upvar_id.var_id))
917917
}
918918
};
919919

src/librustc/infer/error_reporting/need_type_info.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use hir::{self, Local, Pat, Body};
11+
use hir::{self, Local, Pat, Body, HirId};
1212
use hir::intravisit::{self, Visitor, NestedVisitorMap};
1313
use infer::InferCtxt;
1414
use infer::type_variable::TypeVariableOrigin;
1515
use ty::{self, Ty, TyInfer, TyVar};
16-
17-
use syntax::ast::NodeId;
1816
use syntax_pos::Span;
1917

2018
struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -26,7 +24,7 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
2624
}
2725

2826
impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
29-
fn node_matches_type(&mut self, node_id: NodeId) -> bool {
27+
fn node_matches_type(&mut self, node_id: HirId) -> bool {
3028
let ty_opt = self.infcx.in_progress_tables.and_then(|tables| {
3129
tables.borrow().node_id_to_type_opt(node_id)
3230
});
@@ -56,15 +54,15 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
5654
}
5755

5856
fn visit_local(&mut self, local: &'gcx Local) {
59-
if self.found_local_pattern.is_none() && self.node_matches_type(local.id) {
57+
if self.found_local_pattern.is_none() && self.node_matches_type(local.hir_id) {
6058
self.found_local_pattern = Some(&*local.pat);
6159
}
6260
intravisit::walk_local(self, local);
6361
}
6462

6563
fn visit_body(&mut self, body: &'gcx Body) {
6664
for argument in &body.arguments {
67-
if self.found_arg_pattern.is_none() && self.node_matches_type(argument.id) {
65+
if self.found_arg_pattern.is_none() && self.node_matches_type(argument.hir_id) {
6866
self.found_arg_pattern = Some(&*argument.pat);
6967
}
7068
}

src/librustc/infer/error_reporting/note.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
4545
err.span_note(span,
4646
&format!("...so that closure can access `{}`",
4747
self.tcx
48-
.local_var_name_str(upvar_id.var_id)
49-
.to_string()));
48+
.local_var_name_str_def_index(upvar_id.var_id)));
5049
}
5150
infer::InfStackClosure(span) => {
5251
err.span_note(span, "...so that closure does not outlive its stack frame");
@@ -176,18 +175,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
176175
E0313,
177176
"lifetime of borrowed pointer outlives lifetime \
178177
of captured variable `{}`...",
179-
self.tcx.local_var_name_str(upvar_id.var_id));
178+
self.tcx
179+
.local_var_name_str_def_index(upvar_id.var_id));
180180
self.tcx.note_and_explain_region(&mut err,
181181
"...the borrowed pointer is valid for ",
182182
sub,
183183
"...");
184184
self.tcx
185-
.note_and_explain_region(&mut err,
186-
&format!("...but `{}` is only valid for ",
187-
self.tcx
188-
.local_var_name_str(upvar_id.var_id)),
189-
sup,
190-
"");
185+
.note_and_explain_region(
186+
&mut err,
187+
&format!("...but `{}` is only valid for ",
188+
self.tcx.local_var_name_str_def_index(upvar_id.var_id)),
189+
sup,
190+
"");
191191
err
192192
}
193193
infer::InfStackClosure(span) => {

0 commit comments

Comments
 (0)