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

Treat dependencies of proc-macro crates like normal dependencies #69976

Closed
wants to merge 4 commits into from

Conversation

Aaron1011
Copy link
Member

Split out from #68941

Previously, we special-cased dependencies of proc-macro crates: we didn't load metadata for them, and we excluded them from the sysroot.

With #68941, this will no longer work - we may need to deserialize Spans from proc-macro crates and their dependencies, which requires having metadata available.

This PR removes the special handling of proc-macro crates in resolve_crate_deps, and adjusts the sysroot generation in bootstrap to only exclude build scripts, not proc-macro dependencies.

I don't know of a way to write a test for this. However, the ui-fulldeps testsuite implicitly tests this, since it has several tests containing extern crate rustc (which ends up loading proc-macro dependencies from the sysroot).

@rust-highfive
Copy link
Collaborator

r? @Mark-Simulacrum

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 13, 2020
@Aaron1011
Copy link
Member Author

cc @petrochenkov

// instead of relying on this check.
if !is_build_script {
deps.push((filename.to_path_buf(), false));
}
Copy link
Member

Choose a reason for hiding this comment

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

Why does this need a different check from the above crate_types.iter().any(|t| t == "proc-macro")?

Generally it also feels wrong or at least odd that we're putting proc macros seemingly twice, once into the host and once into the target directory. That feels reminiscent of a flag @Zoxc, IIRC, added (-Zdual-macros, or so, I don't recall exactly).

Copy link
Member Author

Choose a reason for hiding this comment

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

The crate_types.iter().any(|t| t == "proc-macro") check is looking for proc macro crates. This check is looking for dependencies of proc-macros, which may not be proc-macros themselves.

For example, suppose we have the dependency graph normal_crate_one -> proc_macro_crate -> normal_crate_two. The crate normal_crate_two is not a proc macro crate - but since it's a dependency of proc_macro_crate, it will end up in the host dir.

@pietroalbini
Copy link
Member

Had to kill the PR build to get CI back up and running, sorry for the trouble.


// Note that we need to resolve deps for proc-macro crates (just like normal crates)
// since we may need to decode `Span`s that reference the `CrateNums`
// of transitive dependencies
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: this comment looks unnecessary, like "look, nothing unusual is happening here, move along". It's the removed special case that required a comment, but didn't have it.

Copy link
Member Author

Choose a reason for hiding this comment

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

We still special-case proc macros is some places, so I thought it was worthwhile to explain why we do this (in case someone ever thinks of re-adding this an an optimization).

Copy link
Member

Choose a reason for hiding this comment

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

There's nothing here about proc macros anymore though? I would agree with @petrochenkov that this comment seems more confusing than helpful. We should have a test that ensures this doesn't get re-added?

@Zoxc
Copy link
Contributor

Zoxc commented Mar 13, 2020

With #68941, this will no longer work - we may need to deserialize Spans from proc-macro crates and their dependencies, which requires having metadata available.

Why do we need to do this? Can their Spans appear in proc-macro output? or is there some other reason for this?

@Aaron1011
Copy link
Member Author

It turns out that this bootstrap change causes us to include build-dependencies of std (cc and autocfg) when we copy the libstd artifacts into the sysroot. However, cc and autocfg also get included in the sysroot when we copy rustc artifacts, so we end up with multiple versions of cc and autocfg in the sysroot.

This makes it impossible to write extern crate cc when using the sysroot - instead of the usual "this crate is being loaded from the sysroot" message on stable, you get a mesage about incompatible versions of cc.

On one hand, there's no reason to be using cc or autocfg from the sysroot - you can always add them to your Cargo.toml.

On the other hand, this will give a confusing error message for anyone who writes extern crate cc without first adding it to their Cargo.toml.

At the moment, we have no way of filtering out build dependencies from the sysroot when inspecting Cargo's JSON output - they cannot be distinguished from non-build dependencies, which we do want to include.

We have two options:

  1. Accept the sub-optimal error message, and adjust the run-make-fulldeps/sysroot-crates-are-unstable test to accept this message for cc and autocfg.
  2. Hardcode exclusions for cfg and autocfg when we copy libstd artifacts into the sysroot during bootstrap. All dependency changes to libstd are carefully audited, so this shouldn't be too much of a maintence burden.

The long-term fix is for Cargo to provide more information in its json output, so that we can distinguish between build-dependencies and normal dependencies.

@Aaron1011
Copy link
Member Author

Aaron1011 commented Mar 13, 2020

Why do we need to do this? Can their Spans appear in proc-macro output? or is there some other reason for this?

