Unsigned-to-signed cast of the same width may wrap to a negative value

ID

rust.portability.cast_possible_wrap

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Numeric Conversion

Language

Rust

Description

Detects an as cast from an unsigned integer to a signed integer of the same width, and the pointer-width variants between usize, isize and 64-bit integers.

Rationale

A same-width unsigned-to-signed cast keeps every bit and only reinterprets the top one as a sign bit, so any value above the signed maximum silently becomes negative. The usize/isize forms are additionally target-dependent: what fits on a 64-bit build wraps on a 32-bit one, so the defect only shows up on part of the supported platforms.

The following code illustrates the pattern detected by this rule:

pub fn header_fields(len: usize, flags: u32, count: u64, tag: u16, marker: u8) -> i64 {
    // FLAGGED: Unsigned-to-signed cast of the same width may wrap to a negative value
    let offset = len as isize;
    // FLAGGED: Unsigned-to-signed cast of the same width may wrap to a negative value
    let signed_flags = flags as i32;
    // FLAGGED: Unsigned-to-signed cast of the same width may wrap to a negative value
    let signed_count = count as i64;
    // FLAGGED: Unsigned-to-signed cast of the same width may wrap to a negative value
    let signed_tag = tag as i16;
    // FLAGGED: Unsigned-to-signed cast of the same width may wrap to a negative value
    let signed_marker = marker as i8;
    // FLAGGED: Unsigned-to-signed cast of the same width may wrap to a negative value
    let wide_len = len as i64;
    offset as i64 + signed_flags as i64 + signed_count + signed_tag as i64 + signed_marker as i64 + wide_len
}

Remediation

Convert with i64::try_from(value) (or the matching try_into()) and handle the error, or cast to a wider signed type that can represent the whole unsigned range.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved