Skip to content

rustc: Gives inconsistent error messages if a dependency's dependency rlib has an unexpected filename #110460

@sdroege

Description

@sdroege
Contributor

Note that the following can only happen when calling rustc directly instead of going through cargo as cargo uses an rlib filename scheme that works and AFAIU doesn't allow overriding that anyway.

I tried this code:

  • a/lib.rs:
pub fn foo() -> i32 {
    123
}
  • b/lib.rs:
pub fn bar() -> i32 {
    some_a::foo() * 2
}
  • c/main.rs:
fn main() {
    //use b::bar;
    println!("{}", b::bar());
}

When compiling this as follows it will fail on the third rustc invocation.

mkdir -p builddir
rm -f builddir/liba.rlib
rm -f builddir/libb.rlib
rm -f builddir/c
rustc --crate-type rlib --edition=2021 --crate-name some_a --emit link -o builddir/liba.rlib a/lib.rs
rustc --crate-type rlib --edition=2021 --crate-name b --emit link -o builddir/libb.rlib --extern some_a=builddir/liba.rlib -L builddir b/lib.rs
rustc --crate-type bin --edition=2021 --crate-name c --emit link -o builddir/c --extern b=builddir/libb.rlib -L builddir c/main.rs

This gives the following error with latest stable (1.68.2) and also 660c966

error[E0463]: can't find crate for `some_a` which `b` depends on
 --> c/main.rs:3:20
  |
3 |     println!("{}", b::bar());
  |                    ^ can't find crate

error: aborting due to previous error

Note that the crate name of a is some_a while the rlib file is called liba.rlib. If changing either the crate name to a or the filename to libsome_a.rlib it works.

More confusingly, when using 660c966 and uncommenting the use b::foo line, it gives a different error

error[E0519]: the current crate is indistinguishable from one of its dependencies: it has the same crate-name `b` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
 --> c/main.rs:2:9
  |
2 |     use b::bar;
  |         ^

error[E0519]: the current crate is indistinguishable from one of its dependencies: it has the same crate-name `b` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
 --> c/main.rs:3:20
  |
3 |     println!("{}", b::bar());
  |                    ^

error: aborting due to 2 previous errors

I would expect

  1. both cases to give the same error message
  2. either using an "invalid" rlib name should fail directly (i.e. first rustc invocation above), or compilation of the above testcase should work fine

Activity

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Apr 17, 2023
jyn514

jyn514 commented on Apr 18, 2023

@jyn514
Member

either using an "invalid" rlib name should fail directly (i.e. first rustc invocation above), or compilation of the above testcase should work fine

this doesn't error in the first example because you pass --extern some_a=liba.rlib. I think if you remove that flag it would give the same error, and that seems correct to me.

I don't have an explanation for why it errors trying to load b, that bit seems like a bug.

sdroege

sdroege commented on Apr 18, 2023

@sdroege
ContributorAuthor

this doesn't error in the first example because you pass --extern some_a=liba.rlib. I think if you remove that flag it would give the same error, and that seems correct to me.

Yes then it fails directly as expected

I don't have an explanation for why it errors trying to load b, that bit seems like a bug.

Me neither but it behaves as if the rlib "remembers" the crate name but not the filename, and then it reconstructs the filename from the crate name and that doesn't work.

Mark-Simulacrum

Mark-Simulacrum commented on May 8, 2023

@Mark-Simulacrum
Member

Note that the crate name of a is some_a while the rlib file is called liba.rlib. If changing either the crate name to a or the filename to libsome_a.rlib it works.

This is expected behavior given the current implementation. To reduce work we prune the list of files we attempt to load to get at the embedded crate name etc. (See https://github.com/rust-lang/rust/blob/master/compiler/rustc_metadata/src/locator.rs#L73-L84 for a summary of the steps).

The indistinguishable error seems separate though, not quite sure there.

sdroege

sdroege commented on May 9, 2023

@sdroege
ContributorAuthor

That makes sense, thanks for checking. Considering that this is a constraint of the current implementation, it would probably make sense to check this during compilation of the first rlib (in this case) and fail directly as it won't be usable at a later step?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-metadataArea: Crate metadataC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @sdroege@GuillaumeGomez@Mark-Simulacrum@jyn514

        Issue actions

          rustc: Gives inconsistent error messages if a dependency's dependency rlib has an unexpected filename · Issue #110460 · rust-lang/rust