-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for RFC 1977: public & private dependencies #44663
Comments
Maybe it's useful to look at how this problem is approached in Haskell. Here is an example of a subtle issue that occurs with private dependencies: Btw, I found it through this post: http://harry.garrood.me/blog/purescript-why-bower/ |
Would Rust2018 be a good opportunity to make the braking changes to |
Maybe. Though such changes should be designed and proposed soon, have an easy migration path, and preferably only affect a minority of existing crates. |
Thought I just had related to ecosystems like [dependencies]
futures = { version = "10.17", public = false }
futures-core = { version = "1.2", public = true } But then, in code you would never import items from the "core" crate, instead you would simply have public APIs that return types which have been re-exported through the "facade" from the "core" crate and rely on the compiler to warn you if you accidentally use something that didn't originate in the "core" crate. |
I don't quite understand something about your example. Can you elaborate on what the |
@Eh2406 the setup's a little annoying to just explain, so here's a full compiling set of example crates: https://github.com/Nemo157/rust-44663-facade-example In this example Now So, to have the compiler enforce this restriction the developers of |
I'd like to work on this. |
Thanks for offering to work on this! @alexcrichton, do you have any mentoring advice? I can at any time get a branch ready for the resolver part of cargo, it will be good enough to start experimentation, although not good enough to be ready to stabilize. |
Sure! @Aaron1011 so this is split roughly into two features, one being rustc knowing what crates are in the "public interface" and a second being the support in Cargo's resolver to make various decisions differently. Are you interested in one of those in particular? |
@alexcrichton: I've started working on the rustc part in a branch: https://github.com/Aaron1011/rust/commits/feature/pub-priv-dep, and I plan to submit a (WIP) PR soon. I might also be interested in working on the cargo part as well. |
@Aaron1011 please cc me when you make that PR. I know nothing about the internals of Rust, so will be of no help, but I do want to follow the discussion. I will redouble my efforts to get the Cargo's resolver part mergeable. I have been enjoying ( and hating ) it because it is the hardest algorithmic problem I have ever worked on. I would be happy for some help, perhaps a new perspective will get me un-stuck. |
@Aaron1011 ok and it seems like you're off to a great start! I'd be up for reviewing that PR, and if you've got any questions along the way just let me know |
There was another usecase for this mentioned on i.rl.o, if Similarly, if you're self-hosting documentation for a crate somewhere you may want to be able to generate a documentation bundle including the crate and all its public dependencies so that it is fully self-contained. |
Implement public/private dependency feature Implements #44663 The core implementation is done - however, there are a few issues that still need to be resolved: - [x] The `EXTERNAL_PRIVATE_DEPENDENCY` lint currently does notthing when the `public_private_dependencies` is not enabled. Should mentioning the lint (in an `allow` or `deny` attribute) be an error if the feature is not enabled? (Resolved- the feature was removed) - [x] Crates with the name `core` and `std` are always marked public, without the need to explcitily specify them on the command line. Is this what we want to do? Do we want to allow`no_std`/`no_core` crates to explicitly control this in some way? (Resolved - private crates are now explicitly specified) - [x] Should I add additional UI tests? (Resolved - added more tests) - [x] Does it make sense to be able to allow/deny the `EXTERNAL_PRIVATE_DEPENDENCY` on an individual item? (Resolved - this is implemented)
This implements the crates.io side of rust-lang/rust#44663 This is fully backwards-compatible - 'public' will default to 'false' for old versions of Cargo that don't include it in their manifest
I think the decision to require a key ( At the same time I understand that |
I can understand the desire for this to not require an MSRV change. Part of the problem is historical, that the original feature was designed to be very different than what we have today. Part of the problem is not require an MSRV bump is very out of the ordinary with the only cases I can think of being However, I don't feel a redundant field would be appropriate. We could consider dropping the nightly requirement now so we at least have a couple release lead time on this problem (with the risk of stabilzation being even further out than that with the state of the compiler side). I do think this conversation represents a deeper problem: a push towards stagnation due to MSRV. I'm working on the update for the MSRV resolver RFC that I'm hoping will help lay out a better path for MSRV policies that can help push us out of this stagnation, shifting costs to those that need old versions rather than being old Rust versions being a millstone around the communities neck. |
I started on this because I thought public/private deps would weigh on the ability of a library crate to be linked dynamically within a larger build graph, but I don't believe that to be true anymore. So if the cost of not being able to adopt this feature is only local to a crate, it doesn't matter that much. That being said, I still think we can do better in the future.
I can throw any random key in my Cargo.toml and will only get a warning that it wasn't used. That is, I believe, what cargo should have continued doing with the Your RFC gets this right, by phasing in enforcement as a warning (with opt-in, even) and turning it into a hard error over an edition. I can think of other approaches that use this "two factor" opt-in idea to get away without waiting for an edition.
Yes, I think we should do that in any case.
Respectfully, I think we still have to take version skew issues seriously in the design of our package manager. Shifting the cost to the users who want or need the most stability that might help motivate updates in some instances, but in others it will just make Rust a less viable option. Having access to recent versions of ecosystem crates is a security matter. There is a fundamental tension between stability and stagnation. How confident can you be that your MSRV RFC will modify the revealed preferences of ecosystem libraries and their users? There will always be a cost to updating unless we take a very hard line stance on backward compatibility, which historically we have not been willing to do (and I don't think we should). |
Its not as simple as "it was ignored before so it should be fine to not error while unstable". Depending on how the key changes behavior, ignoring it would run counter to the users intention. While we can't go back in time to ensure the key was never allowed, the unstable period offers us the chance to ensure users will get a hard error, telling them that the feature they are trying to use is unsupported and cargo cannot fulfill their intent. This also discourages users mixing nightly and stable code where an upgrade of stable can break them because the stabilized form of the feature is different. To balance this out, I was the one who advocated for |
We discussed the blocking feature gate in today's cargo meeting and I've posted rust-lang/cargo#13307 to clarify the documentation to encourage more non-blocking gates and I've opened rust-lang/cargo#13308 to change our feature gate here. |
Thanks @epage, I really appreciate your receptiveness here! |
See #121710 (comment). The non-blocking gate |
Probably worth keeping both opt-ins. |
@rustbot labels +E-help-wanted If this item is going to make it into Rust 2024 (and it's OK if it doesn't), we're going to need some help to check off the remaining items above. As @davidtwco describes:
We'll mark this as |
@rustbot labels -A-edition-2024 +A-maybe-future-edition Without an owner driving this work forward, this is looking unlikely for this edition, so let's drop that label and mark this as a possibility for a future edition. |
We decided to remove this from Rust 2024 here: - rust-lang/rust#44663 (comment)
Here is proof why We should write this [package]
name = "foo"
version = "1.0"
[dependencies]
bar = "1.0"
baz = "1.0"
quux_from_bar = { package = "quux", from = ["bar"] }
quux_from_baz = { package = "quux", from = ["baz"] } (Of course, it is possible just to specify versions for Then we should call So, I hope I provided proof explaining why There are 2 other alternatives:
So here is my trilemma: either we should support Of course, the second approach is the worst, because it pushes a lot of work on all maintainers |
@safinaskar let's be careful in setting up false dichotomies. Those are not the only two options. It would be great to have a path for improving this behavior. However, that idea was marked as a future possibility for a reason. In design and implementation work, we need to stay focused on the minimal set or else we'll never be able to make progress. The previous RFC tried to solve this problem, in a different way, and that was responsible for this RFC languishing for years and precluded us from noticing other issues that blocked this effort (the lint implementation). Let's separate out the conversation of supporting public/private dependencies in the first place from how we can take advantage of it in the future. |
Summary
RFC (original, superseded): #1977
RFC: #3516
Cargo tracking issue: rust-lang/cargo#6129
Issues: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AF-public_private_dependencies
Cargo issues: https://github.com/rust-lang/cargo/issues?q=is%3Aopen+is%3Aissue+label%3AZ-public-dependency
Documentation: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#public-dependency
This feature enables the ability to track which dependencies are publicly exposed through a library's interface. It has two sides to the implementation: rustc (lint and
--extern
flag), and cargo (Cargo.toml
syntax, and passing--extern
flags).This feature was originally specified in rust-lang/rfcs#1977, but was later down-scoped in rust-lang/rfcs#3516.
About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Discussion comments will get marked as off-topic or deleted.
Repeated discussions on the tracking issue may lead to the tracking issue getting locked.
Unresolved Questions
Steps
exported_private_dependencies
lint only take effect in innermost dependency #119428private-dependency
bug #122757public
dependency configuration with workspace deps cargo#12817exported-private-dependencies
lints to libraries cargo#13039--public
support forcargo add
cargo#13037cargo add
should check public transitive dependencies when auto-picking a version cargo#13038cargo metadata
cargo#14502Command to update Cargo.lock to minimal versions (Command to update Cargo.lock to minimal versions cargo#4100)Makecargo publish
use the minimal versions allowed by Cargo.tomlcargo fix
support forexported-private-dependencies
cargo#13095exported-private-dependencies
allow
-by-default pre-2024 anddeny
-by-default in 2024+ / in the 2024-compatibility lint groupallow
orwarn
(context from zulip)Non-blocking further improvements
Cargo.toml
context toexported-private-dependencies
lints cargo#13096Changes from RFC
cc @rust-lang/cargo @epage
The text was updated successfully, but these errors were encountered: