Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use hir::ItemLocalId as keys in TypeckTables. #43740

Merged
merged 16 commits into from
Aug 14, 2017

Conversation

michaelwoerister
Copy link
Member

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 NodeIds after HIR lowering anywhere. Then the amount of switching should be minimal again.

r? @eddyb, maybe?

@eddyb
Copy link
Member

eddyb commented Aug 8, 2017

LGTM. r? @arielb1

@rust-highfive rust-highfive assigned arielb1 and unassigned eddyb Aug 8, 2017
@@ -119,6 +119,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {

fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def,
pats: &[codemap::Spanned<hir::FieldPat>]) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@@ -375,7 +375,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
});
let mut reachable_context = ReachableContext {
tcx,
tables: &ty::TypeckTables::empty(),
tables: &ty::TypeckTables::empty(DefId::invalid()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a FIXME? Shouldn't tables be None when outside of an item?

TypeckTables {
type_dependent_defs: NodeMap(),
local_id_root,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing with local_id_root being sometimes invalid makes me uncomfortable. Please insert an Option somewhere (I think making local_id_root an option would work well).

@@ -384,6 +390,30 @@ impl<'tcx> TypeckTables<'tcx> {
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
self.upvar_capture_map[&upvar_id]
}

/// Validate that a NodeId can safely be converted to an ItemLocalId for
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is this function called? It seems to be called on some random HIR id accesses.

@@ -466,7 +466,11 @@ impl Definitions {
}

pub fn find_node_for_hir_id(&self, hir_id: hir::HirId) -> ast::NodeId {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you rather do some sort of merging of this function with validate_hir_id? Unmarked linear searches are dangerous.

@@ -207,52 +207,55 @@ pub struct CommonTypes<'tcx> {

#[derive(RustcEncodable, RustcDecodable)]
pub struct TypeckTables<'tcx> {
/// The HirId::owner all ItemLocalIds in this table are relative to.
pub local_id_root: DefId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in several places initialized with an invalid_def_id. Why can't this be an Option?

@arielb1
Copy link
Contributor

arielb1 commented Aug 9, 2017

I don't like the way validate_def_id is spread around randomly in code. I think I would make the TypeckTables fields to be functions that return a

pub struct LocalTableInContext<'a, V> {
    parent_def_id: Option<DefId>,
    data: &'a LocalItemMap<V>
}

Which does validation on the accessor methods. Or something.

@aidanhs aidanhs added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Aug 10, 2017
@michaelwoerister
Copy link
Member Author

OK, I'll change the various visitors to use an Option<&TypeckTables>. I don't like make the local_id_root optional, since every TypeckTables should really have one of these.

I'll also look into a way of handling HirId validation in a more central place.

@bors
Copy link
Contributor

bors commented Aug 10, 2017

☔ The latest upstream changes (presumably #43582) made this pull request unmergeable. Please resolve the merge conflicts.

@michaelwoerister michaelwoerister force-pushed the local-id-in-typecktables branch from 49abb36 to 75022ed Compare August 10, 2017 14:30
@bors
Copy link
Contributor

bors commented Aug 11, 2017

☔ The latest upstream changes (presumably #43743) made this pull request unmergeable. Please resolve the merge conflicts.

@michaelwoerister michaelwoerister force-pushed the local-id-in-typecktables branch from 91207de to c078583 Compare August 11, 2017 10:09
@michaelwoerister michaelwoerister force-pushed the local-id-in-typecktables branch from c078583 to a69eaf6 Compare August 11, 2017 10:17
@michaelwoerister
Copy link
Member Author

@arielb1 I think I addressed your comments.

@michaelwoerister michaelwoerister added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 11, 2017
@michaelwoerister
Copy link
Member Author

(Note: I've added the last three commits. The others were not touched except for rebasing).

@@ -201,4 +201,11 @@ impl DefId {
pub fn is_local(&self) -> bool {
self.krate == LOCAL_CRATE
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused function plz kill

@@ -119,7 +119,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {

fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def,
pats: &[codemap::Spanned<hir::FieldPat>]) {
let variant = match self.tables.node_id_to_type(lhs.id).sty {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: stray newlines in program

}

impl<'a, V> LocalTableInContextMut<'a, V> {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: stray newline in program

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually like newlines in places like this. Makes the impl line easier to read. But I'll remove it for consistency.

@@ -1606,21 +1656,26 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

let krate = tcx.hir.krate();

let empty_tables = ty::TypeckTables::empty(None);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: stray newline in program (I think)

@arielb1
Copy link
Contributor

arielb1 commented Aug 13, 2017

Nice! r=me modulo nits.

@michaelwoerister michaelwoerister force-pushed the local-id-in-typecktables branch from b30f28a to 6fd7d85 Compare August 14, 2017 09:21
@michaelwoerister
Copy link
Member Author

@bors r=arielb1

Amended the nit fixes to the last commit. Thanks for the reviews!

@bors
Copy link
Contributor

bors commented Aug 14, 2017

📌 Commit 6fd7d85 has been approved by arielb1

@bors
Copy link
Contributor

bors commented Aug 14, 2017

⌛ Testing commit 6fd7d85 with merge 52523ded9a2d39d7a76f41a9d373610cdeecf501...

@bors
Copy link
Contributor

bors commented Aug 14, 2017

💔 Test failed - status-travis

/// stored/returned.
fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
hir_id: hir::HirId,
mut_access: bool) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[00:10:17] error: unused variable: `local_id_root`
[00:10:17]    --> /checkout/src/librustc/ty/context.rs:226:38
[00:10:17]     |
[00:10:17] 226 | fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
[00:10:17]     |                                      ^^^^^^^^^^^^^
[00:10:17]     |
[00:10:17] 
[00:10:17] error: unused variable: `hir_id`
[00:10:17]    --> /checkout/src/librustc/ty/context.rs:227:38
[00:10:17]     |
[00:10:17] 227 |                                      hir_id: hir::HirId,
[00:10:17]     |                                      ^^^^^^
[00:10:17] 
[00:10:17] error: unused variable: `mut_access`
[00:10:17]    --> /checkout/src/librustc/ty/context.rs:228:38
[00:10:17]     |
[00:10:17] 228 |                                      mut_access: bool) {
[00:10:17]     |                                      ^^^^^^^^^^
[00:10:17] 
[00:10:18] error: aborting due to 3 previous errors
[00:10:18] 
[00:10:18] error: Could not compile `rustc`.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @kennytm! That must be because of the cfg(debug_assertions) switch...

@michaelwoerister
Copy link
Member Author

@bors r=arielb1

@bors
Copy link
Contributor

bors commented Aug 14, 2017

📌 Commit 3b92b97 has been approved by arielb1

@bors
Copy link
Contributor

bors commented Aug 14, 2017

⌛ Testing commit 3b92b97 with merge 0d12553...

bors added a commit that referenced this pull request Aug 14, 2017
…rielb1

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?
@bors
Copy link
Contributor

bors commented Aug 14, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: arielb1
Pushing 0d12553 to master...

@bors bors merged commit 3b92b97 into rust-lang:master Aug 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants