From a769f7faaeca4ddc6b7caab23bef590d982274fc Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 12 Feb 2026 14:41:57 -0600 Subject: [PATCH 01/13] chore: Start template --- text/0000-used-deps.md | 103 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 text/0000-used-deps.md diff --git a/text/0000-used-deps.md b/text/0000-used-deps.md new file mode 100644 index 00000000000..fdc40810e86 --- /dev/null +++ b/text/0000-used-deps.md @@ -0,0 +1,103 @@ +- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) +- Start Date: (fill me in with today's date, YYYY-MM-DD) +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +## Summary +[summary]: #summary + +One paragraph explanation of the feature. + +## Motivation +[motivation]: #motivation + +Any changes to Rust should focus on solving a problem that users of Rust are having. +This section should explain this problem in detail, including necessary background. + +It should also contain several specific use cases where this feature can help a user, and explain how it helps. +This can then be used to guide the design of the feature. + +This section is one of the most important sections of any RFC, and can be lengthy. + +## Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: + +- Introducing new named concepts. +- Explaining the feature largely in terms of examples. +- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible. +- If applicable, provide sample error messages, deprecation warnings, or migration guidance. +- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. +- Discuss how this impacts the ability to read, understand, and maintain Rust code. Code is read and modified far more often than written; will the proposed feature make code easier to maintain? + +For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms. + +## Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +This is the technical portion of the RFC. Explain the design in sufficient detail that: + +- Its interaction with other features is clear. +- It is reasonably clear how the feature would be implemented. +- Corner cases are dissected by example. + +The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. + +## Drawbacks +[drawbacks]: #drawbacks + +Why should we *not* do this? + +## Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +- Why is this design the best in the space of possible designs? +- What other designs have been considered and what is the rationale for not choosing them? +- What is the impact of not doing this? +- If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain? + +## Prior art +[prior-art]: #prior-art + +Discuss prior art, both the good and the bad, in relation to this proposal. +A few examples of what this can include are: + +- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? +- For community proposals: Is this done by some other community and what were their experiences with it? +- For other teams: What lessons can we learn from what other communities have done here? +- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. + +This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. +If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. + +Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. +Please also take into consideration that rust sometimes intentionally diverges from common language features. + +## Unresolved questions +[unresolved-questions]: #unresolved-questions + +- What parts of the design do you expect to resolve through the RFC process before this gets merged? +- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? +- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC? + +## Future possibilities +[future-possibilities]: #future-possibilities + +Think about what the natural extension and evolution of your proposal would +be and how it would affect the language and project as a whole in a holistic +way. Try to use this section as a tool to more fully consider all possible +interactions with the project and language in your proposal. +Also consider how this all fits into the roadmap for the project +and of the relevant sub-team. + +This is also a good place to "dump ideas", if they are out of scope for the +RFC you are writing but otherwise related. + +If you have tried and cannot think of any future possibilities, +you may simply state that you cannot think of anything. + +Note that having something written down in the future-possibilities section +is not a reason to accept the current or a future RFC; such notes should be +in the section on motivation or rationale in this or subsequent RFCs. +The section merely provides additional information. From 93b717af7240af6b7f626cacb3901fa13529f55a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 13 Feb 2026 08:16:17 -0600 Subject: [PATCH 02/13] Initial draft --- text/0000-used-deps.md | 250 +++++++++++++++++++++++++++++++---------- 1 file changed, 193 insertions(+), 57 deletions(-) diff --git a/text/0000-used-deps.md b/text/0000-used-deps.md index fdc40810e86..e05d416f352 100644 --- a/text/0000-used-deps.md +++ b/text/0000-used-deps.md @@ -1,103 +1,239 @@ -- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) -- Start Date: (fill me in with today's date, YYYY-MM-DD) +- Feature Name: `used-deps` +- Start Date: 2026-02-12 - RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) ## Summary [summary]: #summary -One paragraph explanation of the feature. +Extend Cargo's dependency specifications so users can mark that a dependency is used, independent of what [unused externs](https://doc.rust-lang.org/nightly/rustc/json.html#unused-dependency-notifications) says. ## Motivation [motivation]: #motivation -Any changes to Rust should focus on solving a problem that users of Rust are having. -This section should explain this problem in detail, including necessary background. +Rusts can report to Cargo +[unused externs](https://doc.rust-lang.org/nightly/rustc/json.html#unused-dependency-notifications) +which Cargo can aggregate and report back which dependencies are unused. -It should also contain several specific use cases where this feature can help a user, and explain how it helps. -This can then be used to guide the design of the feature. +However, not all dependencies exist for using their `extern` in the current package, including +- activating a feature on a transitive dependency +- pinning the version of a transitive dependency in `Cargo.toml` (however, normally this would be done via `Cargo.lock`) -This section is one of the most important sections of any RFC, and can be lengthy. +The user needs a way to be able to augment what the compiler reports with their intentions. ## Guide-level explanation [guide-level-explanation]: #guide-level-explanation -Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: - -- Introducing new named concepts. -- Explaining the feature largely in terms of examples. -- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible. -- If applicable, provide sample error messages, deprecation warnings, or migration guidance. -- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. -- Discuss how this impacts the ability to read, understand, and maintain Rust code. Code is read and modified far more often than written; will the proposed feature make code easier to maintain? - -For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms. +Say I have the following packages: +```toml +[package] +name = "user" + +[dependencies] +abstraction = "1.0" +mechanism = { version = "1.0", features = ["semantic-addition"] } +``` + +```toml +[package] +name = "abstraction" + +[dependencies] +mechanism = "1.0" +``` + +```toml +[package] +name = "mechanism" + +[features] +semantic-addition = [] +``` + +In this case, `user` references `abstraction` within its Rust source code. +The dependency on `mechanism` is only to activate the `semantic-addition` feature. + +With [cargo#16600](https://github.com/rust-lang/cargo/pull/16600), +Cargo would report `mechanism` as an unused dependency: +``` +[WARNING] unused dependency + --> Cargo.toml:6:1 + | + 6 | mechanism = { version = "1.0", features = ["semantic-addition"] } + | ^^^^^^^^^ + | + = [NOTE] `cargo::unused_dependencies` is set to `warn` by default +[HELP] remove the dependency + | + 6 - mechanism = { version = "1.0", features = ["semantic-addition"] } + | +[HELP] to keep the dependency, mark it as used: + | + 6 | mechanism = { version = "1.0", features = ["semantic-addition"], used = true } + | +++++++++++++ + | +``` + +To resolve this, `user` can: +```toml +[package] +name = "user" + +[dependencies] +abstraction = "1.0" +mechanism = { version = "1.0", features = ["semantic-addition"], used.reason = "feature activation" } +``` + +Cargo would see that a `reason` is provided for why this is `used` and silence the lint. ## Reference-level explanation [reference-level-explanation]: #reference-level-explanation -This is the technical portion of the RFC. Explain the design in sufficient detail that: +Within [Specifying Dependencies](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) + +### `used` + +Always consider this dependency used -- Its interaction with other features is clear. -- It is reasonably clear how the feature would be implemented. -- Corner cases are dissected by example. +Applicability: +- `[*dependencies]`: yes +- `[workspace.dependencies]`: no +- `[patch]`: no -The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. +Type: +- `used = `: `true` if used, `false` if unused +- `used.reason = `: used, the description is unused and for documentation purposes only ## Drawbacks [drawbacks]: #drawbacks -Why should we *not* do this? +`reason` is unused by Cargo and could just as well be a comment. +In contrast, Rust's `reason` can be applied to `warn`, `deny`, and `forbid` lints and reported back in the diagnostic +([reference](https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-reasons)). ## Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -- Why is this design the best in the space of possible designs? -- What other designs have been considered and what is the rationale for not choosing them? -- What is the impact of not doing this? -- If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain? +As we are restricted to TOML syntax, we don't have a general purpose way of handling lint control like `#[expect]`. + +### `used` + +Pros: +- Close to the dependency + +Downsides: +- Manifest schema is being extended for control of a one off lint which can be incongruous with other lints and encourage the doing this for other lints which could overcomplicate manifest files + +### Lint config + +```toml +[lints.cargo] +unused_dependencies = { level = "warn", used = ["mechanism"] } +``` + +Pros: +- Follows a consistent pattern for where to configure lints + +Downsides: +- Far away from the dependency specification, making it hard to reason about when looking at `mechanism` +- Need to decide what to do when `mechanism` becomes used or doesn't exist +- This config should not be inherited from `[workspace.lints]` +- Can't inherit `[workspace.lints]` *and* specify lint config in `[lints]` ([#13157](https://github.com/rust-lang/cargo/issues/13157)) +- Blunt hammer, not distinguishing which dependencies table this applies to + - Having it reference the dependencies table makes this more complicated and requires us to have a way to refer to `[dependencies]` + +### `_dep` + +```toml +_mechanism = { package = "mechanism", version = "1.0", features = ["semantic-addition"] } +``` + +Pros: +- Close to the dependency +- Aligns with Rust treating `_` as "don't care" +- Low overhead for design and implementation + +Downsides: +- Doesn't mix well with kebab case names (e.g. `_regex-syntax`) +- The Cargo team was hesitant to officially support something similar for features ([#10794](https://github.com/rust-lang/cargo/issues/10794)) +- Affects sort order, moving it away from any related packages ## Prior art [prior-art]: #prior-art -Discuss prior art, both the good and the bad, in relation to this proposal. -A few examples of what this can include are: +### Rust + +```rust +// Will warn +let something = foo(); + +// Ways of resolving +let _ = foo(); +let _description = foo(); +#[expect(unused_variables, reason = "description")] +let something = foo(); + +#[expect(unused_variables, reason = "description")] +mod { + fn bar() { + let something = foo(); + } +} +``` + +### `cargo udeps` + +[Documentation](https://github.com/est31/cargo-udeps?tab=readme-ov-file#ignoring-some-of-the-dependencies) + +```toml +[package.metadata.cargo-udeps.ignore] +normal = ["if_chain"] +#development = [] +#build = [] -- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? -- For community proposals: Is this done by some other community and what were their experiences with it? -- For other teams: What lessons can we learn from what other communities have done here? -- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. +[dependencies] +if_chain = "1.0.0" # Used only in doc-tests, which `cargo-udeps` cannot check. +``` -This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. -If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. +### `cargo machete` -Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. -Please also take into consideration that rust sometimes intentionally diverges from common language features. +[Documentation](https://github.com/bnjbvr/cargo-machete?tab=readme-ov-file#false-positives) +```toml +[dependencies] +prost = "0.10" # Used in code generated by build.rs output, which cargo-machete cannot check + +# in an individual package Cargo.toml +[package.metadata.cargo-machete] +ignored = ["prost"] + +# in a workspace Cargo.toml +[workspace.metadata.cargo-machete] +ignored = ["prost"] +``` + +### `cargo shear` + +[Documentation](https://github.com/Boshen/cargo-shear) +```toml +[package.metadata.cargo-shear] +ignored = ["crate-name"] +``` ## Unresolved questions [unresolved-questions]: #unresolved-questions -- What parts of the design do you expect to resolve through the RFC process before this gets merged? -- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? -- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC? +Is this the right direction? + +Is `reason` justified? ## Future possibilities [future-possibilities]: #future-possibilities -Think about what the natural extension and evolution of your proposal would -be and how it would affect the language and project as a whole in a holistic -way. Try to use this section as a tool to more fully consider all possible -interactions with the project and language in your proposal. -Also consider how this all fits into the roadmap for the project -and of the relevant sub-team. - -This is also a good place to "dump ideas", if they are out of scope for the -RFC you are writing but otherwise related. - -If you have tried and cannot think of any future possibilities, -you may simply state that you cannot think of anything. +### Potential lints that may need configuration -Note that having something written down in the future-possibilities section -is not a reason to accept the current or a future RFC; such notes should be -in the section on motivation or rationale in this or subsequent RFCs. -The section merely provides additional information. +- [#5340: Lint against non semver-open dependencies](https://github.com/rust-lang/cargo/issues/5340) +- [#9058: Warning when large binary files are included into the bundle](https://github.com/rust-lang/cargo/issues/9058) +- [#13681: Build script allowlist mode](https://github.com/rust-lang/cargo/issues/13681) +- [#15580: Lint for redundant feature names](https://github.com/rust-lang/cargo/issues/15580) +- [#15581: Lint for negative feature names](https://github.com/rust-lang/cargo/issues/15581) +- [#15590: Lint for feature named for private dependency](https://github.com/rust-lang/cargo/issues/15590) From d6c64a3cf44d54548be27b5240e77ccd06af56be Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 13 Feb 2026 08:18:01 -0600 Subject: [PATCH 03/13] Update RFC number in filename --- text/{0000-used-deps.md => 3920-used-deps.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename text/{0000-used-deps.md => 3920-used-deps.md} (100%) diff --git a/text/0000-used-deps.md b/text/3920-used-deps.md similarity index 100% rename from text/0000-used-deps.md rename to text/3920-used-deps.md From fcc06ed8a0272dc89e2b8ba2184bc1a890146f5d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 13 Feb 2026 08:18:24 -0600 Subject: [PATCH 04/13] Update RFC number in body --- text/3920-used-deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index e05d416f352..cdaeb1ccc57 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -1,6 +1,6 @@ - Feature Name: `used-deps` - Start Date: 2026-02-12 -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- RFC PR: [rust-lang/rfcs#3920](https://github.com/rust-lang/rfcs/pull/3920) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) ## Summary From cba23b9cfbad34ed5b4dbc0af624563e26227645 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 13 Feb 2026 08:37:18 -0600 Subject: [PATCH 05/13] feat(prior): Add npm peerDependencies --- text/3920-used-deps.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index cdaeb1ccc57..807e842847c 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -219,6 +219,13 @@ ignored = ["prost"] ignored = ["crate-name"] ``` +### `peerDependencies` + +npm has the concept of +[`peerDependencies`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#peerdependencies) +for requiring a version of a package if it exists without actually building against this. +This was developed for plugins to specify the version of what they plug into ([announcment](https://nodejs.org/en/blog/npm/peer-dependencies)). + ## Unresolved questions [unresolved-questions]: #unresolved-questions From 027b6c3289bc5afa3d8bfc5b607a04bed01c2187 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 13 Feb 2026 08:39:45 -0600 Subject: [PATCH 06/13] feat(prior): Include cfg-false dependencies --- text/3920-used-deps.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index 807e842847c..ce76ad43123 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -17,7 +17,7 @@ which Cargo can aggregate and report back which dependencies are unused. However, not all dependencies exist for using their `extern` in the current package, including - activating a feature on a transitive dependency -- pinning the version of a transitive dependency in `Cargo.toml` (however, normally this would be done via `Cargo.lock`) +- pinning the version of a transitive dependency in `Cargo.toml` (however, normally this would be done via `Cargo.lock` or `target."cfg(false)".dependencies`) The user needs a way to be able to augment what the compiler reports with their intentions. @@ -219,6 +219,16 @@ ignored = ["prost"] ignored = ["crate-name"] ``` +### `cfg(false)` dependencies + +To specify a version requirement on a package without using it, you can do: +```toml +[target."cfg(false)".dependencies] +foo = "1.0.0" +``` + +This would not work for feature activations. + ### `peerDependencies` npm has the concept of From c4d9a80edcb418b29ff9e15b7e05eeb2b1c3e77a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 17 Feb 2026 10:25:37 -0600 Subject: [PATCH 07/13] fix(motivation): Typo --- text/3920-used-deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index ce76ad43123..acd9035dc7d 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -11,7 +11,7 @@ Extend Cargo's dependency specifications so users can mark that a dependency is ## Motivation [motivation]: #motivation -Rusts can report to Cargo +Rustc can report to Cargo [unused externs](https://doc.rust-lang.org/nightly/rustc/json.html#unused-dependency-notifications) which Cargo can aggregate and report back which dependencies are unused. From c23e9a1c8558657605f8eeed7b933fa5b458f4a9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 17 Feb 2026 10:28:35 -0600 Subject: [PATCH 08/13] feat(future): Mention programmatic reasons --- text/3920-used-deps.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index acd9035dc7d..2f92b343c28 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -246,6 +246,23 @@ Is `reason` justified? ## Future possibilities [future-possibilities]: #future-possibilities +### Programmatic reason + +The user being able to tell Cargo the reason in a way that it can verify it and still warn if the reason no longer applies. + +For example, say we had: +```toml +[package] +name = "user" + +[dependencies] +abstraction = "1.0" +mechanism = { version = "1.0", features = ["semantic-addition"], used.transitive = true } +``` +Then if `abstraction` is removed, we could start warning about `mechanism` again. + +For `transitive`, this could get complicated to have access to the dependency resolution graph at the time the warning is being handled. + ### Potential lints that may need configuration - [#5340: Lint against non semver-open dependencies](https://github.com/rust-lang/cargo/issues/5340) From 42547d84fb36ed8a19a3d7cdb8b54379d192704a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 17 Feb 2026 10:31:09 -0600 Subject: [PATCH 09/13] feat(drawback): No way to verify users declaration of used --- text/3920-used-deps.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index 2f92b343c28..770d2b6bd92 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -111,6 +111,10 @@ Type: In contrast, Rust's `reason` can be applied to `warn`, `deny`, and `forbid` lints and reported back in the diagnostic ([reference](https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-reasons)). +With any of the current options, +if the dependency ever becomes truly unused, +there is no way to report this to the user. + ## Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives From 607511173a751b66a96b2c9802da47b099dcdd06 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 17 Feb 2026 10:32:23 -0600 Subject: [PATCH 10/13] fix(prior): Typo --- text/3920-used-deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index 770d2b6bd92..d9def83cb87 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -238,7 +238,7 @@ This would not work for feature activations. npm has the concept of [`peerDependencies`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#peerdependencies) for requiring a version of a package if it exists without actually building against this. -This was developed for plugins to specify the version of what they plug into ([announcment](https://nodejs.org/en/blog/npm/peer-dependencies)). +This was developed for plugins to specify the version of what they plug into ([announcement](https://nodejs.org/en/blog/npm/peer-dependencies)). ## Unresolved questions [unresolved-questions]: #unresolved-questions From 5777fcc60ce356b4ba17c75776b24611f410dd61 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 19 Feb 2026 14:15:14 -0600 Subject: [PATCH 11/13] feat: Pull out used.reason for being write-only --- text/3920-used-deps.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index d9def83cb87..c07a429d330 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -81,10 +81,11 @@ name = "user" [dependencies] abstraction = "1.0" -mechanism = { version = "1.0", features = ["semantic-addition"], used.reason = "feature activation" } +# For feature activation +mechanism = { version = "1.0", features = ["semantic-addition"], used = true } ``` -Cargo would see that a `reason` is provided for why this is `used` and silence the lint. +Cargo would see that the dependency is marked as `used` and silence the lint. ## Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -100,17 +101,11 @@ Applicability: - `[workspace.dependencies]`: no - `[patch]`: no -Type: -- `used = `: `true` if used, `false` if unused -- `used.reason = `: used, the description is unused and for documentation purposes only +Type: `bool` ## Drawbacks [drawbacks]: #drawbacks -`reason` is unused by Cargo and could just as well be a comment. -In contrast, Rust's `reason` can be applied to `warn`, `deny`, and `forbid` lints and reported back in the diagnostic -([reference](https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-reasons)). - With any of the current options, if the dependency ever becomes truly unused, there is no way to report this to the user. @@ -128,6 +123,12 @@ Pros: Downsides: - Manifest schema is being extended for control of a one off lint which can be incongruous with other lints and encourage the doing this for other lints which could overcomplicate manifest files +### `used.reason` + +If we added `reason`, it would be unused by Cargo and could just as well be a comment. +In contrast, Rust's `reason` can be applied to `warn`, `deny`, and `forbid` lints and reported back in the diagnostic +([reference](https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-reasons)). + ### Lint config ```toml @@ -245,8 +246,6 @@ This was developed for plugins to specify the version of what they plug into ([a Is this the right direction? -Is `reason` justified? - ## Future possibilities [future-possibilities]: #future-possibilities @@ -265,7 +264,7 @@ mechanism = { version = "1.0", features = ["semantic-addition"], used.transitive ``` Then if `abstraction` is removed, we could start warning about `mechanism` again. -For `transitive`, this could get complicated to have access to the dependency resolution graph at the time the warning is being handled. +However for `transitive`, this could get complicated to have access to the dependency resolution graph at the time the warning is being handled. ### Potential lints that may need configuration From 8c95d29e6a1c17eba5ab40a8b2db2e242c50b636 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 23 Feb 2026 10:27:13 -0600 Subject: [PATCH 12/13] feat(alt): Cover link control --- text/3920-used-deps.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index c07a429d330..a55f586c49c 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -163,6 +163,26 @@ Downsides: - The Cargo team was hesitant to officially support something similar for features ([#10794](https://github.com/rust-lang/cargo/issues/10794)) - Affects sort order, moving it away from any related packages +### Link control + +```toml +mechanism = { version = "1.0", lib = false, features = ["semantic-addition"] } +``` + +[Artifact dependencies](https://doc.rust-lang.org/cargo/reference/unstable.html#artifact-dependencies) +has a `lib` field to control whether a package links to that dependency. + +We could stabilize that piece independent of the rest of artifact dependencies +and shift the focus of this lint to `unused_lib_dependencies`. +We could suggest to users to remove the dependency or set `lib = false`. + +Open questions: +- How would artifact / unlinked dependencies resolve features? Independent of the rest of unified? + - My guess is unified with [opaque dependencies](https://github.com/rust-lang/cargo/issues/3573#issuecomment-3498262549) being a way to make them not unified. +- Does this cover all false-positive cases? + +As an aside: is `lib` or `link` a more appropriate field name? + ## Prior art [prior-art]: #prior-art From 8c024b7a53ba552b4d8602c4aa4da6e2ee66b73c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 23 Feb 2026 10:33:18 -0600 Subject: [PATCH 13/13] fix(alt): Expand on link control --- text/3920-used-deps.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/text/3920-used-deps.md b/text/3920-used-deps.md index a55f586c49c..c98392fa1bc 100644 --- a/text/3920-used-deps.md +++ b/text/3920-used-deps.md @@ -181,6 +181,14 @@ Open questions: - My guess is unified with [opaque dependencies](https://github.com/rust-lang/cargo/issues/3573#issuecomment-3498262549) being a way to make them not unified. - Does this cover all false-positive cases? +Pros: +- Close to the dependency +- Low overhead for design and implementation +- Won't build if it goes stale, avoiding slowing down builds + +Downsides: +- Requires a comment to make sense of it + As an aside: is `lib` or `link` a more appropriate field name? ## Prior art