Open heaths opened 1 month ago
Hm, unfortunately I'm not able to reproduce that. Can you include a .zip
file of a workspace the demonstrates the issue?
FWIW, I opened it here because my assumption was that cargo
was not "flatting" the package manifest (if it even does that) before lint tables were parsed. Certainly possible this is an issue in clippy itself. In the course of trying to troubleshoot the issue, it seems plenty of people were successfully using workspace.lints.rust
.
Hm, unfortunately I'm not able to reproduce that. Can you include a
.zip
file of a workspace the demonstrates the issue?
@ehuss certainly, but it'll take me a bit. Our main
branch as it exists right (commit b16e8790a1d0ebe608584db675b4042796b35caf
) now at https://github.com/Azure/azure-sdk-for-rust exhibits all this if you were to run RUSTFLAGS=-Dwarnings cargo +stable clippy --package azure_storage_blobs
but I'm happy to try to provide a minimal repro.
To note, I went ahead and fixed the bug that was unnecessarily using format!()
in some cases so main
won't have this problem next week sometime. Initially it didn't seem worth the time fixing it, but I ended up spending more time troubleshooting this issue. 🤦♂️
I cannot reproduce it either. Guess there were something cached between the first and the second invocation. You might want to run cargo clean
in between.
The implementation of [lints]
table is as simple as passing corresponding -A clippy::useless_format
rustc flag to rustc invocation. You could run cargo clippy
with --verbose
and check if -Dwarnings
is passed to rustc after -A clippy::useless_format
. If I am not wrong, -Dwarnings
should be the last flag.
It took me a bit - I couldn't repro it either at first - but then I figured out what my minimal repro was missing: an empty [workspace.lints]
section in the root Cargo.toml
. That was there to satisfy cargo
since we've been injecting lints.workspace = true
in all our newer crates.
See https://github.com/heaths/rust-lang-cargo-14645, specifically https://github.com/heaths/rust-lang-cargo-14645/commit/19378e57508a3c256e51703c3be4216c34eed288. Note that the root crate imports a dependency by path, but that dependency is part of a separate workspace.
In https://github.com/azure/azure-sdk-for-rust we are generating dozens of crates that we put into a separate workspace to avoid rust-analyzer perf degredation with hand-coded crates. One of those hand-coded crates is using the generated crate in its underlying implementation. That hand-coded crate has lints.workspace = true
in a workspace with an empty [workspace.lints]
. The generated crate also has lints.workspace = true
but its workspace had a non-empty [workspace.lints.clippy]
as documented above.
So somehow that empty workspace.lints
section is affecting the path-imported dependency. If I put the useless_format = "allow"
in the root Cargo.toml
and remove it from the deps/Cargo.toml
workspace, it still works. Seems the empty [workspace.lints]
is overwriting the [workspace.lints.clippy]
of the separate workspace. See https://github.com/heaths/rust-lang-cargo-14645/pull/1 for an example of how the separate root workspace is impacting the crate from another workspace. Is that expected?
What am I supposed to do with this to reproduce the issue?
Clone the repo and run cargo clippy
from the root. You'll get a clippy::useless_format
for deps/foo
warning despite that crate's workspace (deps/Cargo.toml
) allowing it. If you add the allow to the root workspace's Cargo.toml
the issue goes away. So it seems the empty root workspace - of which the dependent root crate belongs - is effectively clearing out dependencies' workspace-configured lints. Conversely, "parent" workspaces like this can override "chlid" workspaces' lint configurations. Seems those two should remain separate. Granted, the dependency is also included by path (monorepo example), or should that be expected?
This also reproduces with rustc which is a more minimal case as an implementation detail of Cargo's development. I switched this out for unused_variables
and added a let unused = "";
in the function with the useless_format
I put in some debug statements in Cargo
[src/cargo/util/toml/mod.rs:318:9] &package_name = PackageName(
"rust-lang-cargo-14645",
)
[src/cargo/util/toml/mod.rs:831:5] normalized_path = "/home/epage/src/personal/dump/rust-lang-cargo-14645/Cargo.toml"
[src/cargo/util/toml/mod.rs:504:9] &normalized_lints = Some(
{},
)
[src/cargo/util/toml/mod.rs:318:9] &package_name = PackageName(
"foo",
)
[src/cargo/util/toml/mod.rs:831:5] normalized_path = "/home/epage/src/personal/dump/rust-lang-cargo-14645/deps/foo/Car
go.toml"
[src/cargo/core/workspace.rs:1991:13] current = "/home/epage/src/personal/dump/rust-lang-cargo-14645/deps/foo"
[src/cargo/core/workspace.rs:1991:13] current = "/home/epage/src/personal/dump/rust-lang-cargo-14645/deps"
[src/cargo/core/workspace.rs:1991:13] current = "/home/epage/src/personal/dump/rust-lang-cargo-14645"
[src/cargo/util/toml/mod.rs:859:5] &workspace_path = "/home/epage/src/personal/dump/rust-lang-cargo-14645/Cargo.toml"
[src/cargo/util/toml/mod.rs:504:9] &normalized_lints = Some(
{},
)
[src/cargo/core/workspace.rs:1991:13] current = "/home/epage/src/personal/dump/rust-lang-cargo-14645/deps/foo"
[src/cargo/core/workspace.rs:1991:13] current = "/home/epage/src/personal/dump/rust-lang-cargo-14645/deps"
[src/cargo/core/workspace.rs:1991:13] current = "/home/epage/src/personal/dump/rust-lang-cargo-14645"
The bug appears to be that our caching of parsed workspaces isn't taking into account all of the workspace load rules. This is a problem for all of workspace inheritance. I'm assuming this hasn't been found before as workspaces aren't usually nested but parallel to each other.
The bug appears to be that our caching of parsed workspaces isn't taking into account all of the workspace load rules. This is a problem for all of workspace inheritance. I'm assuming this hasn't been found before as workspaces aren't usually nested but parallel to each other.
Yeah, given what I've seen in the cargo docs and the Cargo.toml files I've looked at, I personally assumed that nested workspaces weren't really a thing, though I guess the workspace.exclude
key should have been a clue that it was more complicated than that? Though The workspace
field does explicitly state that you can't have both package.workspace
and [workspaces]
in the same manifest:
That is, a crate cannot both be a root crate in a workspace (contain
[workspace]
) and also be a member crate of another workspace (containpackage.workspace
).
(Fortunately, in the scenario described in this issue, nobody actually wants the two workspaces to be related.)
reference/workspaces.md also says:
When inside a subdirectory within the workspace, Cargo will automatically search the parent directories for a
Cargo.toml
file with a[workspace]
definition to determine which workspace to use.
and two things jump out at me:
The "when" clause ("When inside a subdirectory within the workspace") doesn't make sense, because there is no way for Cargo to know "this crate is not part of a workspace" without searching.
It doesn't actually say which Cargo.toml
wins if more than one parent has a [workspace]
table:
workspace.exclude
would exclude the present directory's crate?workspace.members
[^1], either directly or by some sequence of path
dependencies?
(This is a rhetorical question. I suspect it would be bad for both performance and layering, assuming that it is even possible to compute this.)[^1]: Wait, not workspace.includes
?
- Is it the outermost?
- Is it the innermost?
- Is this just against the rules?
If we're discussing possible design, I'd prefer the innermost since it follows quite a bit (most?) of similar concepts in our industry such as .gitignore
, .editorconfig
, etc. Most features tend to look up to find the innermost "thing" and, in some cases, might continue on either implicitly e.g., .gitignore
or explicitly if imported e.g., Directory.Build.props
(MSBuild). This would provide a consistent experience, IMO.
Problem
We have a monorepo where we want to manage some lints at the workspace level. We also have some CI scripts that set
RUSTFLAGS=-Dwarnings
. For crates that setlints.workspace = true
, lint configuration is ignored. I've even tried setting the priority as discussed in #12208 et. al. to no avail.If I simply set e.g.,
lints.clippy.useless_format = "allow"
in the specific crates'Cargo.toml
, no warnings-as-errors are emitted.Steps
Cargo.toml
with the content:Cargo.toml
with content:clippy::useless_format
warnings-as-errors are still emitted and the command fails.Possible Solution(s)
No response
Notes
No response
Version
No response