{"id":18664082,"url":"https://github.com/phansch/mini_rfc_for_cargo_lint_configuration","last_synced_at":"2026-01-26T01:01:41.898Z","repository":{"id":80164035,"uuid":"162242372","full_name":"phansch/mini_rfc_for_cargo_lint_configuration","owner":"phansch","description":null,"archived":false,"fork":false,"pushed_at":"2019-01-01T20:13:14.000Z","size":97,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-18T05:08:26.683Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phansch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-18T06:39:32.000Z","updated_at":"2019-01-01T20:13:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"837c161f-f963-4fcc-8284-9f9012fa51d6","html_url":"https://github.com/phansch/mini_rfc_for_cargo_lint_configuration","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/phansch/mini_rfc_for_cargo_lint_configuration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phansch%2Fmini_rfc_for_cargo_lint_configuration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phansch%2Fmini_rfc_for_cargo_lint_configuration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phansch%2Fmini_rfc_for_cargo_lint_configuration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phansch%2Fmini_rfc_for_cargo_lint_configuration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phansch","download_url":"https://codeload.github.com/phansch/mini_rfc_for_cargo_lint_configuration/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phansch%2Fmini_rfc_for_cargo_lint_configuration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28763086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T00:37:26.264Z","status":"ssl_error","status_checked_at":"2026-01-26T00:37:25.959Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T08:21:34.247Z","updated_at":"2026-01-26T01:01:41.875Z","avatar_url":"https://github.com/phansch.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mini-RFC: Cargo Lint configuration\n\nThis is a rough plan for adding lint configuration by config file to Cargo.\n\nIt's a continuation of [this Cargo issue][that_issue] from @rantanen. Relevant\nparts were copied and used as a starting ground for this text. @detrumi opened a\n[Cargo PR][detrumi_pr] when the issue was opened. However, it was decided at the\ntime that the design should go through more discussion first. That's what this\nMini-RFC is meant to kick-off.\n\n## Summary\n\nRust currently only allows configuring lint levels on the command line or via\ncrate level attributes. This Mini-RFC proposes an additional way to configure\nlint levels and possibly lint-specific settings in `Cargo.toml`.\n\n## Motivation\n\nConfiguring lint levels on the command line or via crate level attributes is\nfine when the project consists of a single crate, but gets more cumbersome when\nthe project is a workspace with more than a few crates.\n\nBeing able to define the lints in an external file that will be used when\nbuilding the crates would have several benefits:\n\n * Sharing one configuration file for all the crates in a workspace, therefore\n   ensuring consistent lint levels everywhere.\n * A canonical place to check for lint configuration when contributing to a new\n   project.\n * An easy way to examine the version history for lint changes.\n\nSome real world examples of where this could bring improvements:\n\n* [This rustc rollup][rollup] which denies a single lint in various subcrates\n  over multiple PRs.\n* [serde's lib.rs][ex_serde] and [serde_derive's lib.rs][ex_serde2] would also\n  benefit from having a central lint configuration file. The same for\n  [diesel's lib.rs][ex_diesel] and [diesel_migrations's lib.rs][ex_diesel2].\n* The [Amethyst game framework][amethyst], with 15 different sub crates, has to\n  enable warnings for the `rust_2018_ideoms` and `rust_2018_compatibilty` lint\n  groups in [every][am_1] [single][am_2] [one][am_3] [of][am_4] [the][am_5]\n  [sub-crates][am_6] (that's 6 of them linked here).\n* Similarly, [ripgrep][ripgrep] denies the `missing_docs` lint in all of its 9\n  workspace members: [GitHub search][ripgrep_search]\n\nPreviously this topic came up a few times in the Clippy issue tracker as well:\n\n* [#574: Ability to conditionally set levels for lints when not using clippy through cargo features](previous_574)\n* [#1313: Allow/deny lints in clippy.toml](previous_1313)\n* [#3164: It is impossible to understand from the readme file how to suppress lints using clippy.toml](previous_3164)\n\n## Guide-level explanation\n\nLint configuration can also be done through a configuration file.  The\nconfiguration needs to be able to configure the `allow/warn/deny/forbid` lint\nlevels for each lint. In order to be more teachable, using toml syntax is\nprobably the best way to configure the lints. The most obvious location is in\nthe `Cargo.toml` file.\n\n## Reference-level explanation\n\nIn the most basic version, it would be possible to set the\n`allow/warn/deny/forbid` of lints that are registered with the lint registry.\nThese would be grouped in a new `[lints]` section. Tool-specific lints (like\nClippy) are grouped together using the tool name.\n\nThat would give us a format like this:\n\n```toml\n[lints]\ndead_code = \"allow\"\n\n[lints.clippy]\nnon_snake_case = \"warn\"\n```\n\nThis format would make git history easy to read and would allow you to add\nconfiguration options to lints later on. It also allows grouping of lints on\nmore than just the lint level.\n\nAnd if Cargo/rustc ever support lint configurations, this would be more future proof:\n\n```toml\n[lints.clippy]\ncyclomatic_complexity = { state = \"deny\", threshold = 30 }\n```\n\nAnother possible format would be:\n\n```toml\n[lints]\nallow = [\"dead_code\", \"non_snake_case\"]\n```\n\nThis has the benefit of not having to repeat the lint level for every single\nlint. However, this would probably make diffs more difficult to read.\n\n### `cargo check` and tool lints interaction\n\nIf a user has configured a tool lint in `Cargo.toml` and runs `cargo check`, the\nimplementation needs to make sure to only pass the rustc lints to `rustc`,\notherwise rustc would complain about unknown lints because it was invoked with\n`check` and not `clippy`, for example.\n\nWhen `cargo clippy` is executed, it should include the rustc lints, as it does\ntoday.\n\n### Lint precedence\n\nThe lints can be specified on the workspace level and for individual packages.\nAnything on the package level will override the workspace setup on a per lint\nbasis. This means that lints configured in the workspace will act as a default\nfor packages within that workspace, and can be overridden by individual packages.\n\n### Why Cargo.toml?\n\nThe biggest advantage of using `Cargo.toml` is that it's already used for\nconfiguring project and workspace level settings. Most users would expect to\nfind lint configuration there and pretty much every Rust project uses it\nalready.\n\nHowever, one downside is that there is currently no way to share a `Cargo.toml`\nbetween separate projects. There's no concrete solution here, but maybe\na new `inherit_from` or `inherit_lints_from` key could solve that problem. Prior\nart includes at least [Rubocop's `inherit_from` setting][rubocop_inherit] and\n[eslint's `extend` setting][eslint_inherit].\n\nAdditionally, one might argue that `Cargo.toml` is part of Cargo, which should\njust be concerned about package management and not lint configuration. However,\nCargo is currently the only tool available that interfaces with `rustc` and\noffers a way to configure interfacing with rustc.\n\nFor users it may also not be immediately clear that both `cargo check` and\n`cargo clippy` work with the same underlying lint system and they may not expect\nto be able to configure tool lints through a Cargo configuration file. This is\nbecause other programming language ecosystems usually have completely separate\ntools for their lints. See the _Prior art_ section below for a small\ndiscussion of this problem.\n\nIf we find a solution to `Cargo.toml` not being shareable across projects, we\nconsider it to be the best approach mainly because the file is already present\nin every Cargo project.\n\n## Drawbacks\n- Adding lint configuration to `Cargo.toml` means that there will be more places\nwhere lints can be configured, making it more difficult to quickly see what lint\nlevels are used.\n- Another downside of this is that it becomes less clear which lint level takes\nprecedence, if the same lint is set multiple times in different locations. Even\nif the precedence rules are useful for the majority of use cases, developers still\nneed to be aware of the precedence, or avoid specifying the lint multiple times.\n\n## Alternatives\n\n### Using `package.metadata` tables\n\nAnother approach, that was [proposed on IRLO recently][other_irlo_post], could\nbe using the `metadata` configuration:\n\nCargo would look for a `[package.metadata.lints]` section instead of a `[lints]`\nsection. Tools that are not hooking into the lint system, could use their own\n`[package.metadata.toolname]` section instead of using a custom file.\n\nOne problem with `[package.metadata]` is that it does not support [virtual\nworkspaces][virtual_workspaces] as it requires the `package` table to be\npresent in the `Cargo.toml`.\n\n### Different configuration file location\n\nThere are some other plausible locations to configure lints, such as\n`.cargo/config` or `Lints.toml`.\n\n#### .cargo/config\n\nA more standard location, though less well-known, would be `.cargo/config` (see [Cargo reference](cargo_docs)).\nAs with `Cargo.toml`, this file would need a new `[lints]` section, too.\n\nOne big advantage would be that users could add their personal lint preferences\nin their home directory (both `$HOME/.cargo/config` and `.cargo/config` are\nsupported) as `.cargo/config` already\n[has a hierarchical configuration lookup][cargo_hierarchical].\n\nA downside would be that Lint configuration via config file would supposedly be\npretty common, while custom Cargo configuration is rarely used. Almost every\nproject would want to make use of a lint configuration, which means that every\nproject would end up having to create the additional `.cargo/config` file.\n\n#### Lints.toml\n\nAnother option would be a completely separate file. Maybe called `Lints.toml`.\nThis would be the most flexible solution because the implementation would not\nhave to care about existing code for `Cargo.toml` or `.cargo/config`. It is also\nmore similar to the existing [`Clippy.toml`][clippy_toml].\n\nHowever, it would also mean that, like with `.cargo/config`, users have to add\nan additional configuration file to the roots of their repositories.\n\nAdditionally, we may also want to handle `rustfmt` configuration, and we would\nneed to find a more general name.\n\n## Prior art\n\nIn other programming language ecosystems, the concerns of dependency management\nand things such as lint configuration are handled by completely separate tools.\nThis is usually because the language itself does not come with any lints like\nRust. For example, in Javascript, you have [eslint][eslint] and the\n`package.json`, which don't really interact. In Ruby, you have\n[Rubocop][rubocop] for lints and `bundler`/`Gemfile` for dependencies.\n\nRust is different from these examples because it already comes with built-in\nlints and offers an interface for external tools to make use of the same lint\nsystem.\n\nIf another language exists that provides external tools with hooks into its lint\nsystem, it would be good to take a look. Specifically how the interaction\nbetween external and internals lints is handled.\n\n## Future possibilities\n\n* It might be desirable to also be able to configure the settings of specifics lints, such as in the `cyclomatic_complexity` shown earlier. This could also replace\nthe [`clippy.toml`][clippy_toml] file, which currently allows configuring lints.\n* It would make sense to include other settings related to lints, such as output verbosity or `--cap-lints` in the lint configuration.\n* Other tools could also add lints to the same lints section, not just Clippy.\n* rustfmt configuration via `Cargo.toml` might be something that's desired, too.\n\n### Diagnostics for lint level definition location reporting\n\nWith the current approach, we pass all lint level definitions from the config\nfile to rustc via the command line arguments. Consequently, rustc will tell the\nuser the lint level has been defined on the command-line. This is the opposite\nof helpful if the user wants to change the level of the lint:\n\n```text\nerror: any use of this value will cause an error\n  --\u003e $DIR/const-err-multi.rs:13:1\n   |\nLL | pub const A: i8 = -std::i8::MIN;\n   | ^^^^^^^^^^^^^^^^^^-------------^\n   |                   |\n   |                   attempt to negate with overflow\n   |\n   = note: requested on the command line with `-D const_err`\n```\n\nIdeally, the user would get a `note` like this:\n\n```text\nnote: lint level defined here\n  --\u003e $DIR/Cargo.toml:511:1\n   |\nLL | const_err = { state = \"deny\" }\n   | ^^^^^^^^^\n```\n\nAdding a new variant to [`LintSource`][lintsource] is the easy part, but how is this\ninformation passed from Cargo to rustc? Should we pass a json file with lint\nlevel definition locations to rustc every time cargo invokes rustc?\n\n### Diagnostics for unknown lints reporting\n\nThere is currently no good way to detect whether a lint is known or not: all\nconfigured lints are passed to rustc directly, which throws an error if the\nlint isn't known. Ideally, Cargo would issue a warning instead that includes\nthe line number in the configuration file.\n\n[that_issue]: https://github.com/rust-lang/cargo/issues/5034\n[ex_serde]: https://github.com/serde-rs/serde/blob/5c24f0f0f300c7bd21bad5b097f6f1919de8477c/serde/src/lib.rs#L87-L134\n[ex_serde2]: https://github.com/serde-rs/serde/blob/5c24f0f0f300c7bd21bad5b097f6f1919de8477c/serde_derive/src/lib.rs#L18-L49\n[ex_diesel]: https://github.com/diesel-rs/diesel/blob/59aa49b65713df8d666991b37f5e18011f3671d5/diesel/src/lib.rs#L132-L170\n[ex_diesel2]: https://github.com/diesel-rs/diesel/blob/36078014717d6c2fb0d03d2a10d19177c06ed86d/diesel_migrations/src/lib.rs#L1-L21\n[rollup]: https://github.com/rust-lang/rust/pull/52268\n[eslint]: https://eslint.org/docs/user-guide/getting-started#configuration\n[rubocop]: https://docs.rubocop.org/en/latest/basic_usage/\n[amethyst]: https://github.com/amethyst/amethyst\n[am_1]: https://github.com/amethyst/amethyst/blob/8e7f06a9bca8b60664855cac12dd74be7ddc0c82/amethyst_derive/src/lib.rs#L2\n[am_2]: https://github.com/amethyst/amethyst/blob/8e7f06a9bca8b60664855cac12dd74be7ddc0c82/amethyst_animation/src/lib.rs#L48\n[am_3]: https://github.com/amethyst/amethyst/blob/8e7f06a9bca8b60664855cac12dd74be7ddc0c82/amethyst_assets/src/lib.rs#L10\n[am_4]: https://github.com/amethyst/amethyst/blob/8e7f06a9bca8b60664855cac12dd74be7ddc0c82/amethyst_audio/src/lib.rs#L1\n[am_5]: https://github.com/amethyst/amethyst/blob/8e7f06a9bca8b60664855cac12dd74be7ddc0c82/amethyst_config/src/lib.rs#L6\n[am_6]: https://github.com/amethyst/amethyst/blob/8e7f06a9bca8b60664855cac12dd74be7ddc0c82/amethyst_controls/src/lib.rs#L3\n[ripgrep]: https://github.com/BurntSushi/ripgrep\n[ripgrep_search]: https://github.com/BurntSushi/ripgrep/search?q=missing_docs\u0026unscoped_q=missing_docs\n[detrumi_pr]: https://github.com/rust-lang/cargo/pull/5728\n[previous_574]: https://github.com/rust-lang/rust-clippy/issues/574\n[previous_1313]: https://github.com/rust-lang/rust-clippy/issues/1313\n[previous_3164]: https://github.com/rust-lang/rust-clippy/issues/3164\n[cargo_config]: https://doc.rust-lang.org/cargo/reference/config.html\n[other_irlo_post]: https://internals.rust-lang.org/t/tool-configs-in-cargo-toml-particularily-rustfmt-clippy/9055\n[lintsource]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/enum.LintSource.html\n[rubocop_inherit]: https://docs.rubocop.org/en/latest/configuration/#inheriting-from-another-configuration-file-in-the-project\n[eslint_inherit]: https://eslint.org/docs/developer-guide/shareable-configs\n[clippy_toml]: https://github.com/rust-lang/rust-clippy#configuration\n[cargo_hierarchical]: https://doc.rust-lang.org/cargo/reference/config.html#hierarchical-structure\n[virtual_workspaces]: https://doc.rust-lang.org/cargo/reference/manifest.html#virtual-manifest\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphansch%2Fmini_rfc_for_cargo_lint_configuration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphansch%2Fmini_rfc_for_cargo_lint_configuration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphansch%2Fmini_rfc_for_cargo_lint_configuration/lists"}