Skip to content

"Mismatched types" error when comparing the same struct for equality when referenced from two libraries #87534

New issue

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

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

Already on GitHub? # to your account

Closed
andyyu2004 opened this issue Jul 28, 2021 · 2 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@andyyu2004
Copy link

I tried this code:

// in a/src/lib.rs which has a dependency on crate b
pub fn mk_struct() -> b::SomeStruct {
    b::SomeStruct
}

#[test]
fn wer() {
    // compiles
    assert_eq!(self::mk_struct(), b::SomeStruct);
}

// in b/src/lib.rs which has dev-dependency on crate a
#[derive(PartialEq, Eq, Debug)]
pub struct SomeStruct;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        // doesn't compile with following error
        // expected struct `b::SomeStruct`, found struct `SomeStruct`
        a::mk_struct() == super::SomeStruct;
    }
}

I would expect this code to compile but instead it emits the error "expected struct b::NonGeneric, found struct NonGeneric" which is odd as I would think they are the same type.

Meta

Reproducible on 1.56.0-nightly.
Repository: https://github.com/andyyu2004/rust-bug-repro

@andyyu2004 andyyu2004 added the C-bug Category: This is a bug. label Jul 28, 2021
@Enselic
Copy link
Member

Enselic commented Jul 10, 2024

Triage: If we build with cargo -vvvv test we get more info on exactly what happens. Here are the commands that are run. I have only kept relevant differences.

First b is built like a library, since a depends on it.

rustc --crate-name b b/src/lib.rs --crate-type lib --emit=dep-info,metadata,link        -C metadata=f4816aced84dfaf9 -C extra-filename=-f4816aced84dfaf9 

Then a is built as a library, referencing the b lib that was just built.

rustc --crate-name a a/src/lib.rs --crate-type lib --emit=dep-info,metadata,link        -C metadata=ca41d80a37a85d0f -C extra-filename=-ca41d80a37a85d0f --extern b=/home/martin/src/rust-bug-repro/target/debug/deps/libb-f4816aced84dfaf9.rmeta`

Now a is built as a test, depending on the b lib that is already built. Nothing strange.

rustc --crate-name a a/src/lib.rs                  --emit=dep-info,link          --test -C metadata=df26514d981f8ad0 -C extra-filename=-df26514d981f8ad0 --extern b=/home/martin/src/rust-bug-repro/target/debug/deps/libb-f4816aced84dfaf9.rlib`

Now b is built as a test, depending on the a lib that depends on the b lib that is already built.

rustc --crate-name b b/src/lib.rs                  --emit=dep-info,link          --test -C metadata=6107a1a1766b86b2 -C extra-filename=-6107a1a1766b86b2 --extern a=/home/martin/src/rust-bug-repro/target/debug/deps/liba-ca41d80a37a85d0f.rlib`

so now we have two instances of the b crate. The one being compiled (6107a1a1766b86b2), and the one indirectly referenced by a (f4816aced84dfaf9).

The error given nowadays is I think pretty clear. Can you think of a way to make the error message even clearer?

error[E0308]: mismatched types
  --> b/src/lib.rs:10:27
   |
10 |         a::mk_struct() == super::SomeStruct;
   |         --------------    ^^^^^^^^^^^^^^^^^ expected `b::SomeStruct`, found `SomeStruct`
   |         |
   |         expected because this is `b::SomeStruct`
   |
   = note: `SomeStruct` and `b::SomeStruct` have similar names, but are actually distinct types
note: `SomeStruct` is defined in the current crate
  --> b/src/lib.rs:2:1
   |
2  | pub struct SomeStruct;
   | ^^^^^^^^^^^^^^^^^^^^^
note: `b::SomeStruct` is defined in crate `b`
  --> /home/martin/src/rust-bug-repro/b/src/lib.rs:2:1
   |
2  | pub struct SomeStruct;
   | ^^^^^^^^^^^^^^^^^^^^^
   = note: the crate `b` is compiled multiple times, possibly with different configurations

For more information about this error, try `rustc --explain E0308`.
error: could not compile `b` (lib test) due to 1 previous error

@Enselic Enselic added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage-legacy labels Jul 10, 2024
@andyyu2004
Copy link
Author

Thanks for the explanation. I think #105793 makes this error abundantly clear now.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

3 participants