Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source replacements are ignored when producing compilation units #14821

Open
P-E-Meunier opened this issue Nov 14, 2024 · 4 comments
Open

Source replacements are ignored when producing compilation units #14821

P-E-Meunier opened this issue Nov 14, 2024 · 4 comments
Labels
A-source-replacement Area: [source] replacement C-bug Category: bug Command-vendor S-triage Status: This issue is waiting on initial triage.

Comments

@P-E-Meunier
Copy link

P-E-Meunier commented Nov 14, 2024

Problem

When replacing sources in .cargo/config.toml so that two different sources point to the same vendored directory, cargo identifies a single package from two different sources as different, giving rise to a confusing error message where a type from a file is claimed to be distinct from itself:

error[E0308]: mismatched types
 --> src/main.rs:2:10
  |
2 |     b::b(c::C {});
  |     ---- ^^^^^^^ expected `c::C`, found `C`
  |     |
  |     arguments to this function are incorrect
  |
  = note: `C` and `c::C` have similar names, but are actually distinct types
note: `C` is defined in crate `c`
 --> /tmp/cargo-vendor-test/a/vendor/c/src/lib.rs:1:1
  |
1 | pub struct C {}
  | ^^^^^^^^^^^^
note: `c::C` is defined in crate `c`
 --> /tmp/cargo-vendor-test/a/vendor/c/src/lib.rs:1:1
  |
1 | pub struct C {}
  | ^^^^^^^^^^^^
  = note: perhaps two different versions of crate `c` are being used?
note: function defined here
 --> /tmp/cargo-vendor-test/a/vendor/b/src/lib.rs:1:8
  |
1 | pub fn b(_c: c::C) {}
  |        ^

Steps

  1. Clone https://github.com/P-E-Meunier/cargo-vendor-test
  2. Run a fake private registry from the root of the repo:
cd cargo-vendor-test
python -m http.server 8080 --bind 127.0.0.1 --directory .
  1. Run cargo vendor ../vendor from subdirectory a, which yields a wrong output (as per Cargo vendor doesn't replace all sources used by dependencies in its output #14729).
  2. The correct output, to be written to a/.cargo/config.toml, should be:
[source."sparse+http://localhost:8080/registry-y/"]
registry = "sparse+http://localhost:8080/registry-y/"
replace-with = "vendored-sources"

[source."sparse+http://localhost:8080/registry-x/"]
registry = "sparse+http://localhost:8080/registry-x/"
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "vendor"
  1. Run cargo build from subdirectory a.
@weihanglo
Copy link
Member

Ran cargo vendor didn't give me that output. With which version of Cargo under which directory should I run cargo vendor?

@P-E-Meunier
Copy link
Author

P-E-Meunier commented Nov 14, 2024

So, in my example repo, you need to run those steps from subdirectory a.
In #14729, you additionally need to start a fake private registry before, using the following command from the root of the repo:

python -m http.server 8080 --bind 127.0.0.1 --directory .

@weihanglo
Copy link
Member

In #14729, you additionally need to start a fake private registry before

You need to start the fake registry in either of those, otherwise Cargo cannot connect to them.

Anyway I can reproduce it now. This reminds me #10310 though they don't seem to be the same, and also one of the two c crate is vendored. The issue is kind of hitting several bad cases of cargo vendor?

@P-E-Meunier
Copy link
Author

It is indeed. This isn't an artificial case though, it was triggered by migrating a registry from one domain to another: some versions of some crates are mirrored on both, leading to this situation.

Fortunately, the fix for #14729 doesn't have any unintended effects: the only thing it does is replace more sources in .cargo/config.toml, which can't hurt if these registries aren't used, and fixes the issue when they are.

The fix for this issue is a little different, since it changes the rustc invocations when sources are replaced:

  • Currently, Cargo produces "metadata" or "extra filenames" to be prepended to build products based on the original source of the dependency. If you replaced a source with a local one in .cargo/config.toml, the metadata doesn't change, meaning that Cargo considers the two sources (original and replaced) to be the same. IIUC, both would be valid since an original crate and its replacement never appear in the same rustc invocation.
  • All Use the replacement source instead of the original source when generating -C metadata and -C extra-filename #14822 does is to use the replaced source to produce the metadata instead, meaning that (1) a replaced source won't be considered the same as its original source but (2) two sources replaced to the same one will be considered equal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-source-replacement Area: [source] replacement C-bug Category: bug Command-vendor S-triage Status: This issue is waiting on initial triage.
Projects
None yet
Development

No branches or pull requests

3 participants