# How does `.into()` work? > [!summary] > - `.into()` is shorthand for calling `U::from(self)` > - It relies on `From<T> for U`, which auto-implements `Into<U> for T` > - Type inference or [[Explicit type annotations|explicit type annotation]] tells Rust what type to convert into > - If no `From<T>` exists,`.into()` won’t work When using `call.into()`, Rust uses **type inference** or **[[Explicit type annotations|explicit type annotations]]** to determine what type it should convert into. ## Example ```rust let s: String = "hello".into(); // `&str` -> `String` ``` The compiler knows that `s` is a `String`, so it looks for `Into<String>` implementations. Rust automatically provides `Into<T>` [implementations](https://github.com/rust-lang/rust/blob/1.85.0/library/core/src/convert/mod.rs#L748-L763) if `From<T>` exists: ```rust impl<T, U> Into<U> for T where U: From<T>, { fn into(self) -> U { U::from(self) } } ``` `String` [implements](https://github.com/rust-lang/rust/blob/1.85.0/library/alloc/src/string.rs#L2868-L2878) `From` trait: ```rust impl From<&str> for String { fn from(s: &str) -> Self { String::from(s) } } ``` - If `From<T> for U` exists, then `T.into()` will work to produce `U` - `.into()` is just calling `U::from(self)`, but in a more generic way ```rust let x: i32 = 42; let y: i64 = x.into(); // Implicit conversion ``` - `i32` implements `From<i32> for i64`, so `.into()` works. > [!warning] > If the target type (`y: i64`) wasn’t specified, Rust would throw an error because it wouldn’t know which type to convert into.