Assert_eq! differ with different order

I'm confused about:

2024-09-21_172921

Does the order of the assert_eq! matter? Wish some advice and thanks!

In Rust, the ability to compare for equality is done through traits (PartialEq and Eq); you can find the implementation of these traits for a given type in the docs and, among them, you'll find one for Vec<T> when comparing it with an array, but you won't find one for [T; N] when comparing it with a Vec. In other words, it's a missing implementation... but you'll find one for comparing arrays with slices, so it's just a matter of converting the vector to a slice:

fn main() {
    let a = [0, 1, 2];
    let v: Vec<i32> = (0..3).collect();
    assert_eq!(v, a); // right
    assert_eq!(a, v.as_slice()); // Now it works 
}
1 Like

In "trait based" languages (I don't know what the proper term is, but Scala's implicits, meta-driven languages etc.) I wish there was a code-action for showing the exact implementations that are at play, so this would expand to showing exactly what traits, types, and fn calls are being used.

This would be generally useful and make discoverability and understanding much easier I think.

1 Like

In the playground, you can click tools > expand macros. You'll find that is has nothing to do with assert_eq, but the error comes from calling ==.

1 Like

thanks @jendrikw - that isn't quite what I wanted ;-). I wanted it to tell me, for example, which impls are used when traits are in play, for example.

So, if I had x.into(), which particular (potential chain of) impl From<..> calls are executed.

2 Likes

If you have code that compiles, you can use the playground to show the MIR (mid-level intermediate representation) the compiler has produced by clicking on the three dots next to the run/build/test button and selecting "MIR".

If the code doesn't compile, the answer lies in the error message:

help: the trait `PartialEq<Vec<i32>>` is not implemented for `[{integer}; 3]`

This means the compiler has decided it needs an impl PartialEq<Vec<i32>> for [{integer}; 3] where {integer} means the type of the integer literal is not yet known. The error message doesn't have the complete truth because there may be other possible trait implementations the compiler could have considered ok, but it usually only shows one hint at a time.

1 Like

Thanks

rust-analyser's Goto Definition (F12 or Alt+Click or Cmd+Click) does exactly that.

Blockquote rust-analyser's Goto Definition (F12 or Alt+Click or Cmd+Click) does exactly that.

I don't think that's true - it won't go into the struct that .into() resolves to, for example, unless the target type is explicitly defined.

unfortunately it's often hard to reduce the problem down into a sufficiently small case that can be put into the playground. Unless there's a way of generating MIR outside of the playground/hooking the playground into your actual app?

Well that's more an Into thing than a r-a thing. All Into::into are from the blanket implementation, so you always get that. Try something else, Some(1i32).into_iter() for example, and you will get redirected to impl<T> IntoIterator for Option<T>.

You can use cargo-show-asm with the --mir option to output MIR for your code.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.