Skip to content

Add lint to enforce repository inheritance in workspaces#16734

Open
moabo3li wants to merge 2 commits intorust-lang:masterfrom
moabo3li:lint_if_pkg_rep_not_inherited
Open

Add lint to enforce repository inheritance in workspaces#16734
moabo3li wants to merge 2 commits intorust-lang:masterfrom
moabo3li:lint_if_pkg_rep_not_inherited

Conversation

@moabo3li
Copy link
Contributor

What does this PR try to resolve?

This patch adds a new pedantic lint, uninherited_repository, that fires whenever a workspace member sets package.repository explicitly rather than using repository.workspace = true. The lint suggests the fix inline.

Fixes:#15870

@rustbot rustbot added A-documenting-cargo-itself Area: Cargo's documentation A-workspaces Area: workspaces S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 11, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 11, 2026

r? @ehuss

rustbot has assigned @ehuss.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ehuss, @epage, @weihanglo
  • @ehuss, @epage, @weihanglo expanded to ehuss, epage, weihanglo
  • Random selection from ehuss, epage, weihanglo

@moabo3li moabo3li changed the title Lint if pkg rep not inherited Add lint to enforce repository inheritance in workspaces Mar 11, 2026
@moabo3li moabo3li force-pushed the lint_if_pkg_rep_not_inherited branch 3 times, most recently from f327c59 to 2bcbbe4 Compare March 11, 2026 06:34
@moabo3li
Copy link
Contributor Author

While I was debugging to solve the failing tests, I added a log to the uninherited_repository function right after LINT.level() was called. The log showed:

{"lint_level":"Allow","is_allow":true}

Even though I already set uninherited_repository = "warn" in [lints.cargo].

I discovered a latent bug in src/cargo/lints/mod.rs in the level_priority function that silently suppresses any lint whose name sorts alphabetically after its group name.

In Lint::level(), the lint-level and group-level are compared via max_by_key:

https://github.com/moabo3li/cargo/blob/2bcbbe42543794a14489abb1747cc4edb0a4bdde/src/cargo/lints/mod.rs#L474-L478

When priorities tie (both 0), the tiebreaker Reverse(*n) picks whichever name is alphabetically earlier. The bug is that level_priority returns priority 0 for both explicitly-set values ("warn") and unset defaults:

https://github.com/moabo3li/cargo/blob/2bcbbe42543794a14489abb1747cc4edb0a4bdde/src/cargo/lints/mod.rs#L595-L599

So when a user writes uninherited_repository = "warn":

  • Lint entry: name = "uninherited_repository", level = Warn, priority = 0
  • Group entry: name = "pedantic", level = Allow (default), priority = 0

Since "pedantic" < "uninherited_repository" alphabetically, Reverse("pedantic") > Reverse("uninherited_repository"), the group wins the tiebreaker. The group's Allow default silently overrides the user's explicit "warn".

This affects any lint whose name sorts after its group name:

  • OK: lint='implicit_minimum_version_req' < group='pedantic' (i < p)
  • AFFECTED: lint='uninherited_repository' > group='pedantic' (u > p)
  • AFFECTED: lint='unknown_lints' > group='suspicious' (un > s)
  • AFFECTED: lint='unused_workspace_dependencies' > group='suspicious' (un > s)
  • AFFECTED: lint='unused_workspace_package_fields' > group='suspicious' (un > s)

To verify, I temporarily renamed implicit_minimum_version_req to ximplicit_minimum_version_req (so it sorts after "pedantic") and reverted the fix. The test immediately failed. The lint stopped firing, identical to the uninherited_repository bug:

---- expected ----
[WARNING] dependency version requirement without an explicit minimum version
 --> Cargo.toml:7:7
  |
7 | dep = "1"
  |       ^^^ missing full version components
  |
  = [NOTE] `cargo::ximplicit_minimum_version_req` is set to `warn` in `[lints]`
++++ actual: stderr ++++
[CHECKING] foo v0.0.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

Renaming it back to implicit_minimum_version_req (before "pedantic") made it pass again. The bug is purely alphabetical.

if this confirmed i will make a pr to solve this before go into in this pr

the fix i propose

} else {
    // Use priority -1 so any explicitly-set lint/group value (priority >= 0)
    // beats an unset default regardless of the name-based tiebreaker.
    (unspecified_level, reason, -1)
}

This also corrects the reason text for unused_workspace_dependencies and unused_workspace_package_fields. They were reporting "by default" despite being explicitly configured via [workspace.lints.cargo] inheritance. Now they correctly report "in [lints]".

@moabo3li
Copy link
Contributor Author

even this lint when i renamed to noninherited_repository the lint fires correctly

@moabo3li moabo3li force-pushed the lint_if_pkg_rep_not_inherited branch from 2bcbbe4 to 9777309 Compare March 11, 2026 09:32
@moabo3li moabo3li force-pushed the lint_if_pkg_rep_not_inherited branch from 9777309 to d6ebd7e Compare March 11, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-documenting-cargo-itself Area: Cargo's documentation A-workspaces Area: workspaces S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants