How to assert a vector of enums?


#1

Hi, I’m currently in the middle of porting the super tiny compiler from JavaScript to Rust. I published a very early non-working version, because I’d like to know what is the best way to compare a vector containing of enums in a test?

For now I used a very dumb way: compare the length and the loop of the items in the vector to compare the items. Ideally I’d like to do this in one step (just compare the vectors - like the deepStrictEqual in JavaScript), but for now I’d like to know why I can’t compare my enums?

My enum Token derives the PartialEq trait here. According to similar questions I found on the internet this should be enough. However when I try to assert the enums here I get this error:

error[E0277]: the trait bound `&the_super_tiny_compiler::Token: std::cmp::PartialEq<the_super_tiny_compiler::Token>` is not satisfied
  --> tests/test.rs:36:9
   |
36 |         assert_eq!(token, tokenizedInput[i]);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::PartialEq<the_super_tiny_compiler::Token>` is not implemented for `&the_super_tiny_compiler::Token`
   |
   = help: the following implementations were found:
   = help:   <the_super_tiny_compiler::Token as std::cmp::PartialEq>
   = note: this error originates in a macro outside of the current crate

Why does it say _ “is not implemented”_? I thought this would be done by #[derive(PartialEq)]?

Thank you! :heart:


#2

Note the error message says “&the_super…” - you implemented PartialEq for the enum, but you have a reference (&) here coming from the iterator. So, just deref to get the value.


#3

Hey, I’ve done super tiny compiler in Rust as well :slight_smile: The code is awful, because I was experimenting with different AST representations, but I kinda like the (few :frowning: ) tests : https://github.com/matklad/compilers/blob/72d3c92c8f726c582ddf6ef8ce677559ec320035/super_tiny_compiler/src/rst.rs#L146

The idea is not to compare tokens or syntax trees directly (it’s hard to construct expected trees by hand), but instead serialize them to strings, and compare strings.


#4

@vitalyd Thanks. Writing assert_eq!(token, &tokenizedInput[i]); worked. So can you tell, if there is a canonical way to compare two vectors in Rust?

@matklad Thank you for the link.


#5

Vec implements impl<'a, 'b, A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B>, so you ought to be able to just compare them via == when the inner type(s) are PartialEq.


#6

Wow. You’re right. I tried that earlier before I used #[derive(PartialEq)] and thought it was not possible in general. Thank you very much.