@Zoxc: This issue is unrelated to proc-macro output. It has to do with the actual identifiers of proc-macro functions (e.g. the foo in #[proc_macro_attr] fn foo()). See #68941 (comment) for more details.

I opened this because we were hitting this case in #68941 when compiling rustc_span with the stage1 compiler - I haven't tracked down exactly what's happening, but I suspect that we're re-exporting a proc macro.

See also #68941 (comment)

@bjorn3
Copy link
Member

bjorn3 commented Mar 13, 2020

I don't think it is useful to show ever show the span of a proc-macro function. The user of the proc-macro probably doesn't want to modify or inspect the proc-macro.

@rust-highfive

This comment has been minimized.

@Aaron1011
Copy link
Member Author

Aaron1011 commented Mar 13, 2020

@bjorn3: I disagree. While it might be unusual for an error to do so, I think we should treat proc macros as just another kind of definition - just as we might show " defined here" or " defined here", we could potentially show "<proc_macro> defined here".

To be clear, whether or not to show the definition of a proc macro would be determined on a per-diagnostic basis. However, unless loading proc-macro dependency metadata has a negative performance impact, I think we should make this change. It will allow any future use of proc-macro Idents to work as expected, without committing us to use them in any particular place.

@JohnCSimon JohnCSimon added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 28, 2020
@joelpalmer joelpalmer added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 6, 2020
@joelpalmer joelpalmer added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 14, 2020
@Dylan-DPC-zz
Copy link

@Aaron1011 if you can fix the failing tests we can proceed with this

@crlf0710 crlf0710 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 24, 2020
@crlf0710 crlf0710 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 2, 2020
@joelpalmer joelpalmer added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 12, 2020
@Elinvynia Elinvynia added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 20, 2020
Previously, we were excluding them since we didn't need to load their
metadata. This will no longer work - we now include everything from the
'host' directory except for build-scripts.
@Aaron1011
Copy link
Member Author

@Dylan-DPC: Fixed

@Dylan-DPC-zz Dylan-DPC-zz 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 May 20, 2020
@Dylan-DPC-zz
Copy link

@Mark-Simulacrum this is ready for review

@Mark-Simulacrum
Copy link
Member

Hardcode exclusions for cfg and autocfg when we copy libstd artifacts into the sysroot during bootstrap. All dependency changes to libstd are carefully audited, so this shouldn't be too much of a maintence burden.

I would prefer that we not give users any errors about sysroot crates if possible, and though these two particular crates are probably quite rare to hit on accident I would prefer to add them to a hardcoded list in bootstrap.

It's also a bit unclear to me -- the PR description says this was necessary for #68941 but that has since landed. I suspect what you meant is that #68941 won't really be useful if we're not loading dependency spans? Can you update the PR description?

@bors try @rust-timer queue

Also would like to gather performance diff of this change. I would also like to make sure that @petrochenkov is okay with this, as I'm not really all that familiar with the details of our resolution/crate loading implementation.

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion

@bors
Copy link
Contributor

bors commented May 22, 2020

⌛ Trying commit 9dc999e with merge 3bee93ff74bbd046a67c3acfa691de1399929ee2...

@bors
Copy link
Contributor

bors commented May 22, 2020

☀️ Try build successful - checks-azure
Build commit: 3bee93ff74bbd046a67c3acfa691de1399929ee2 (3bee93ff74bbd046a67c3acfa691de1399929ee2)

@rust-timer
Copy link
Collaborator

Queued 3bee93ff74bbd046a67c3acfa691de1399929ee2 with parent de6060b, future comparison URL.

@petrochenkov petrochenkov self-assigned this May 22, 2020
@petrochenkov
Copy link
Contributor

@Mark-Simulacrum

I suspect what you meant is that #68941 won't really be useful if we're not loading dependency spans?

#68941 is still useful without this, but incomplete, that PR has a stub producing dummy spans for proc macro crates.

@petrochenkov
Copy link
Contributor

I would also like to make sure that @petrochenkov is okay with this, as I'm not really all that familiar with the details of our resolution/crate loading implementation.

Loading spans from proc macro crates is suboptimal and long term it would be good to inline actually used spans from all build-time dependencies into crates built with their help somehow, but that may be a nontrivial optimization.
For the initial version of span/hygiene serialization I think we can keep the whole proc macro crates around just to retrieve spans from them, if performance allows it.

@petrochenkov petrochenkov removed their assignment May 22, 2020
@rust-timer
Copy link
Collaborator

Finished benchmarking try commit 3bee93ff74bbd046a67c3acfa691de1399929ee2, comparison URL.

@bjorn3
Copy link
Member

bjorn3 commented May 23, 2020

On average there seems to be a <1% regression.

@Elinvynia Elinvynia added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 3, 2020
@Mark-Simulacrum
Copy link
Member

The perf run had a bunch of crates fail to build (see the log at the bottom); e.g.

hyper-2 failed with:

     Checking futures-util v0.3.1                                                                                                                                            +
 error: /tmp/.tmpuivAPw/target/debug/deps/libfutures_macro-865b1fd2b529a20c.so: undefined symbol: _ZN11unicode_xid6tables16derived_property12XID_Continue17h1c47640b6319d252E+
   --> /home/collector/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.1/src/async_await/join_mod.rs:78:13                                                  +
    |                                                                                                                                                                        +
 78 |     pub use futures_macro::join;                                                                                                                                       +
    |             ^^^^^^^^^^^^^                                                                                                                                              +
                                                                                                                                                                             +
 error: aborting due to previous error                                                                                                                                       +
                                                                                                                                                                             +
 error: could not compile `futures-util`.                                                                                                                                    +
                                                                                                                                                                             +
 To learn more, run the command again with --verbose.                                                                                                                        +
 warning: build failed, waiting for other jobs to finish...                                                                                                                  +
 error: build failed                                                                                                                                                         +
                                                                                                                                                                             +
                                                                                                                                                                             +
  stdout=

Other have similar link failures. We can rerun perf if you think it was spurious, but it feels like errors like that are plausibly caused by this PR somehow?

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

Aaron1011 commented Jun 24, 2020

Closing in favor of #73706, which is much less invasive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.