# Type Inference Rust will look at how the variable is _used_ to determine the type: ```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); } ```
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 to write a more concise code. The following code tells the compiler to copy into a certain generic container without the code ever explicitly specifying the contained type, using `_` as a placeholder: ```rust,editable fn main() { let mut v = Vec::new(); v.push((10, false)); v.push((20, true)); println!("v: {v:?}"); let vv = v.iter().collect::>(); println!("vv: {vv:?}"); } ``` [`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.collect) relies on `FromIterator`, which [`HashSet`](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) implements.