---
title: Assignments that look like a swap but overwrite both variables
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Static Code Analysis (SAST) > SAST
  Rules > Assignments that look like a swap but overwrite both variables
---

# Assignments that look like a swap but overwrite both variables

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**ID:** `rust-code-quality/almost-swapped`

**Language:** Rust

**Severity:** Error

**Category:** Error Prone

## Description{% #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?{% #how-to-remediate %}

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

```rust
// 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{% #non-compliant-code-examples %}

```rust
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{% #compliant-code-examples %}

```rust
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;
}
```
  Seamless integrations. Try Datadog Code SecurityDatadog Code Security 
{% icon name="icon-external-link" /%}
 