-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Re-implement proc-macro feature decoupling. #8028
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
I'm not sure how I feel about this, yet. I have a sense that there is too much spaghetti here, but I wanted to get some initial feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks great to me! I get the impression that the feeling of "spaghetti code" largely comes from how the backend of cargo is a bit sprawling and requires so many contexts to get going (or roughly equivalent). I didn't really get the impression that this made anything more spaghetti-like at least.
I do think though that this is an important feature to consider because affecting downloads can affect build times and such for users that have slower networks. I originally started typing out this comment once I realized that all optional dependencies are always downloaded. I thought that mean that crates.io optional dependencies were also downloaded, but I realize now due to the feature resolution in the resolver itself that's not quite the case. You won't always download every single optional dep, only those that are possibly reachable from your own feature set.
In any case this is my main worry with this change. It will increase the download size for builds, and if that increases too much I think it's a problem. That being said I think there's a few points in favor of this change:
- Having static "download all this" information is, in my opinion, better. It always felt weird that unit dependencies was a loop which felt like it was iterating to a fixed point. This feels better for build system integration, build system preparation, etc.
- It seems unlikly that we'll really increase download sizes all that much. The main download things to avoid are platform specific dependencies (already handled here), and features I've found tend to pull in fewer crates as a whole (plus many crate graphs are already relatively hefty).
- We could even argue that this is an optimization instead of a regression in that we're making future builds faster because it's faster to download a set of crates rather than individually. Furthermore this truly is downloading everything all at once rather than as the previous "iteratively download new frontiers of crates", so on faster connections this might honestly be faster since it fires off all requests all at once.
Overall while I wanted to write down some possible concerns I'm in favor of this approach and would be down for merging.
@@ -159,7 +173,7 @@ fn resolve_with_registry<'cfg>( | |||
true, | |||
)?; | |||
|
|||
if !ws.is_ephemeral() { | |||
if !ws.is_ephemeral() && ws.require_optional_deps() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was initially curious as to what's going on here, but this seems like it's connected to weirdness around cargo install
.
Honestly I've entirely lost track of why cargo install
is so weird at this point. IIRC though require_optional_deps
was a -Z
flag as well we want to have work on some day, so this raises a bit of a red flag with me in that it could be something we accidentally forget is connected to the -Z
flag perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea it is funky, and I have to look it up every time I come across it.
cargo install
disables require_optional_deps
so that people who mirror a registry (like with a directory registry) don't need to have every optional dependency on disk (only the enabled ones). You can see the original motivation in #3369.
-Zavoid-dev-deps
is another way to disable require_optional_deps
, to get equivalent behavior with other commands, and was added much later.
I'm pretty sure we do not want to write Cargo.lock
in this mode, since it will be incomplete, and I think this has just been a pre-existing bug. But nothing really used it, so it didn't really matter or get noticed.
I changed it so that I could use resolve_ws
in the "yank" check for cargo install
, because I didn't want to trigger downloads, and didn't need the full power of resolve_ws_with_opts
. There are some comments above that I removed explaining this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok that sounds reasonable enough. Not great I think for the future of -Zavoid-dev-deps
, but hey that's a problem for another day.
let specs = opts | ||
.spec | ||
.iter() | ||
.map(|spec| PackageIdSpec::parse(spec)) | ||
.collect::<CargoResult<Vec<_>>>()?; | ||
let features = FeatureResolver::resolve( | ||
let ws_resolve = ops::resolve_ws_with_opts( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come this changed from resolve_ws
to resolve_ws_with_opts
?
I feel like we keep trying to move everything over to resolve_ws
, but things seem to oscillate between the two methods over tiem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched it so that it could reuse the code for building the feature resolver and downloading dependencies. Otherwise, that would need to be duplicated here if it continued to use resolve_ws
.
FWIW, I'd really like to completely change how cargo clean -p
works some day. This technique of trying to guess what the filename hash is just too cumbersome and fragile, and doesn't always work. I hope that we can get some on-disk metadata to sufficiently track it so that cargo clean
doesn't need to do all this silliness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm ok. We may want to add a helper method to "download everything necessary" at some point, but seems reasonable enough for now.
So I'm personally ok r+'ing this as-is. Do you want to mull this over some more though? |
I think I'd like to go ahead with this. I think overall it is better than the previous approach. There's a couple calls to |
@bors: r+ Ok! |
📌 Commit 944f504 has been approved by |
☀️ Test successful - checks-azure |
Update cargo. 8 commits in 7019b3ed3d539db7429d10a343b69be8c426b576..8a0d4d9c9abc74fd670353094387d62028b40ae9 2020-03-17 21:02:00 +0000 to 2020-03-24 17:57:04 +0000 - Re-implement proc-macro feature decoupling. (rust-lang/cargo#8028) - Remove unused transitive dependencies: miniz_oxide, adler32 (rust-lang/cargo#8023) - Fix bug with -Zfeatures=dev_dep and `check --profile=test`. (rust-lang/cargo#8027) - Remove Config from CompileOptions. (rust-lang/cargo#8021) - Add `rustless.org` to documented blocklist. (rust-lang/cargo#7922) - Print colored warnings when build script panics (rust-lang/cargo#8017) - Do not supply --crate-version flag to rustdoc if present in RUSTDOCFLAGS (rust-lang/cargo#8014) - Add proc-macro to index, and new feature resolver. (rust-lang/cargo#8003)
Update cargo. 8 commits in 7019b3ed3d539db7429d10a343b69be8c426b576..8a0d4d9c9abc74fd670353094387d62028b40ae9 2020-03-17 21:02:00 +0000 to 2020-03-24 17:57:04 +0000 - Re-implement proc-macro feature decoupling. (rust-lang/cargo#8028) - Remove unused transitive dependencies: miniz_oxide, adler32 (rust-lang/cargo#8023) - Fix bug with -Zfeatures=dev_dep and `check --profile=test`. (rust-lang/cargo#8027) - Remove Config from CompileOptions. (rust-lang/cargo#8021) - Add `rustless.org` to documented blocklist. (rust-lang/cargo#7922) - Print colored warnings when build script panics (rust-lang/cargo#8017) - Do not supply --crate-version flag to rustdoc if present in RUSTDOCFLAGS (rust-lang/cargo#8014) - Add proc-macro to index, and new feature resolver. (rust-lang/cargo#8003)
This is essentially a rewrite of #8003. Instead of adding proc-macro to the index, it uses a strategy of downloading all packages before doing feature resolution. Then the package can be inspected for the proc-macro field.
This is a fairly major change. A brief overview:
PackageSet
now has adownload_accessible
method which tries to download a minimal set of every accessible package. This isn't very smart right now, and errs on downloading too much. In most cases it should be the same (or nearly the same) as before. It downloads extra in the following cases:[target]
dependencies checks both host and target for every dependency. I could tighten that up a little so build dependencies only check for the host, but it would add some complexity and I wanted to get feedback first.