rust-lang / rust-lang/rustfmt

`cargo fmt` does not handle workspace member "Cargo.toml" being a symlink; gives error "Failed to find targets"

Open
#6,184 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-cargo-fmt C-bug
Dominant language
Rust
Stars
7k
Forks
1.1k
Avg merge
2d 13h
Merged PRs (30d)
24

Description

Problem

If a cargo workspace has a member project whose Cargo.toml is a symlink to a valid Cargo.toml, then running cargo fmt from the member directory fails with:

$ cargo fmt
Failed to find targets
This utility formats all bin and lib files of the current crate using rustfmt.

Usage: cargo fmt [OPTIONS] [-- <rustfmt_options>...]

Arguments:
  [rustfmt_options]...  Options passed to rustfmt

Options:
  -q, --quiet
          No output printed to stdout
  -v, --verbose
          Use verbose output
      --version
          Print rustfmt version and exit
  -p, --package <package>...
          Specify package to format
      --manifest-path <manifest-path>
          Specify path to Cargo.toml
      --message-format <message-format>
          Specify message-format: short|json|human
      --all
          Format all packages, and also their local path-based dependencies
      --check
          Run rustfmt in check mode
  -h, --help
          Print help

Here's a diff with a simple workspace that reproduces the issue.
You can git apply in an empty Git repo:

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..96ef6c0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..b7695d7
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,8 @@
+[workspace]
+resolver = "2"
+
+# lists member "concrete" crates that are in the virtual workspace
+members = [
+    "lib_a",
+    "main",
+]
diff --git a/lib_a/Cargo.toml b/lib_a/Cargo.toml
new file mode 120000
index 0000000..01b4380
--- /dev/null
+++ b/lib_a/Cargo.toml
@@ -0,0 +1 @@
+../lib_a_Cargo.toml
\ No newline at end of file
diff --git a/lib_a/src/lib.rs b/lib_a/src/lib.rs
new file mode 100644
index 0000000..211bfff
--- /dev/null
+++ b/lib_a/src/lib.rs
@@ -0,0 +1,3 @@
+pub fn add(left: usize, right: usize) -> usize {
+    left + right
+}
diff --git a/lib_a_Cargo.toml b/lib_a_Cargo.toml
new file mode 100644
index 0000000..bab3991
--- /dev/null
+++ b/lib_a_Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "lib_a"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/main/Cargo.toml b/main/Cargo.toml
new file mode 100644
index 0000000..bd9e3fa
--- /dev/null
+++ b/main/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "main"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+lib_a = { path = "../lib_a" }
diff --git a/main/src/main.rs b/main/src/main.rs
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/main/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+    println!("Hello, world!");
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+    println!("Hello, world!");
+}
Steps
  1. Create cargo workspace project
  2. Convert one member project's Cargo.toml to a symlink
  3. cd into member project directory from previous step
  4. run cargo fmt
Notes

Interestingly, even if all of the Cargo.toml files are symlinks, the issue does not occur when running cargo fmt from the root of the workspace.

Version

This occurs on the latest stable and nightly versions of rustfmt as of submitting:

$ cargo fmt --version
rustfmt 1.7.0-stable (9b00956 2024-04-29)

$ cargo +nightly fmt --version
rustfmt 1.7.0-nightly (a330e49 2024-06-04)

(Migrated from https://github.com/rust-lang/cargo/issues/14012 since cargo-fmt lives in rust repo, not cargo repo)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue provides a reproducible workspace diff with lib_a/Cargo.toml symlinked to ../lib_a_Cargo.toml; start by applying it and running cargo fmt from lib_a, then compare with the workspace-root invocation. Done means the member-directory command no longer reports “Failed to find targets” and formats the member, while the existing root behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.