You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cargo fix support for exported-private-dependencies #13095
rust-lang/rfcs#3516 calls for making exported-private-dependencies into an error in new editions. This means it needs to be machine-applicable so cargo fix can migrate it.
The problem is the most useful thing for a machine-applicable fix is to update Cargo.toml but rustc has no knowledge of that.
Proposed Solution
Intercept the message from rustc, before cargo fix (or the "machine applicable lints counter) sees this and add the machine-applicable content.
We have the code but not the dependency name. It'd be ugly and brittle but we could parse the dependency name out of "from private dependency '{name}' in public interface". We ship with rustc so we can make sure this stays up to date as rustc changes, though it'll cause CI failures.
Expectation
Parse the json blob, ensuring its a message and has the right code, extracting the dependency name, and constructing a machine applicable lint.
Depending on how replacements are encoded, we might need to add an item to children
Test to verify we can auto-fix code
Test the above with dependency renames
Test that the "run cargo fix" message shows up for these with cargo check.
Is it currently not supported to obtain the specific line number of a certain configuration item?
Give a example, I like to know the line of license and regex in the Cargo.toml.
It looks like this issue need this ability to fixed.
@Muscraft was going to add code to cargo to get the needed spans in a follow up to #13172. If you need it before, reach out to them for notes they have on the topic
@Muscraft was going to add code to cargo to get the needed spans in a follow up to #13172. If you need it before, reach out to them for notes they have on the topic
#13172 was merged recently. I'd to take a shot :-) .
Being machine applicable means that we always fix it which should only happen if it is definitively the right answer.
Is it?
If I have a impl From<foreign::ForeignError> for MyError accidentally, is the fix to make foreign public or to remove the impl? If removing the impl is a considered a breaking change, then there is only one answer. However, we could consider this more like `#[doc(hidden)]`` where the answer is "it depends".
Some additional options
We never move this to an error
We give this a long time as a warning, greatly reducing the impact of this being an error or maybe even being machine applicable
My 2c: I think making the dependencies public is the simplest both from Cargo's and the user's point of view - after the fix, they can (and should) audit their public dependencies and make private again whatever they want and then change the code based on what lints are emitted then. I would expect most crates to just accept what is public though and maybe later working on trimming that down.
I believe all instances where there was a dependency in public interface and we remove it from there, is a breaking change, so making everything in the public interface public is the only correct solution I see. If there were such cases and were automatically identifiable, the lint shouldn't fire there either. So I believe making the dependency public is definitively the right answer but the human also has a choice to evolve their API to remove the public dependency from there. Which strictly speaking they should do with a major bump, but as always, it's their choice.
At the end of the day, the fix as currently proposed just surfaces the current state, it doesn't add anything to the public API that wasn't there to begin with.
Ignoring/allowing/deleting specific implementations is something that only the user can do I think. If they decide to ignore a given impl because no one should use it, they can do that, but there's not way for anyone else to decide that I think.
I think it would be beneficial for this to be machine applicable even if it is a warning but I agree there is no rush to make this an error.
From my understanding, the compiler has different categories of fixes. "MachineApplicable" is if it is a definitive fix that can be applied without intervention. There are also "MaybeApplicable" which cargo fix does not apply today. What you are describing sounds like MaybeApplicable. I'd love for cargo fix to have an interactive mode where we can ask the user about MaybeApplicable but we are not there today.
I might have described it poorly, but reading the definitions, I do think making the dependencies public in Cargo.toml is MachineApplicable. The dependencies are already part of the public API and the fix just surfaces that into Cargo.toml without any semantic changes.
To me that's similar to e.g. how in 2024 edition, if let was changed to match because of earlier drops and people then manually verified and changed it back if they wanted to.
We provide a fix that keeps all semantics and if users decide their original intent was different from the current state, they make manual changes afterwards.
Activity
epage commentedon Dec 1, 2023
What we need is
Looking at the compiler message
{ "reason": "compiler-message", "package_id": "cargo-pub-priv 0.1.0 (path+file:///home/epage/src/personal/dump/cargo-pub-priv)", "manifest_path": "/home/epage/src/personal/dump/cargo-pub-priv/Cargo.toml", "target": { "kind": [ "lib" ], "crate_types": [ "lib" ], "name": "cargo-pub-priv", "src_path": "/home/epage/src/personal/dump/cargo-pub-priv/src/lib.rs", "edition": "2021", "doc": true, "doctest": true, "test": true }, "message": { "rendered": "warning: trait `FooTrait` from private dependency 'foo' in public interface\n --> src/lib.rs:11:1\n |\n11 | pub trait UseFoo: foo::FooTrait {}\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n", "children": [], "code": { "code": "exported_private_dependencies", "explanation": null }, "level": "warning", "message": "trait `FooTrait` from private dependency 'foo' in public interface", "spans": [ { "byte_end": 189, "byte_start": 158, "column_end": 32, "column_start": 1, "expansion": null, "file_name": "src/lib.rs", "is_primary": true, "label": null, "line_end": 11, "line_start": 11, "suggested_replacement": null, "suggestion_applicability": null, "text": [ { "highlight_end": 32, "highlight_start": 1, "text": "pub trait UseFoo: foo::FooTrait {}" } ] } ] } }We have the code but not the dependency name. It'd be ugly and brittle but we could parse the dependency name out of
"from private dependency '{name}' in public interface". We ship with rustc so we can make sure this stays up to date as rustc changes, though it'll cause CI failures.Expectation
childrencargo check.epage commentedon Dec 1, 2023
Depending on the details, we might need #13096
linyihai commentedon Jan 2, 2024
Is it currently not supported to obtain the specific line number of a certain configuration item?
Give a example, I like to know the line of
licenseandregexin the Cargo.toml.It looks like this issue need this ability to fixed.
And some discussiton can be found in zulip is it possible to include position data for
cargo metadataepage commentedon Jan 2, 2024
@Muscraft was going to add code to cargo to get the needed spans in a follow up to #13172. If you need it before, reach out to them for notes they have on the topic
linyihai commentedon Jan 12, 2024
#13172 was merged recently. I'd to take a shot :-) .
epage commentedon Jan 12, 2024
Note that I was referring to a PR they'll be working on after that PR. That PR doesn't have the functionality you would need.
iepathos commentedon Jan 11, 2026
Hi, I'm interested in working on this.
My current understanding of the approach to take based on the comments:
Does this align with what you had in mind?
epage commentedon Jan 12, 2026
Along with tests and ideally following the commit practices for tests at https://doc.crates.io/contrib/process/working-on-cargo.html#submitting-a-pull-request
epage commentedon Aug 10, 2026
Being machine applicable means that we always fix it which should only happen if it is definitively the right answer.
Is it?
If I have a
impl From<foreign::ForeignError> for MyErroraccidentally, is the fix to makeforeignpublic or to remove theimpl? If removing theimplis a considered a breaking change, then there is only one answer. However, we could consider this more like `#[doc(hidden)]`` where the answer is "it depends".Some additional options
mladedav commentedon Aug 26, 2026
My 2c: I think making the dependencies public is the simplest both from Cargo's and the user's point of view - after the fix, they can (and should) audit their public dependencies and make private again whatever they want and then change the code based on what lints are emitted then. I would expect most crates to just accept what is public though and maybe later working on trimming that down.
I believe all instances where there was a dependency in public interface and we remove it from there, is a breaking change, so making everything in the public interface public is the only correct solution I see. If there were such cases and were automatically identifiable, the lint shouldn't fire there either. So I believe making the dependency public is definitively the right answer but the human also has a choice to evolve their API to remove the public dependency from there. Which strictly speaking they should do with a major bump, but as always, it's their choice.
At the end of the day, the fix as currently proposed just surfaces the current state, it doesn't add anything to the public API that wasn't there to begin with.
Ignoring/allowing/deleting specific implementations is something that only the user can do I think. If they decide to ignore a given impl because no one should use it, they can do that, but there's not way for anyone else to decide that I think.
I think it would be beneficial for this to be machine applicable even if it is a warning but I agree there is no rush to make this an error.
epage commentedon Aug 26, 2026
From my understanding, the compiler has different categories of fixes. "MachineApplicable" is if it is a definitive fix that can be applied without intervention. There are also "MaybeApplicable" which
cargo fixdoes not apply today. What you are describing sounds likeMaybeApplicable. I'd love forcargo fixto have an interactive mode where we can ask the user aboutMaybeApplicablebut we are not there today.mladedav commentedon Aug 27, 2026
I might have described it poorly, but reading the definitions, I do think making the dependencies public in
Cargo.tomlisMachineApplicable. The dependencies are already part of the public API and the fix just surfaces that intoCargo.tomlwithout any semantic changes.To me that's similar to e.g. how in 2024 edition,
if letwas changed tomatchbecause of earlier drops and people then manually verified and changed it back if they wanted to.We provide a fix that keeps all semantics and if users decide their original intent was different from the current state, they make manual changes afterwards.
cjc0013 commentedon Oct 20, 2026
weihanglo commentedon Oct 21, 2026
@cjc0013 I folded your comment because it seems to be a LLM generated one. Per our policy comment should not be initially LLM generated: https://forge.rust-lang.org/policies/llm-usage.html.
You are welcome to comment with your own voice.