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

incr.comp.: Crate Metadata not corresponding to a DefId is untracked. #41417

Closed
michaelwoerister opened this issue Apr 20, 2017 · 34 comments
Closed
Labels
A-incr-comp Area: Incremental compilation C-enhancement Category: An issue proposing an enhancement or a PR with one. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.

Comments

@michaelwoerister
Copy link
Member

michaelwoerister commented Apr 20, 2017

Mentoring update: Mentoring instructions can be found here


There are many things in crate metadata that are not covered by dependency tracking (basically everything below this line). Those are things that are unlikely to change in an upstream crate, which is why this has not caused problems yet, but we'll not want to rely on that.

The best way to solve this is probably to create separate "input" DepNodes for these.

cc @nikomatsakis

@michaelwoerister michaelwoerister added the A-incr-comp Area: Incremental compilation label Apr 20, 2017
@nikomatsakis
Copy link
Contributor

Yes, I want to refactor how this stuff is handled. Ultimately, I think that metadata should just be a bunch of (key, value) pairs where the key is some query, and there should be no more "crate store" trait (except for the "connect providers" method).

However, it occurs to me that once we get the red-green system, we could just have a single "metadata" node corresponding to the entire crate, and then let the red/green caching remember what the values of specific metadata queries were.

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Apr 24, 2017

After some discussion on IRC, @michaelwoerister and I were thinking that the best immediate way to make progress here is going to involve converting all CrateStore methods into queries. The main sticking point will be resolve, which we will leave 'as is' for now.

To that end, here is a checklist of CrateStore methods. Let's see if we can convert them all to queries. I've checked some off that probably don't make sense at this juncture (or ever).

Remaining

  • fn crates(&self) -> Vec<CrateNum>;

Resolve and elsewhere in rustc?

Rename these methods to {name}_untracked in CrateStore, add queries to TyCtxt, convert the compiler to use the query and change resolve to using {name}_untracked

Transitioned

??

  • fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, link_meta: &LinkMeta, reachable: &NodeSet) -> EncodedMetadata;
  • fn metadata_encoding_version(&self) -> &[u8];
  • fn def_key(&self, def: DefId) -> DefKey;
    • def-id is just a canonicalized def-key and def-path, so this is an immutable property or else def-id would be different
  • fn def_path(&self, def: DefId) -> hir_map::DefPath;
    • see above
  • fn def_path_hash(&self, def: DefId) -> u64;
    • see above
  • fn def_path_table(&self, cnum: CrateNum) -> Rc<DefPathTable>;
    • see above
  • fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>; -- used in resolve
  • fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro; -- used in resolve
  • fn export_macros(&self, cnum: CrateNum); -- used in resolve
  • fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem; -- used in resolve
  • fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
  • fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>; - deferred to incremental: Hide lang_items behind a query in the TyCtxt #44190
  • fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>; - deferred to incremental: Hide lang_items behind a query in the TyCtxt #44190

@nikomatsakis
Copy link
Contributor

cc @cramertj @aochagavia -- you interested in tackling some of these? In some cases, queries actually exist already, and we just have to convert code to use them exclusively (e.g., is_foreign_item)

@nikomatsakis nikomatsakis added E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. labels Apr 24, 2017
@nikomatsakis
Copy link
Contributor

Mentoring instructions: The current step in resolving this is to move methods from the CrateStore trait and convert them into queries. The CrateStore trait serves as the "abstract interface" to the metadata -- it is defined in librustc, but implemented in librustc_metadata (exactly once, though there exists a second, dummy impl).

The idea then for a PR is to:

  • pick a method in the list
  • find uses of it:
    • if it is used in resolve, you can skip it for now and move on to another
  • otherwise:

@hackeryarn
Copy link
Contributor

I would love to get started on this. I will try to have an implementation for one of the items up in a couple days to align on direction.

@cramertj
Copy link
Member

Yeah, I can take a look at some of these tonight or tomorrow.

@hackeryarn
Copy link
Contributor

@cramertj I was planning on taking a look at the couple of the first ones today or tomorrow morning if you want to start a little further down the list.

Wouldn't want us stepping on each other's toes 😄

@cramertj
Copy link
Member

@achernyak Sounds great! Thanks.

@nikomatsakis
Copy link
Contributor

@cramertj @achernyak great! =)

@michaelwoerister
Copy link
Member Author

However, it occurs to me that once we get the red-green system, we could just have a single "metadata" node corresponding to the entire crate, and then let the red/green caching remember what the values of specific metadata queries were.

One downside of this approach, that came up during discussion, is that this would mean that we would have to load and deserialize each value just to find out if it has changed or not. Currently we directly load fingerprints to do this check.

@arielb1
Copy link
Contributor

arielb1 commented Apr 25, 2017

One downside of this approach, that came up during discussion, is that this would mean that we would have to load and deserialize each value just to find out if it has changed or not. Currently we directly load fingerprints to do this check.

Can't we save fingerprints in the parent crate metadata and copy the expected fingerprints into the child crate IC-info?

@nikomatsakis
Copy link
Contributor

@arielb1

Can't we save fingerprints in the parent crate metadata and copy the expected fingerprints into the child crate IC-info?

Yes, we could presumably special-case this code somewhat, though I think that -- for this to really work well -- we would want to align the metadata and queries so that they have a 1:1 relationship (refactoring the CrateStore methods away gets us closer to this vision). That said, I've been wondering if we will ever want more stability in our metadata format, in which case tying it directly to the current set of queries may or may not be wise. Probably not worth worrying about right now.

arielb1 pushed a commit to arielb1/rust that referenced this issue Apr 27, 2017
query for describe_def

Resolves `fn describe_def(&self, def: DefId) -> Option<Def>;` of rust-lang#41417.

r? @nikomatsakis I would greatly appreciate a review. I hope I covered everything described in the pr.
frewsxcv added a commit to frewsxcv/rust that referenced this issue Apr 27, 2017
query for describe_def

Resolves `fn describe_def(&self, def: DefId) -> Option<Def>;` of rust-lang#41417.

r? @nikomatsakis I would greatly appreciate a review. I hope I covered everything described in the pr.
frewsxcv added a commit to frewsxcv/rust that referenced this issue Apr 28, 2017
query for describe_def

Resolves `fn describe_def(&self, def: DefId) -> Option<Def>;` of rust-lang#41417.

r? @nikomatsakis I would greatly appreciate a review. I hope I covered everything described in the pr.
@cramertj
Copy link
Member

Many of these methods don't take DefId as an argument, but the provide macro at the top of src/librustc_metadata/cstore_impl.rs assumes that they do-- should I change the macro to allow specifying the input type, or is there another way you think I should provide those methods?

@nikomatsakis
Copy link
Contributor

@cramertj good point. I'd prefer to change the macro, but I'm not sure how easy that would be to do. I guess you can leverage the Key trait (not public, but it could be -- and in fact on one of my upcoming branches I made it public) in the maps crate to extract the krate number from any kind of legal key.

@hackeryarn
Copy link
Contributor

@cramertj in the short term, I think most of these can be handled but using a tuple like const_eval_dep_node does, or by pulling the needed information off the TyCtxt itself. For example, for def_span the Session is available on TyCtxt and that's actually how it was passed in &tcx.sess.

Also CrateNumber, which is the other major one, is supported by the query already i.e. typecheck_item_body takes a CrateNumber already.

bors added a commit that referenced this issue Apr 30, 2017
query for def_span

Resolves `fn def_span(&self, sess: &Session, def: DefId) -> Span;` of  #41417.

I had to change the query name to `def_sess_span` since `ty::TyCtxt` already has a method `def_span` implemented.

This also will probably have merge conflicts with  #41534 but I will resolves those once it's merged and wanted to start a code review on this one now.

r? @eddyb
@hackeryarn
Copy link
Contributor

hackeryarn commented Apr 30, 2017

I am making this comment as a way to track the conversions that proved problematic.

Used in resolve:

  • fn visibility(&self, def: DefId) -> ty::Visibility;
  • fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;

Unreachable tcx in calls. Call sights should be converted on-demand computations:

  • fn item_generics_cloned(&self, def: DefId) -> ty::Generics;

@nikomatsakis
Copy link
Contributor

@cramertj will do! I'll do a sweep with what I can find, and you can compare.

@nikomatsakis
Copy link
Contributor

Updated -- I tagged with all the PRs.

@cramertj
Copy link
Member

cramertj commented May 5, 2017

@nikomatsakis Great, thanks! It looks like almost all the rest are ones I put off because they don't have a single DefId argument. I'll plan to have a PR out tonight updating the provide macro to allow for other arguments.

frewsxcv added a commit to frewsxcv/rust that referenced this issue May 11, 2017
More Queries for Crate Metadata

This covers a little bit of clean up and the following parts of rust-lang#41417:
* `fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;`
* `fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;`
* `fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;`
* `fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;`
* ` fn is_foreign_item(&self, did: DefId) -> bool;`
* `fn is_exported_symbol(&self, def_id: DefId) -> bool;`

r? @nikomatsakis
frewsxcv added a commit to frewsxcv/rust that referenced this issue May 11, 2017
More Queries for Crate Metadata

This covers a little bit of clean up and the following parts of rust-lang#41417:
* `fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;`
* `fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;`
* `fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;`
* `fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;`
* ` fn is_foreign_item(&self, did: DefId) -> bool;`
* `fn is_exported_symbol(&self, def_id: DefId) -> bool;`

r? @nikomatsakis
@hackeryarn
Copy link
Contributor

hackeryarn commented May 30, 2017

@cramertj from looking into this a bit. It looks like the windows error in your other pr was thrown by the implementation for is_dllimport_foreign_item. Have you tried removing that and seeing if everything else works?

I think the last of this issue is blocked by #41780

@nikomatsakis
Copy link
Contributor

@achernyak

I think the last of this issue is blocked by #41780

that's a closed PR? Is that what you meant to link to?

@hackeryarn
Copy link
Contributor

hackeryarn commented May 30, 2017

@nikomatsakis, that PR was closed due to a Windows build issue in #41766 which was taking too long to resolved. I believe @cramertj closed both of these to not keep the PRs open for an extended period of time.

@cramertj
Copy link
Member

Finally getting back to this-- I'm opening a PR with a few new ones. I also looked at lang_items and missing_lang_items. I discovered those are currently calculated before tcx is made and then stored in a field. They're accessed all over the place, so that'll require a large-scale refactor. I'm not sure how often the list of lang items changes, but if we want incremental results to be valid across lang-item-list changes, the lang-item list will need to be broken up similar to what @nikomatsakis did for the region maps (#41662).

@michaelwoerister
Copy link
Member Author

@cramertj Anything that is wrapped in a Tracked (like lang_items) you don't need to worry about. Those things can only be accessed when specifying a DepNode (or at least one has to explicitly work around tracking if it's really necessary).

@cramertj
Copy link
Member

cramertj commented Jun 13, 2017

@michaelwoerister Oh, good to know. We should check those ones off on the list, then. I'll put together a list of them when I get a chance later today.

@michaelwoerister
Copy link
Member Author

@cramertj Excellent, thank you!

@cramertj
Copy link
Member

Out of the list above, I see these included as Tracked:

  • lang_items
  • missing_lang_items
  • native_libraries
  • implementations_of_trait above is backed by the get_implementations_for_trait method on cdata, which appears to just be a filter on top of CrateRoot.impls, which is Tracked<LazySeq<TraitImpls>>. I'm not sure whether or not to count this-- I guess it depends on whether or not we want to directly track the filtered result of get_implementations_for_trait separately from the overall list of trait impls. I'd expect we probably would want to. If that's the case, it should not be checked off until this has been done.
  • exported symbols
  • dllimport_foreign_items is Tracked, but like implementations_of_trait I'd expect we probably still want to track is_dllimport_foreign_item (which should be unchecked, BTW, as the linked PR for it was closed, not merged).
  • panic_strategy
  • dylib_dependency_formats

bors added a commit that referenced this issue Jun 16, 2017
@cramertj
Copy link
Member

item_generics_cloned should also be checked off -- it's used in librustc/middle/resolve_lifetime.rs, and only has access to a Session.

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 27, 2017
@kennytm
Copy link
Member

kennytm commented Aug 16, 2017

Could the list in #41417 (comment) be updated? #41766 was closed, and some are done in later PRs. Specifically,

Also,

bors added a commit that referenced this issue Sep 7, 2017
Migrate a slew of metadata methods to queries

This PR intends to make more progress on #41417, knocking off some low-hanging fruit.

Closes #44190
cc #44137
bors added a commit that referenced this issue Sep 8, 2017
Migrate a slew of metadata methods to queries

This PR intends to make more progress on #41417, knocking off some low-hanging fruit.

Closes #44190
cc #44137
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-incr-comp Area: Incremental compilation C-enhancement Category: An issue proposing an enhancement or a PR with one. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
Projects
None yet
Development

No branches or pull requests

7 participants