Skip to content

cargo check fires when rustc lints use - instead of _ #17341

Open

Description

@zacknewman

Problem

All the names of lints and lint groups use - instead of _ in the output of rustc -Whelp:

[zack@laptop ~]$ rustc --version
rustc 1.99.0-nightly (1a98b1e13 2026-08-07)
[zack@laptop ~]$ rustc -Whelp

Available lint options:
    -W <foo>           Warn about <foo>
    -A <foo>           Allow <foo>
    -D <foo>           Deny <foo>
    -F <foo>           Forbid <foo> (deny <foo> and all attempts to override)


Lint checks provided by rustc:

                                                       name  default  meaning
                                                       ----  -------  -------
                     absolute-paths-not-starting-with-crate  allow    fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name
⋮

Despite the "official names" using - instead of _ at least per rustc in -Whelp and diagnostic messages (e.g., note: requested on the command line with `-D unused-results`), cargo check complains that the use of such names is deprecated and won't work in a future edition:

[zack@laptop example]$ cargo check
warning: Cargo.toml: `lints.rust.ambiguous-negative-literals` is deprecated in favor of `lints.rust.ambiguous_negative_literals` and will not work in a future edition
warning: Cargo.toml: `lints.rust.closure-returning-async-block` is deprecated in favor of `lints.rust.closure_returning_async_block` and will not work in a future edition
warning: Cargo.toml: `lints.rust.dead-code-pub-in-binary` is deprecated in favor of `lints.rust.dead_code_pub_in_binary` and will not work in a future edition
warning: Cargo.toml: `lints.rust.deprecated-in-future` is deprecated in favor of `lints.rust.deprecated_in_future` and will not work in a future edition
warning: Cargo.toml: `lints.rust.deprecated-safe` is deprecated in favor of `lints.rust.deprecated_safe` and will not work in a future edition
warning: Cargo.toml: `lints.rust.deref-into-dyn-supertrait` is deprecated in favor of `lints.rust.deref_into_dyn_supertrait` and will not work in a future edition
warning: Cargo.toml: `lints.rust.ffi-unwind-calls` is deprecated in favor of `lints.rust.ffi_unwind_calls` and will not work in a future edition
warning: Cargo.toml: `lints.rust.future-incompatible` is deprecated in favor of `lints.rust.future_incompatible` and will not work in a future edition
warning: Cargo.toml: `lints.rust.impl-trait-redundant-captures` is deprecated in favor of `lints.rust.impl_trait_redundant_captures` and will not work in a future edition
warning: Cargo.toml: `lints.rust.keyword-idents` is deprecated in favor of `lints.rust.keyword_idents` and will not work in a future edition
warning: Cargo.toml: `lints.rust.let-underscore` is deprecated in favor of `lints.rust.let_underscore` and will not work in a future edition
warning: Cargo.toml: `lints.rust.linker-info` is deprecated in favor of `lints.rust.linker_info` and will not work in a future edition
warning: Cargo.toml: `lints.rust.macro-use-extern-crate` is deprecated in favor of `lints.rust.macro_use_extern_crate` and will not work in a future edition
warning: Cargo.toml: `lints.rust.meta-variable-misuse` is deprecated in favor of `lints.rust.meta_variable_misuse` and will not work in a future edition
warning: Cargo.toml: `lints.rust.missing-copy-implementations` is deprecated in favor of `lints.rust.missing_copy_implementations` and will not work in a future edition
warning: Cargo.toml: `lints.rust.missing-debug-implementations` is deprecated in favor of `lints.rust.missing_debug_implementations` and will not work in a future edition
warning: Cargo.toml: `lints.rust.missing-docs` is deprecated in favor of `lints.rust.missing_docs` and will not work in a future edition
warning: Cargo.toml: `lints.rust.non-ascii-idents` is deprecated in favor of `lints.rust.non_ascii_idents` and will not work in a future edition
warning: Cargo.toml: `lints.rust.nonstandard-style` is deprecated in favor of `lints.rust.nonstandard_style` and will not work in a future edition
warning: Cargo.toml: `lints.rust.redundant-imports` is deprecated in favor of `lints.rust.redundant_imports` and will not work in a future edition
warning: Cargo.toml: `lints.rust.redundant-lifetimes` is deprecated in favor of `lints.rust.redundant_lifetimes` and will not work in a future edition
warning: Cargo.toml: `lints.rust.refining-impl-trait` is deprecated in favor of `lints.rust.refining_impl_trait` and will not work in a future edition
warning: Cargo.toml: `lints.rust.rust-2018-compatibility` is deprecated in favor of `lints.rust.rust_2018_compatibility` and will not work in a future edition
warning: Cargo.toml: `lints.rust.rust-2018-idioms` is deprecated in favor of `lints.rust.rust_2018_idioms` and will not work in a future edition
warning: Cargo.toml: `lints.rust.rust-2021-compatibility` is deprecated in favor of `lints.rust.rust_2021_compatibility` and will not work in a future edition
warning: Cargo.toml: `lints.rust.rust-2024-compatibility` is deprecated in favor of `lints.rust.rust_2024_compatibility` and will not work in a future edition
warning: Cargo.toml: `lints.rust.single-use-lifetimes` is deprecated in favor of `lints.rust.single_use_lifetimes` and will not work in a future edition
warning: Cargo.toml: `lints.rust.trivial-casts` is deprecated in favor of `lints.rust.trivial_casts` and will not work in a future edition
warning: Cargo.toml: `lints.rust.trivial-numeric-casts` is deprecated in favor of `lints.rust.trivial_numeric_casts` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unit-bindings` is deprecated in favor of `lints.rust.unit_bindings` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unknown-or-malformed-diagnostic-attributes` is deprecated in favor of `lints.rust.unknown_or_malformed_diagnostic_attributes` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unnameable-types` is deprecated in favor of `lints.rust.unnameable_types` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unreachable-pub` is deprecated in favor of `lints.rust.unreachable_pub` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unsafe-code` is deprecated in favor of `lints.rust.unsafe_code` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unstable-features` is deprecated in favor of `lints.rust.unstable_features` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unused-crate-dependencies` is deprecated in favor of `lints.rust.unused_crate_dependencies` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unused-import-braces` is deprecated in favor of `lints.rust.unused_import_braces` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unused-lifetimes` is deprecated in favor of `lints.rust.unused_lifetimes` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unused-qualifications` is deprecated in favor of `lints.rust.unused_qualifications` and will not work in a future edition
warning: Cargo.toml: `lints.rust.unused-results` is deprecated in favor of `lints.rust.unused_results` and will not work in a future edition
warning: `example` (manifest) generated 40 warnings

