`cargo publish` ignores Cargo.lock in workspace


I have found that using cargo publish on a binary crate inside a workspace ignores the Cargo.lock in the workspace directory, whereas cargo build considers it. However, when moving the Cargo.lock inside the binary crate root, both commands consider it.

To set up the environment:

mkdir foo # our workspace
cd foo
echo -e '[workspace]\nmembers = ["bar"]' > Cargo.toml
cargo new bar # our binary
cd bar
cargo add beef@=0.5.0
cargo check # generate Cargo.lock with beef locked to 0.5.0
cargo add beef@0.5.0 # relax bounds
cd ..

Now run:

cargo build # uses beef 0.5.0 ✅
cargo publish --dry-run --allow-dirty -p bar # uses beef 0.5.2 (0.5.0 expected) ❌
cp Cargo.lock bar/
cargo publish --dry-run --allow-dirty -p bar # uses beef 0.5.0 ✅

(Using cargo publish with --locked does not change anything.)

Doesn't Cargo.lock in a workspace apply to all crates inside the workspace? To cite the Cargo book:

The key points of workspaces are:

  • All packages share a common Cargo.lock file which resides in the workspace root.
  • [...]

Can I make cargo publish consider my Cargo.lock in the workspace root? Or what is the correct way to deal with this?

[EDIT]: I found that also cargo package --allow-dirty -p bar does not use the workspace Cargo.lock --- the Cargo.lock in the produced crate makes a reference to beef 0.5.2, not 0.5.0.
I believe that this means that crates published from workspaces, even when installed with cargo install --locked, do not respect the workspace's Cargo.lock. That sounds like a serious bug to me.

I created an issue, and it seems that this is indeed a bug.