Confusion when dereference is needed or not

From the Rust by exemples web pages, I have this code:

struct Point {
    x: f32,
    y: f32,
}

struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

I added a function to make a square out of a point (reference) and a side length:

fn square(point: &Point, side: f32) -> Rectangle {
    let Point { x, y } = point;
    return Rectangle{top_left: Point{x: x, 
                                     y: y
                                    },
                     bottom_right: Point{x: x + side,
                                         y: y + side}
                    };
}

As a shortcut I recover the x and y fields as variables.
The compiler outputs:

error[E0308]: mismatched types
  --> ch3_1structs_b.rs:39:41
   |
39 |     return Rectangle{top_left: Point{x: x, 
   |                                         ^ expected `f32`, found `&f32`
   |
help: consider dereferencing the borrow
   |
39 |     return Rectangle{top_left: Point{x: *x, 
   |                                         +

(same for y)

So I fixed it with:

fn square(point: &Point, side: f32) -> Rectangle {
    let Point { x, y } = point;
    return Rectangle{top_left: Point{x: *x, 
                                     y: *y
                                    },
                     bottom_right: Point{x: x + side,
                                         y: y + side}
                    };
}

And the compiler is now happy.

What I don't understand is why the dereferences were not needed for bottom_right as well:

                     bottom_right: Point{x: *x + side,
                                         y: *y + side}
                    };

???

There's an Add trait implementation that covers the use case of adding an &f32 to an f32: Add in std::ops - Rust

Thanks for the suggestion.
However, I was not looking at an alternative.
I was rather expecting an the answer that would explain why it is necessary to add a * to x and y here:

top_left: Point{x: *x, 
                y: *y

but not here:

bottom_right: Point{x: x + side,
                    y: y + side

My (most likely incorrect) conclusion up to now is that in Rust, once a variable is dereferenced once, there's no need to dereference any further, until the end of the scope...

It isn't a suggestion, it's the explanation for your question.

Ho sorry, I see now.

Then that explains why the following works without using * anywhere:

    return Rectangle{top_left: Point{x: x + 0.0, 
                                     y: y + 0.0
                                    },
                     bottom_right: Point{x: x + side,
                                         y: y + side}
                    };

Yup, exactly :slight_smile:.