2525//! # Generic Implementations
2626//!
2727//! - [`AsRef`] and [`AsMut`] auto-dereference if the inner type is a reference
28+ //! (but not generally for all [dereferenceable types][core::ops::Deref])
2829//! - [`From`]`<U> for T` implies [`Into`]`<T> for U`
2930//! - [`TryFrom`]`<U> for T` implies [`TryInto`]`<T> for U`
3031//! - [`From`] and [`Into`] are reflexive, which means that all types can
@@ -109,10 +110,12 @@ pub const fn identity<T>(x: T) -> T {
109110/// If you need to do a costly conversion it is better to implement [`From`] with type
110111/// `&T` or write a custom function.
111112///
113+ /// # Relation to `Borrow`
114+ ///
112115/// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in a few aspects:
113116///
114117/// - Unlike `AsRef`, [`Borrow`] has a blanket impl for any `T`, and can be used to accept either
115- /// a reference or a value.
118+ /// a reference or a value. (See also note on `AsRef`'s reflexibility below.)
116119/// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for a borrowed value are
117120/// equivalent to those of the owned value. For this reason, if you want to
118121/// borrow only a single field of a struct you can implement `AsRef`, but not [`Borrow`].
@@ -122,9 +125,66 @@ pub const fn identity<T>(x: T) -> T {
122125///
123126/// # Generic Implementations
124127///
125- /// - `AsRef` auto-dereferences if the inner type is a reference or a mutable
126- /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type
127- /// `&mut Foo` or `&&mut Foo`)
128+ /// `AsRef` auto-dereferences if the inner type is a reference or a mutable reference
129+ /// (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`).
130+ ///
131+ /// Note that due to historic reasons, the above currently does not hold generally for all
132+ /// [dereferenceable types], e.g. `foo.as_ref()` will *not* work the same as
133+ /// `Box::new(foo).as_ref()`. Instead, many smart pointers provide an `as_ref` implementation which
134+ /// simply returns a reference to the [pointed-to value] (but do not perform a cheap
135+ /// reference-to-reference conversion for that value). However, [`AsRef::as_ref`] should not be
136+ /// used for the sole purpose of dereferencing; instead ['`Deref` coercion'] can be used:
137+ ///
138+ /// [dereferenceable types]: core::ops::Deref
139+ /// [pointed-to value]: core::ops::Deref::Target
140+ /// ['`Deref` coercion']: core::ops::Deref#more-on-deref-coercion
141+ ///
142+ /// ```
143+ /// let x = Box::new(5i32);
144+ /// // Avoid this:
145+ /// // let y: &i32 = x.as_ref();
146+ /// // Better just write:
147+ /// let y: &i32 = &x;
148+ /// ```
149+ ///
150+ /// Types which implement [`Deref`] should consider implementing `AsRef<T>` as follows:
151+ ///
152+ /// [`Deref`]: core::ops::Deref
153+ ///
154+ /// ```
155+ /// # use core::ops::Deref;
156+ /// # struct SomeType;
157+ /// # impl Deref for SomeType {
158+ /// # type Target = [u8];
159+ /// # fn deref(&self) -> &[u8] {
160+ /// # &[]
161+ /// # }
162+ /// # }
163+ /// impl<T> AsRef<T> for SomeType
164+ /// where
165+ /// T: ?Sized,
166+ /// <SomeType as Deref>::Target: AsRef<T>,
167+ /// {
168+ /// fn as_ref(&self) -> &T {
169+ /// self.deref().as_ref()
170+ /// }
171+ /// }
172+ /// ```
173+ ///
174+ /// # Reflexivity
175+ ///
176+ /// Ideally, `AsRef` would be reflexive, i.e. there would be an `impl<T: ?Sized> AsRef<T> for T`
177+ /// with [`as_ref`] simply returning its argument unchanged.
178+ /// Such a blanket implementation is currently *not* provided due to technical restrictions of
179+ /// Rust's type system (it would be overlapping with another existing blanket implementation for
180+ /// `&T where T: AsRef<U>` which allows `AsRef` to auto-dereference, see "Generic Implementations"
181+ /// above).
182+ ///
183+ /// [`as_ref`]: AsRef::as_ref
184+ ///
185+ /// A trivial implementation of `AsRef<T> for T` must be added explicitly for a particular type `T`
186+ /// where needed or desired. Note, however, that not all types from `std` contain such an
187+ /// implementation, and those cannot be added by external code due to orphan rules.
128188///
129189/// # Examples
130190///
@@ -172,29 +232,138 @@ pub trait AsRef<T: ?Sized> {
172232///
173233/// # Generic Implementations
174234///
175- /// - `AsMut` auto-dereferences if the inner type is a mutable reference
176- /// (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo`
177- /// or `&mut &mut Foo`)
235+ /// `AsMut` auto-dereferences if the inner type is a mutable reference
236+ /// (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo` or `&mut &mut Foo`).
237+ ///
238+ /// Note that due to historic reasons, the above currently does not hold generally for all
239+ /// [mutably dereferenceable types], e.g. `foo.as_mut()` will *not* work the same as
240+ /// `Box::new(foo).as_mut()`. Instead, many smart pointers provide an `as_mut` implementation which
241+ /// simply returns a reference to the [pointed-to value] (but do not perform a cheap
242+ /// reference-to-reference conversion for that value). However, [`AsMut::as_mut`] should not be
243+ /// used for the sole purpose of mutable dereferencing; instead ['`Deref` coercion'] can be used:
244+ ///
245+ /// [mutably dereferenceable types]: core::ops::DerefMut
246+ /// [pointed-to value]: core::ops::Deref::Target
247+ /// ['`Deref` coercion']: core::ops::DerefMut#more-on-deref-coercion
248+ ///
249+ /// ```
250+ /// let mut x = Box::new(5i32);
251+ /// // Avoid this:
252+ /// // let y: &mut i32 = x.as_mut();
253+ /// // Better just write:
254+ /// let y: &mut i32 = &mut x;
255+ /// ```
256+ ///
257+ /// Types which implement [`DerefMut`] should consider to add an implementation of `AsMut<T>` as
258+ /// follows:
259+ ///
260+ /// [`DerefMut`]: core::ops::DerefMut
261+ ///
262+ /// ```
263+ /// # use core::ops::{Deref, DerefMut};
264+ /// # struct SomeType;
265+ /// # impl Deref for SomeType {
266+ /// # type Target = [u8];
267+ /// # fn deref(&self) -> &[u8] {
268+ /// # &[]
269+ /// # }
270+ /// # }
271+ /// # impl DerefMut for SomeType {
272+ /// # fn deref_mut(&mut self) -> &mut [u8] {
273+ /// # &mut []
274+ /// # }
275+ /// # }
276+ /// impl<T> AsMut<T> for SomeType
277+ /// where
278+ /// <SomeType as Deref>::Target: AsMut<T>,
279+ /// {
280+ /// fn as_mut(&mut self) -> &mut T {
281+ /// self.deref_mut().as_mut()
282+ /// }
283+ /// }
284+ /// ```
285+ ///
286+ /// # Reflexivity
287+ ///
288+ /// Ideally, `AsMut` would be reflexive, i.e. there would be an `impl<T: ?Sized> AsMut<T> for T`
289+ /// with [`as_mut`] simply returning its argument unchanged.
290+ /// Such a blanket implementation is currently *not* provided due to technical restrictions of
291+ /// Rust's type system (it would be overlapping with another existing blanket implementation for
292+ /// `&mut T where T: AsMut<U>` which allows `AsMut` to auto-dereference, see "Generic
293+ /// Implementations" above).
294+ ///
295+ /// [`as_mut`]: AsMut::as_mut
296+ ///
297+ /// A trivial implementation of `AsMut<T> for T` must be added explicitly for a particular type `T`
298+ /// where needed or desired. Note, however, that not all types from `std` contain such an
299+ /// implementation, and those cannot be added by external code due to orphan rules.
178300///
179301/// # Examples
180302///
181- /// Using `AsMut` as trait bound for a generic function we can accept all mutable references
182- /// that can be converted to type `&mut T`. Because [`Box<T>`] implements `AsMut<T>` we can
183- /// write a function `add_one` that takes all arguments that can be converted to `&mut u64`.
184- /// Because [`Box<T>`] implements `AsMut<T>`, `add_one` accepts arguments of type
185- /// `&mut Box<u64>` as well:
303+ /// Using `AsMut` as trait bound for a generic function, we can accept all mutable references that
304+ /// can be converted to type `&mut T`. Unlike [dereference], which has a single [target type],
305+ /// there can be multiple implementations of `AsMut` for a type. In particular, `Vec<T>` implements
306+ /// both `AsMut<Vec<T>>` and `AsMut<[T]>`.
307+ ///
308+ /// In the following, the example functions `caesar` and `null_terminate` provide a generic
309+ /// interface which work with any type that can be converted by cheap mutable-to-mutable conversion
310+ /// into a byte slice (`[u8]`) or byte vector (`Vec<u8>`), respectively.
311+ ///
312+ /// [dereference]: core::ops::DerefMut
313+ /// [target type]: core::ops::Deref::Target
186314///
187315/// ```
188- /// fn add_one<T: AsMut<u64>>(num: &mut T) {
189- /// *num.as_mut() += 1;
316+ /// struct Document {
317+ /// info: String,
318+ /// content: Vec<u8>,
190319/// }
191320///
192- /// let mut boxed_num = Box::new(0);
193- /// add_one(&mut boxed_num);
194- /// assert_eq!(*boxed_num, 1);
321+ /// impl<T: ?Sized> AsMut<T> for Document
322+ /// where
323+ /// Vec<u8>: AsMut<T>,
324+ /// {
325+ /// fn as_mut(&mut self) -> &mut T {
326+ /// self.content.as_mut()
327+ /// }
328+ /// }
329+ ///
330+ /// fn caesar<T: AsMut<[u8]>>(data: &mut T, key: u8) {
331+ /// for byte in data.as_mut() {
332+ /// *byte = byte.wrapping_add(key);
333+ /// }
334+ /// }
335+ ///
336+ /// fn null_terminate<T: AsMut<Vec<u8>>>(data: &mut T) {
337+ /// // Using a non-generic inner function, which contains most of the
338+ /// // functionality, helps to minimize monomorphization overhead.
339+ /// fn doit(data: &mut Vec<u8>) {
340+ /// let len = data.len();
341+ /// if len == 0 || data[len-1] != 0 {
342+ /// data.push(0);
343+ /// }
344+ /// }
345+ /// doit(data.as_mut());
346+ /// }
347+ ///
348+ /// fn main() {
349+ /// let mut v: Vec<u8> = vec![1, 2, 3];
350+ /// caesar(&mut v, 5);
351+ /// assert_eq!(v, [6, 7, 8]);
352+ /// null_terminate(&mut v);
353+ /// assert_eq!(v, [6, 7, 8, 0]);
354+ /// let mut doc = Document {
355+ /// info: String::from("Example"),
356+ /// content: vec![17, 19, 8],
357+ /// };
358+ /// caesar(&mut doc, 1);
359+ /// assert_eq!(doc.content, [18, 20, 9]);
360+ /// null_terminate(&mut doc);
361+ /// assert_eq!(doc.content, [18, 20, 9, 0]);
362+ /// }
195363/// ```
196364///
197- /// [`Box<T>`]: ../../std/boxed/struct.Box.html
365+ /// Note, however, that APIs don't need to be generic. In many cases taking a `&mut [u8]` or
366+ /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then).
198367#[ stable( feature = "rust1" , since = "1.0.0" ) ]
199368#[ cfg_attr( not( test) , rustc_diagnostic_item = "AsMut" ) ]
200369#[ const_trait]
0 commit comments