Lorenzo Yang
Lorenzo Yang

Reputation: 327

Is there a reference pattern happening here?

fn main() {
    // i passed a reference to a value of type i32
    print_type_of(&1); // but print: i32

    // but if i pass a double reference
    print_type_of(&&1); // it print &i32, not &&i32

    // i passed a referece to a value of type i32
    print_type_of_without_ampersand(&1); // now print: &i32 as expected

    referece_pattern(&1); // it works!

    // -> update <-

    // if i have
    let x = 1;
    let ref_x = &&x;

    // this is the implementation of Deref for &T
    // #[stable(feature = "rust1", since = "1.0.0")]
    // #[rustc_const_unstable(feature = "const_deref", issue = "88955")]
    // impl<T: ?Sized> const Deref for &T { //! -> here T should be &&i32 or &i32 ? <- !
    //     type Target = T;

    //     #[rustc_diagnostic_item = "noop_method_deref"]
    //     fn deref(&self) -> &T { // if here self is &&i32, and T should be &&i32 too
    //         *self // <- here  after deference self should be &i32, but &T is still &&i32 that is incompatible <- !
    //     }
    // }
    // -> end update <-
}

// amperand is before the type name
// so it should not be a reference pattern
fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

fn print_type_of_without_ampersand<T>(_: T) {
    println!("{}", std::any::type_name::<T>())
}

// reference pattern happens here
// amperand is before the parameter name
fn referece_pattern(&x: &i32) {
    assert!(x == 1);
    println!("it works!");
}

I also read this article on reference patterns,but it doesn't explain this.

update: I added new content in the code, about implementation of Deref for &T

Upvotes: 0

Views: 73

Answers (1)

cafce25
cafce25

Reputation: 27248

Not really sure where the confusion is.

fn print_type_of<T>(_: &T);

is a function with a type parameter T which receives a reference to T (&T) so if you give it a &i32 the type that reference 'points' to is i32 so when you later call type_name::<T>() you get i32 because that's what T is.

If T resolved to &i32 like you seem to be expeting then it would expect an item of type &&i32.

No reference pattern just the way the types check out once you do the substitution.

Upvotes: 4

Related Questions