Skip to main content
The == operator in Rust is a binary comparison operator used to evaluate value equality between two expressions. At the compiler level, it is syntactic sugar for the eq method defined in the std::cmp::PartialEq core trait. When the compiler encounters a == b, it automatically rewrites the expression as a borrowed method call:

The PartialEq Trait

The behavior of the == operator is strictly governed by the PartialEq trait. For the operator to compile, the type of the left-hand operand must implement PartialEq<Rhs> where Rhs is the type of the right-hand operand.
By default, Rhs defaults to Self, meaning the == operator typically compares two instances of the exact same type. Rust does not perform implicit type coercion during equality checks; comparing an i32 to an i64 using == will result in a compiler error unless a specific PartialEq<i64> is implemented for i32.

Partial Equivalence vs. Strict Equivalence

Rust separates equality into two traits: PartialEq and Eq. The == operator only requires PartialEq, which represents a partial equivalence relation. This means the comparison must be symmetric (a == b implies b == a) and transitive (a == b and b == c implies a == c), but it does not need to be reflexive (a == a). The primary technical reason for this distinction is floating-point numbers (f32 and f64). According to the IEEE 754 standard, NaN == NaN evaluates to false. Therefore, floats implement PartialEq but cannot implement Eq. The Eq trait is a marker trait that inherits from PartialEq to indicate a strict equivalence relation (adding reflexivity). It provides no additional methods to the == operator:

Implementation Mechanics

For custom data structures (structs and enums), the == operator is not available by default. It must be explicitly enabled. Derived Implementation: The compiler can automatically generate the PartialEq implementation using the #[derive] macro. This generates a structural equality check, recursively applying the == operator to all fields or variants.
Manual Implementation: If custom comparison logic is required (e.g., ignoring a specific field or comparing across different types), PartialEq must be implemented manually. To enable cross-type comparisons, the Rhs type must exactly match the right-hand operand.

Memory, Ownership, and References

Because PartialEq::eq takes its arguments by reference (&self and &Rhs), the == operator does not consume or take ownership of its operands. It strictly borrows them for the duration of the comparison evaluation. Unlike method calls (the . operator), Rust’s auto-dereferencing rules do not apply to the == operator. Comparing a reference &T to a value T (e.g., &1 == 1) will result in a compiler error due to a type mismatch, unless a specific PartialEq implementation exists for those exact types. To compare a reference and a value, you must manually align the types using the dereference (*) or reference (&) operators:
Tired of Poor Rust Skills? Fix That With Deep Grasping!Learn More