For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/static_analysis/static_analysis_rules/rust-code-quality/almost-swapped.md. A documentation index is available at /llms.txt.

Assignments that look like a swap but overwrite both variables

This product is not supported for your selected Datadog site. ().

Metadata

ID: rust-code-quality/almost-swapped

Language: Rust

Severity: Error

Category: Error Prone

Description

The pattern a = b followed by b = a looks like an attempted variable swap, but it does not work. After a = b, the original value of a is lost. The second assignment b = a then copies the already-overwritten value back, leaving both variables with what b originally held.

This is one of the most common copy-paste bugs across any language.

How to remediate?

Use std::mem::swap to perform a correct in-place swap:

// Before (broken — both end up with b's original value)
a = b;
b = a;

// After (correct)
std::mem::swap(&mut a, &mut b);

Non-Compliant Code Examples

fn broken_swap() {
    let mut a = 1;
    let mut b = 2;
    a = b;
    b = a;
}

fn broken_swap_strings() {
    let mut x = String::from("hello");
    let mut y = String::from("world");
    x = y;
    y = x;
}

struct Point { x: i32, y: i32 }

impl Point {
    fn broken_self_swap(&mut self) {
        self.x = self.y;
        self.y = self.x;
    }
}

fn broken_obj_swap(mut obj: Point) {
    obj.x = obj.y;
    obj.y = obj.x;
}

fn broken_mixed_swap(mut obj: Point, mut y: i32) {
    obj.x = y;
    y = obj.x;
}

struct Wrapper {
    inner: Point,
}

impl Wrapper {
    fn broken_deep_swap(&mut self, other: &mut Wrapper) {
        self.inner.x = other.inner.x;
        other.inner.x = self.inner.x;
    }
}

Compliant Code Examples

fn correct_swap() {
    let mut a = 1;
    let mut b = 2;
    std::mem::swap(&mut a, &mut b);
}

fn unrelated_assignments() {
    let mut a = 1;
    let mut b = 2;
    a = b;
    b = 3;
}

fn self_assign() {
    let mut a = 1;
    // Structurally matches the query pattern but filtered by JS guard
    a = a;
    a = a;
}

struct Point { x: i32, y: i32 }

fn different_targets() {
    let mut obj = Point { x: 1, y: 2 };
    let mut other = Point { x: 3, y: 4 };
    // Not a swap — different objects, no mirror
    obj.x = other.x;
    other.y = obj.y;
}
https://static.datadoghq.com/static/images/logos/github_avatar.svg https://static.datadoghq.com/static/images/logos/vscode_avatar.svg jetbrains

Seamless integrations. Try Datadog Code Security