Proposed Solution

Lints should be allowed to have - instead of _ in [lints.rust] and [lints.clippy].

Notes

I believe #17298 is the sudden cause of these warnings. I have been informed this is due to #17051.

Activity

  1. added
    C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`
    S-triageStatus: This issue is waiting on initial triage.
    on Aug 8, 2026
  2. changed the title [-]`renamed-and-removed-lints` fires when lints use `-` instead of `_` on `nightly`[/-] [+]`cargo check` fires when lints use `-` instead of `_` on `nightly`[/+] on Aug 8, 2026
  3. changed the title [-]`cargo check` fires when lints use `-` instead of `_` on `nightly`[/-] [+]`cargo check` fires when `rustc` lints use `-` instead of `_` on `nightly`[/+] on Aug 8, 2026
  4. weihanglo commented on Aug 8, 2026

    @weihanglo
    Member

    In #17298 (comment):

    Even the link to the "Lint naming" guidelines uses sentences like:

    The basic rule is: the lint name should make sense when read as “allow lint-name” or “allow lint-name items”.

    Notice the use of - instead of _. This seems overly opinionated to be warn-by-default.

    However, down a few lines:

    https://rustc-dev-guide.rust-lang.org/diagnostics.html#lint-naming

    Use snake case in the same way you would for function names.

    See also the rationale: #13943 (comment)

  5. zacknewman commented on Aug 8, 2026

    @zacknewman
    Author

    Hm, I don't find that very convincing though. I understand Cargo wants to require _ for its own lints, but I fail to see how that applies to a different table like lints.rust. Additionally, it seems inconsistent that on a package level no hard requirement is made for packages to only contain one or the other; and even more bizarre is the fact that if such a decision were made it'd likely be in favor of - over _ based on my experience with package names at least.

    While I realize one can technically have two rustc lints that only differ by - or _, that's also true for dependencies. Just like dependencies, Cargo transforms the - one to the _ one when there are no "duplicates". When there are "duplicates", it doesn't complain (unless they are truly identical) and doesn't transform the - one to the _ one forcing one to handle the - one manually by giving it an alias. Because the most popular registry, crates.io, treats packages as the same if they only differ by - and _, it's rare when one has two dependencies in Cargo.toml that differ by - and _ alone. It can still happen though especially with local crates.

    One difference I imagine is that the use of - in package names is far more common than people using - for rustc lints, so this breaking change is not as impactful. Still sucks that I have to update every crate I've ever written since all of them contain at least one rustc lint or lint group with a name that contains -. I chose to reference such lints with - because I thought it would never matter, and I assumed the one with - was "official" seeing how it's the version you always see in diagnostic messages and -Whelp.

  6. tgross35 commented on Aug 26, 2026

    @tgross35
    Member

    I understand that the duplication in #13943 is a problem but I don't think forcing one behavior is a great solution. Why not only warn on duplicates after normalization rather than forcing the underscore style?

    Lints are documented using -, including CLI examples https://doc.rust-lang.org/rustc/lints/groups.html. It's pretty rough that Cargo is deviating here, especially when all other builtin manifest keys use kebab case (dev-dependencies and others).

  7. zacknewman commented on Aug 26, 2026

    @zacknewman
    Author

    Yeah, I really don't understand or agree with this change. It stinks of overreach and adds to the unfortunate reputation that Rustaceans are a little too evangelical. Can you imagine if rustc was changed to no longer compile code that contained types whose names didn't conform to the standard style even if such change happened on an edition boundary? That's obviously an extreme analogy, but I also thought this kind of change wouldn't happen. Again, the biggest problem isn't even the warning but the actual deprecation that will occur.

    I don't even consider duplication a real problem and certainly not a bigger problem than the problem this change creates. As stated multiple times above, there are a bunch of sources that use the -ed form for lints; so it's quite understandable if one does as well. Does this change how lints can be supplied on the command line? If not, that's inconsistent. Cargo is burying its head pretending to not know what a lint means when it's in Cargo.toml but magically knows its meaning when passed on the command line.

    Last, the solution to the "problem" of duplication is far bigger than it needs to be. Why not complain when there actually exists a duplicate? Thus entities that choose to conform with how rustc, online documentation for lints, etc. spell lints (i.e., using - instead of _) can still do so; and for those that have duplicates, they get the deprecation warning saying all lints that only differ by - and _ will be ignored in a future release.

  8. changed the title [-]`cargo check` fires when `rustc` lints use `-` instead of `_` on `nightly`[/-] [+]`cargo check` fires when `rustc` lints use `-` instead of `_` on `beta`[/+] on Aug 26, 2026
  9. tgross35 commented on Oct 14, 2026

    @tgross35
    Member

    However, down a few lines:
    https://rustc-dev-guide.rust-lang.org/diagnostics.html#lint-naming

    Use snake case in the same way you would for function names.

    I'm pretty sure this is referring to snake case for the symbol name, as opposed to MyLintName. They are still referred to using hyphens in most documentation that isn't a code example.

  10. added
    I-nominated-to-discussTo be discussed during issue triage on the next Cargo team meeting
    on Oct 14, 2026
  11. changed the title [-]`cargo check` fires when `rustc` lints use `-` instead of `_` on `beta`[/-] [+]`cargo check` fires when `rustc` lints use `-` instead of `_`[/+] on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lints-tableArea: [lints] tableC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`I-nominated-to-discussTo be discussed during issue triage on the next Cargo team meetingS-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions