---
title: Use From/TryFrom over `as` to avoid silent numeric coercion
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Static Code Analysis (SAST) > SAST
  Rules > Use From/TryFrom over `as` to avoid silent numeric coercion
---

# Use From/TryFrom over `as` to avoid silent numeric coercion

{% 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/as-conversions`

**Language:** Rust

**Severity:** Warning

**Category:** Error Prone

**CWE**: [681](https://cwe.mitre.org/data/definitions/681.html)

**Related CWEs**:

- [197](https://cwe.mitre.org/data/definitions/197.html)

## Description{% #description %}

Using `as` for numeric type conversions can silently truncate, wrap, or coerce values in ways that are easy to miss. For example, `300u32 as u8` evaluates to `44` because the value wraps around, and `1.9f64 as u8` truncates to `1`. Even widening casts that happen to be safe today can become lossy if the source type changes. Explicit conversions make the intent clear and surface potential issues at compile time.

## How to remediate?{% #how-to-remediate %}

Replace `as` casts with explicit conversions using `From` or `TryFrom`:

```rust
// Before — silently truncates if n > 255
let x = n as u8;

// After — fails to compile if the conversion could truncate (widening is infallible)
let x = u8::from(n);       // use when the source type guarantees no truncation
let x = u8::try_from(n)?;  // use when the conversion may fail (returns Result)
```

For pointer-to-integer conversions, prefer `.addr()` over `ptr as usize`.

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```rust
fn truncating(n: u32) -> u8 {
    n as u8
}

fn widening_as(x: i32) -> i64 {
    x as i64
}

fn float_precision(x: f64) -> f32 {
    x as f32
}

fn bool_as_int(flag: bool) -> u8 {
    flag as u8
}

fn ptr_to_addr(ptr: *const i32) -> usize {
    ptr as usize
}
```

## Compliant Code Examples{% #compliant-code-examples %}

```rust
fn widening(x: i32) -> i64 {
    i64::from(x)
}

fn narrowing(n: i32) -> u8 {
    u8::try_from(n).unwrap_or(0)
}

fn bool_to_int(flag: bool) -> u8 {
    u8::from(flag)
}

fn pointer_cast(ptr: *const i32) -> *const u8 {
    ptr as *const u8
}
```
  Seamless integrations. Try Datadog Code SecurityDatadog Code Security 
{% icon name="icon-external-link" /%}
 