Home > Net >  Function return type mismatch doesn't produce any errors
Function return type mismatch doesn't produce any errors

Time:08-06

I'm new to Rust and trying to understand how reference works. Below is a simple function.

fn f1(x: &i32) -> &i32{
    x
}

Since x is of type &i32, return it directly matches the return type &i32. But I found that if I change the function to this, it also compiles without any problem:

fn f1(x: &i32) -> &i32{
    &x
}

Here x is of type &i32, &x is of type &&i32 and doesn't match the return type &i32. Why it compiles?

CodePudding user response:

This is a result of type coercion.

To make the language more ergonomic, a certain set of coercions are allowed in specific situations. One of the situations is determining the return value of a function.

Among the allowed coercions is this:

&T or &mut T to &U if T implements Deref<Target = U>

In this particular case, there is an implementation of the deref trait in the std library:

impl<T: ?Sized> const Deref for &T {
    type Target = T;

    #[rustc_diagnostic_item = "noop_method_deref"]
    fn deref(&self) -> &T {
        *self
    }
}

In your case, the target T is i32, and the trait is implemented for &T (ie. &&i32) so the value can be coerced from &&i32 to &i32.

CodePudding user response:

In your second function Rust automatically dereferences &x to x (i.e. &&i32 to &i32). That's done via the so called "Deref coercion".

Consider this example:

fn f1(x: &i32) -> &i32{
    let t1: &&i32 = &x;     // nothing special here
    let t2: &i32 = &x;      // this works too
    let t3: &i32 = &&&&x;   // this works too!
    let t4: i32 = x;        // this doesn't work though
    x
}
  • Related