top | item 44618731

(no title)

alilleybrinker | 7 months ago

For the disjoint field issues raised, it’s not that the borrow checker can’t “reason across functions,” it’s that the field borrows are done through getter functions which themselves borrow the whole struct mutably. This could be avoided by making the fields public so they can be referenced directly, or if the fields needs to be passed to other functions, just pass the the field references rather than passing the whole struct.

There are open ideas for how to handle “view types” that express that you’re only borrowing specific fields of a struct, including Self, but they’re an ergonomic improvement, not a semantic power improvement.

discuss

order

mirashii|7 months ago

> For the disjoint field issues raised, it’s not that the borrow checker can’t “reason across functions,” it’s that the field borrows are done through getter functions which themselves borrow the whole struct mutably

Right, and even more to the point, there's another important property of Rust at play here: a function's signature should be the only thing necessary to typecheck the program; changes in the body of a function should not cause a caller to fail. This is why you can't infer types in function signatures and a variety of other restrictions.

JoshTriplett|7 months ago

Exactly. We've talked about fixing this, but doing so without breaking this encapsulation would require being able to declare something like (syntax is illustrative only) `&mut [set1] self` and `&mut [set2] self`, where `set1` and `set2` are defined as non-overlapping sets of fields in the definition of the type. (A type with private fields could declare semantic non-overlapping subsets without actually exposing which fields those subsets consist of.)

saghm|7 months ago

It's super easy to demonstrate your point with the first example the article gives as well; instead of separate methods, nothing prevents defining a method `fn x_y_mut(&mut self) -> (&mut f64, &mut 64)` to return both and use that in place of separate methods, and everything works! This obviously doesn't scale super well, but it's also not all that common to need to structure this way in the first place.