---
minutes: 3
---

# Type Inference

Rust will look at how the variable is _used_ to determine the type:

<!-- mdbook-xgettext: skip -->

```rust,editable
fn takes_u32(x: u32) {
    println!("u32: {x}");
}

fn takes_i8(y: i8) {
    println!("i8: {y}");
}

fn main() {
    let x = 10;
    let y = 20;

    takes_u32(x);
    takes_i8(y);
    // takes_u32(y);
}
```

<details>

This slide demonstrates how the Rust compiler infers types based on constraints
given by variable declarations and usages.

It is very important to emphasize that variables declared like this are not of
some sort of dynamic "any type" that can hold any data. The machine code
generated by such declaration is identical to the explicit declaration of a
type. The compiler does the job for us and helps us write more concise code.

When nothing constrains the type of an integer literal, Rust defaults to `i32`.
This sometimes appears as `{integer}` in error messages. Similarly,
floating-point literals default to `f64`.

```rust,compile_fail
fn main() {
    let x = 3.14;
    let y = 20;
    assert_eq!(x, y);
    // ERROR: no implementation for `{float} == {integer}`
}
```

</details>
