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