Feature/error equality#1544
Conversation
| self.program_error == other.program_error | ||
| } | ||
| } | ||
| impl Eq for ProgramErrorWithOrigin {} |
There was a problem hiding this comment.
Why not add Eq to derive? Same question for AnchorError.
There was a problem hiding this comment.
Great question, I personally think that equality shouldn't be based for example on the source (file, line) of the error. The error code (the enum variant) uniquely identifies the 'type' of error so that's what I'm comparing.
There was a problem hiding this comment.
🤔 but my question was about Eq
impl Eq for ProgramErrorWithOrigin {}vs
#[derive(Eq)]There was a problem hiding this comment.
Let me check if it works and get back to you. I got inspired by a reference implementation.
There was a problem hiding this comment.
I tried that syntax (#[derive(Eq)]) and it seems to try to compare the fields one by one (fails because Source doesn't implement Eq) even when PartialEq is implemented manually, which is not the behavior I want. I think the empty impl is needed.
Another option is not implementing Eq at all and only having PartialEq which allows comparison already, but I don't know enough about rust to understand what is better.
There was a problem hiding this comment.
Why do you decide that Derive(Eq) doesn't work?
There was a problem hiding this comment.
I you check the expanded code for Eq, you can see that it reverts to comparing all 3 fields. The behavior I want is the one I implemented for PartialEq : only comparing 1 field, the error code. Therefore Deriv(Eq) doesn't achieve what I want.
There was a problem hiding this comment.
Do you mean these 3 lines?
let _: ::core::cmp::AssertParamIsEq<ProgramError>;
let _: ::core::cmp::AssertParamIsEq<Option<Source>>;
let _: ::core::cmp::AssertParamIsEq<Option<String>>;It's not fields comparing. It only checks that type implement Eq.
https://stdrs.dev/nightly/x86_64-unknown-linux-gnu/std/cmp/struct.AssertParamIsEq.html
There was a problem hiding this comment.
Ok . I misunderstood and thought this was actually also performing a comparison.
Still, I have no interest in some of these fields implementing Eq or PartialEq, because my comparison is based on only 1 of the fields.
I don't think adding Deriv(Eq) to all the structs and substructs is a cleaner solution than what I have now.
There was a problem hiding this comment.
The current solution is implementing PartialEq explicitly and empty Eq in the top level structure to explicitly mark it as Eq.
|
please add a test in (or lmk if I should do it, if you dont have the time) |
Motivation : Close #1538 . It is useful to compare errors in Rust side unit tests (ran with
cargo test), to make sure that my Anchor code fails with the expected error.Example code :
Self-contained example: https://github.com/guibescos/anchor-issue-error-equals
PR : Implements traits
EqandPartialEqforanchor_lang::error:Errorit only looks at the actual error codes and not the source.