From 29722ea0c8420281eafe16dedc4c85e313901a73 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Fri, 20 Dec 2024 13:30:10 +0000 Subject: [PATCH] Arbitrary self types v2: book changes. Preliminary book changes for Arbitrary Self Types v2. The listing number is currently out of order and this will need fixing, I suspect, but keeping things there unchanged for reviewability meanwhile. --- .../listing-15-30/Cargo.lock | 7 +++++ .../listing-15-30/Cargo.toml | 6 +++++ .../listing-15-30/src/main.rs | 27 +++++++++++++++++++ src/ch15-02-deref.md | 19 +++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 listings/ch15-smart-pointers/listing-15-30/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-30/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-30/src/main.rs diff --git a/listings/ch15-smart-pointers/listing-15-30/Cargo.lock b/listings/ch15-smart-pointers/listing-15-30/Cargo.lock new file mode 100644 index 0000000000..1848c41a50 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-30/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "deref-method-example" +version = "0.1.0" diff --git a/listings/ch15-smart-pointers/listing-15-30/Cargo.toml b/listings/ch15-smart-pointers/listing-15-30/Cargo.toml new file mode 100644 index 0000000000..5b59aec5af --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-30/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-method-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-30/src/main.rs b/listings/ch15-smart-pointers/listing-15-30/src/main.rs new file mode 100644 index 0000000000..d308a54942 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-30/src/main.rs @@ -0,0 +1,27 @@ +#![feature(arbitrary_self_types)] +// TODO remove before we land this + +use std::ops::Deref; + +struct CustomSmartPointer(T); + +impl Deref for CustomSmartPointer { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +struct Pointee; + +impl Pointee { + fn hello(self: &CustomSmartPointer) { + println!("Hello!"); + } +} + +fn main() { + let ptr = CustomSmartPointer(Pointee); + ptr.hello(); +} diff --git a/src/ch15-02-deref.md b/src/ch15-02-deref.md index a0b00e1a7e..b2b7be3017 100644 --- a/src/ch15-02-deref.md +++ b/src/ch15-02-deref.md @@ -260,6 +260,25 @@ match the parameter’s type. The number of times that `Deref::deref` needs to b inserted is resolved at compile time, so there is no runtime penalty for taking advantage of deref coercion! +### Calling methods on smart pointers + +If your smart pointer implements `Deref` (or if it implements another trait, +called `Receiver`) then methods on the referent can also receive their `self` +type using your smart pointer. + ++ +```rust +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-30/src/main.rs:here}} +``` + + + +You should normally implement `Deref` rather than directly implementing +`Receiver`. You'd implement `Receiver` only in cases where it's not safe to +create a reference to your smart pointer's referent, often in cases involving +cross-language interoperability. + ### How Deref Coercion Interacts with Mutability Similar to how you use the `Deref` trait to override the `*` operator on