25
25
//! # Generic Implementations
26
26
//!
27
27
//! - [`AsRef`] and [`AsMut`] auto-dereference if the inner type is a reference
28
+ //! (but not generally for all [dereferenceable types][core::ops::Deref])
28
29
//! - [`From`]`<U> for T` implies [`Into`]`<T> for U`
29
30
//! - [`TryFrom`]`<U> for T` implies [`TryInto`]`<T> for U`
30
31
//! - [`From`] and [`Into`] are reflexive, which means that all types can
@@ -109,10 +110,12 @@ pub const fn identity<T>(x: T) -> T {
109
110
/// If you need to do a costly conversion it is better to implement [`From`] with type
110
111
/// `&T` or write a custom function.
111
112
///
113
+ /// # Relation to `Borrow`
114
+ ///
112
115
/// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in a few aspects:
113
116
///
114
117
/// - 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.)
116
119
/// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for a borrowed value are
117
120
/// equivalent to those of the owned value. For this reason, if you want to
118
121
/// 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 {
122
125
///
123
126
/// # Generic Implementations
124
127
///
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.
128
188
///
129
189
/// # Examples
130
190
///
@@ -172,29 +232,138 @@ pub trait AsRef<T: ?Sized> {
172
232
///
173
233
/// # Generic Implementations
174
234
///
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.
178
300
///
179
301
/// # Examples
180
302
///
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
186
314
///
187
315
/// ```
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>,
190
319
/// }
191
320
///
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
+ /// }
195
363
/// ```
196
364
///
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).
198
367
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
199
368
#[ cfg_attr( not( test) , rustc_diagnostic_item = "AsMut" ) ]
200
369
#[ const_trait]
0 commit comments