2 ms·
The "lazy borrowing" was just a personal mental model, not any claim about how things are implemented under the hood. That said, I think all your examples are h
by saghm 3y ago
The "lazy borrowing" was just a personal mental model, not any claim about how things are implemented under the hood. That said, I think all your examples are hinging on very specific behavior from the `Deref` and `DerefMut` traits that might not apply generally.
Looking at the generating MIR output[0] from your second example changed to use the deref syntax from the first one, it seems like the value of `mut1` is silently getting downgraded to `&[&str]` under the hood, presumably due to the fact that the rules for `Deref`[1] and `DerefMut`[1] allow the compiler to liberally substitute dereferences with calls to those trait methods, which crucially allows the compiler to change the result of dereferencing `&mut` to return a shared reference. This is actually almost exactly what was being suggested in the sibling comment here: https://news.ycombinator.com/item?id=39557697 https://news.ycombinator.com/item?id=39557697.
[0]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=30c1c3fda19450fee4519eb49720e2a2 https://play.rust-lang.org/?version=nightly&mode=debug&editi...
[1]: https://doc.rust-lang.org/std/ops/trait.Deref.html#deref-coercion https://doc.rust-lang.org/std/ops/trait.Deref.html#deref-coe...
[2]: https://doc.rust-lang.org/std/ops/trait.DerefMut.html#mutable-deref-coercion https://doc.rust-lang.org/std/ops/trait.DerefMut.html#mutabl...
(edited shortly after posting to rephrase without needing to use deref operator in the in-line snippets because it messed up the italics of all of the text after like this)
- legerdemain 3y agoWould it be easier to convince you if I replaced String with a type that doesn't implement Deref or DerefMut? I do wish you had tried it yourself, because I hope your goal is to learn something about Rust and not just to argue down someone on the Internet. fn main() { #[derive(Debug)] struct X(i32); let mut s = X(1); // create value let mut1: &mut _ = &mut s; // create a ref mut *mut1 = X(2); // write through mut1 println!("using mut1: {mut1:?}"); // print mut1 let mut2: &mut _ = &mut *mut1; // create a second ref mut *mut2 = X(3); // write through mut2 println!("using mut2: {mut2:?}"); // print mut2 *mut1 = X(4); // write through mut1 again println!("using mut1: {mut1:?}"); // print mut1 }
- saghm 3y ago> Would it be easier to convince you if I replaced String with a type that doesn't implement Deref or DerefMut? `&T` and `&mut T` implement Deref (and `&mut T` implements DerefMut) for all types[0]. > I do wish you had tried it yourself, because I hope your goal is to learn something about Rust and not just to argue down someone on the Internet. I'm pretty confused about the sharp turn you took here. I happen to think your explanation of what's going on in the code you posted is incorrect, and if you truly are hoping that others here are trying to learn, you'd be more successful in helping them by not acting as if anyone who doesn't think you're correct is acting in bad faith. From my perspective, you completely misread what I said about Deref in my last comment and then didn't follow the advice you're giving about trying out the change I suggested with your own code because the same error occurs with the struct you define if you don't use the deref operator[1]. I'm open to the idea that I'm wrong about `Deref` being the cause of all this, but you don't really seem to be open the idea that you might be incorrect, which comes across as fairly arrogant given that you haven't really demonstrated that you understand that I'm talking about the `Deref` implementation on the _reference_, not the underlying value,. [0]: https://doc.rust-lang.org/src/core/ops/deref.rs.html#164 https://doc.rust-lang.org/src/core/ops/deref.rs.html#164 [1]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=f830c421eccef01fb4eb2503bb47c508 https://play.rust-lang.org/?version=nightly&mode=debug&editi...
- legerdemain 3y agoI am confused by your responses because the "reborrowing" mechanism in the Rust compiler is pretty widely discussed. https://smallcultfollowing.com/babysteps/blog/2013/11/20/parameter-coercion-in-rust/ https://smallcultfollowing.com/babysteps/blog/2013/11/20/par... https://haibane-tenshi.github.io/rust-reborrowing/ https://haibane-tenshi.github.io/rust-reborrowing/ https://stackoverflow.com/questions/62960584/do-mutable-references-have-move-semantics https://stackoverflow.com/questions/62960584/do-mutable-refe... Meanwhile, you are insisting on reasoning about Rust from first principles and making lists of links to documentation that is, at best, tangentially relevant. For example, the fact that `&T` implements Deref is not relevant here. Applying Deref::deref to a &T returns a &T. For most intents, it's a no-op.