Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

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:
// Syntactic sugar
a == b;

// Desugared compiler representation
PartialEq::eq(&a, &b);

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.
pub trait PartialEq<Rhs = Self>
where
    Rhs: ?Sized,
{
    fn eq(&self, other: &Rhs) -> bool;

    // Provided by default, invoked by the `!=` operator
    fn ne(&self, other: &Rhs) -> bool {
        !self.eq(other)
    }
}
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:
pub trait Eq: PartialEq<Self> {}

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.
#[derive(PartialEq)]
struct Point {
    x: i32,
    y: i32,
}
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.
struct Wrapper(String);

// Enables `Wrapper == &str`
// Because `Rhs` is `&str`, the `other` parameter becomes `&&str` (`&Rhs`).
impl PartialEq<&str> for Wrapper {
    fn eq(&self, other: &&str) -> bool {
        self.0 == *other
    }
}

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:
let a = 5;
let b = &5;

// a == b; // ERROR: no implementation for `{integer} == &{integer}`
*b == a;   // OK: explicitly dereferences b to match a's type
&a == b;   // OK: explicitly references a to match b's type
Master Rust with Deep Grasping Methodology!Learn More