foo which must build on 1.75 and uses Edition 2021
foo_tests which is a separate crate for tests. foo_test uses nightly and importantly uses Edition 2024
In my CI, I want to guarantee that foo can be built using:
cargo +1.75 build --package foo
The above command raises this error:
error: failed to load manifest for workspace member `foo_tests`
Caused by:
failed to parse manifest at `foo_tests/Cargo.toml`
Caused by:
feature `edition2024` is required
The package requires the Cargo feature called `edition2024`, but
that feature is not stabilized in this version of Cargo
(1.75.0 (1d8b05cdd 2023-11-20)).
Because foo_tests uses Edition 2024 (which wasn't stabilized until 1.85) i cannot compile foo using Rust 1.75. However, I'd like to essentially completely ignore the foo_tests member.
What should I do if I want to continue using nightly and Edition 2024 for foo_tests, but also be able to compile foo with Rust 1.75 and Edition 2021?
I want to use Edition 2024 in foo_tests to be able to use let chains
Workspace
Cargo.toml:
[workspace]
members = [
"foo",
"foo_tests"
]
foo/Cargo.toml:
[package]
name = "foo"
version = "0.1.0"
edition = "2021"
rust-version = "1.75.0"
foo_tests/Cargo.toml:
[package]
name = "foo_tests"
version = "0.1.0"
edition = "2024"
Things I have tried
Using the --exclude flag. Error: it can only be used with --workspace
Using --workspace --exclude foo_tests, but the same error is raised as in the original post
I suppose just removing "tests" from the workspace_members array manually will work. If nothing else, writing a small bash script and running it in the CI could work. I was hoping there is a way to do this without changing the filesystem though, I appreciate your answer
I just tried this, it seems to have the same effect as not including "foo_tests" at all. For example, rust-analyzer stops working inside of "foo_tests" when I do this. (and I would like it to continue working)
And If I have some lints I want to inherit from the workspace Cargo.toml:
[package]
name = "foo_tests"
version = "0.1.0"
edition = "2024"
[lints]
workspace = true
Running cargo clippy inside of foo_tests says it failed to find a workspace root:
error: failed to parse manifest at `/home/e/random/proj/foo_tests/Cargo.toml`
Caused by:
error inheriting `lints` from workspace root manifest's `workspace.lints`
Caused by:
failed to find a workspace root
exclude seems mostly useful when globs are involved
Essentially, the idea is that it continues to act like it is in a workspace under normal operations. But running with cargo +1.75 should act as if it is excluded
I think ideal behaviour would be if the --exclude flag allowed me to exclude a package before Cargo verifies that the package's Cargo.toml is valid. Essentially the same behaviour as if it was present in the workspace.exclude field
Such an --exclude flag would require the contents of the workspace Cargo.lock lockfile to change depending on if you pass the flag or not, which is a bad idea.
Another idea that popped into my mind is to set RUSTFLAGS="--edition 2024". However, this doesn't help because Cargo also implicitly passes --edition 2021 as it is specified in the manifest
error: Option 'edition' given more than once
Removing the edition field from the manifest defaults it to 2015 anyway. If there was a way to override the edition that Cargo passes to rustc it would work - So Cargo.toml says Edition 2021 but we pass RUSTFLAGS=--edition 2024
The edition of foo_tests would be 2021 by default. But when compiling with cargo test --package tests we would override it to 2024.