]> git.proxmox.com Git - rustc.git/blame - src/libcore/borrow.rs
New upstream version 1.46.0+dfsg1
[rustc.git] / src / libcore / borrow.rs
CommitLineData
e9174d1e
SL
1//! A module for working with borrowed data.
2
3#![stable(feature = "rust1", since = "1.0.0")]
4
e9174d1e
SL
5/// A trait for borrowing data.
6///
0531ce1d
XL
7/// In Rust, it is common to provide different representations of a type for
8/// different use cases. For instance, storage location and management for a
9/// value can be specifically chosen as appropriate for a particular use via
10/// pointer types such as [`Box<T>`] or [`Rc<T>`]. Beyond these generic
11/// wrappers that can be used with any type, some types provide optional
12/// facets providing potentially costly functionality. An example for such a
13/// type is [`String`] which adds the ability to extend a string to the basic
14/// [`str`]. This requires keeping additional information unnecessary for a
15/// simple, immutable string.
e9174d1e 16///
0531ce1d
XL
17/// These types provide access to the underlying data through references
18/// to the type of that data. They are said to be ‘borrowed as’ that type.
19/// For instance, a [`Box<T>`] can be borrowed as `T` while a [`String`]
20/// can be borrowed as `str`.
e9174d1e 21///
0531ce1d
XL
22/// Types express that they can be borrowed as some type `T` by implementing
23/// `Borrow<T>`, providing a reference to a `T` in the trait’s
24/// [`borrow`] method. A type is free to borrow as several different types.
25/// If it wishes to mutably borrow as the type – allowing the underlying data
26/// to be modified, it can additionally implement [`BorrowMut<T>`].
e9174d1e 27///
0531ce1d
XL
28/// Further, when providing implementations for additional traits, it needs
29/// to be considered whether they should behave identical to those of the
30/// underlying type as a consequence of acting as a representation of that
31/// underlying type. Generic code typically uses `Borrow<T>` when it relies
32/// on the identical behavior of these additional trait implementations.
33/// These traits will likely appear as additional trait bounds.
e9174d1e 34///
532ac7d7
XL
35/// In particular `Eq`, `Ord` and `Hash` must be equivalent for
36/// borrowed and owned values: `x.borrow() == y.borrow()` should give the
37/// same result as `x == y`.
38///
0531ce1d
XL
39/// If generic code merely needs to work for all types that can
40/// provide a reference to related type `T`, it is often better to use
41/// [`AsRef<T>`] as more types can safely implement it.
42///
43/// [`AsRef<T>`]: ../../std/convert/trait.AsRef.html
44/// [`BorrowMut<T>`]: trait.BorrowMut.html
45/// [`Box<T>`]: ../../std/boxed/struct.Box.html
46/// [`Mutex<T>`]: ../../std/sync/struct.Mutex.html
47/// [`Rc<T>`]: ../../std/rc/struct.Rc.html
48/// [`str`]: ../../std/primitive.str.html
49/// [`String`]: ../../std/string/struct.String.html
50/// [`borrow`]: #tymethod.borrow
51///
52/// # Examples
53///
54/// As a data collection, [`HashMap<K, V>`] owns both keys and values. If
55/// the key’s actual data is wrapped in a managing type of some kind, it
56/// should, however, still be possible to search for a value using a
57/// reference to the key’s data. For instance, if the key is a string, then
58/// it is likely stored with the hash map as a [`String`], while it should
59/// be possible to search using a [`&str`][`str`]. Thus, `insert` needs to
60/// operate on a `String` while `get` needs to be able to use a `&str`.
61///
62/// Slightly simplified, the relevant parts of `HashMap<K, V>` look like
63/// this:
64///
65/// ```
66/// use std::borrow::Borrow;
67/// use std::hash::Hash;
68///
69/// pub struct HashMap<K, V> {
70/// # marker: ::std::marker::PhantomData<(K, V)>,
71/// // fields omitted
72/// }
73///
74/// impl<K, V> HashMap<K, V> {
75/// pub fn insert(&self, key: K, value: V) -> Option<V>
76/// where K: Hash + Eq
77/// {
78/// # unimplemented!()
79/// // ...
80/// }
81///
82/// pub fn get<Q>(&self, k: &Q) -> Option<&V>
83/// where
84/// K: Borrow<Q>,
85/// Q: Hash + Eq + ?Sized
86/// {
87/// # unimplemented!()
88/// // ...
89/// }
90/// }
91/// ```
92///
93/// The entire hash map is generic over a key type `K`. Because these keys
94/// are stored with the hash map, this type has to own the key’s data.
95/// When inserting a key-value pair, the map is given such a `K` and needs
96/// to find the correct hash bucket and check if the key is already present
97/// based on that `K`. It therefore requires `K: Hash + Eq`.
98///
99/// When searching for a value in the map, however, having to provide a
100/// reference to a `K` as the key to search for would require to always
101/// create such an owned value. For string keys, this would mean a `String`
102/// value needs to be created just for the search for cases where only a
103/// `str` is available.
104///
105/// Instead, the `get` method is generic over the type of the underlying key
106/// data, called `Q` in the method signature above. It states that `K`
107/// borrows as a `Q` by requiring that `K: Borrow<Q>`. By additionally
108/// requiring `Q: Hash + Eq`, it signals the requirement that `K` and `Q`
109/// have implementations of the `Hash` and `Eq` traits that produce identical
110/// results.
111///
112/// The implementation of `get` relies in particular on identical
113/// implementations of `Hash` by determining the key’s hash bucket by calling
114/// `Hash::hash` on the `Q` value even though it inserted the key based on
115/// the hash value calculated from the `K` value.
116///
117/// As a consequence, the hash map breaks if a `K` wrapping a `Q` value
118/// produces a different hash than `Q`. For instance, imagine you have a
119/// type that wraps a string but compares ASCII letters ignoring their case:
120///
121/// ```
122/// pub struct CaseInsensitiveString(String);
123///
124/// impl PartialEq for CaseInsensitiveString {
125/// fn eq(&self, other: &Self) -> bool {
126/// self.0.eq_ignore_ascii_case(&other.0)
127/// }
128/// }
129///
130/// impl Eq for CaseInsensitiveString { }
131/// ```
132///
133/// Because two equal values need to produce the same hash value, the
134/// implementation of `Hash` needs to ignore ASCII case, too:
135///
136/// ```
137/// # use std::hash::{Hash, Hasher};
138/// # pub struct CaseInsensitiveString(String);
139/// impl Hash for CaseInsensitiveString {
140/// fn hash<H: Hasher>(&self, state: &mut H) {
141/// for c in self.0.as_bytes() {
142/// c.to_ascii_lowercase().hash(state)
143/// }
144/// }
145/// }
146/// ```
147///
148/// Can `CaseInsensitiveString` implement `Borrow<str>`? It certainly can
149/// provide a reference to a string slice via its contained owned string.
150/// But because its `Hash` implementation differs, it behaves differently
151/// from `str` and therefore must not, in fact, implement `Borrow<str>`.
152/// If it wants to allow others access to the underlying `str`, it can do
153/// that via `AsRef<str>` which doesn’t carry any extra requirements.
154///
155/// [`Hash`]: ../../std/hash/trait.Hash.html
156/// [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
157/// [`String`]: ../../std/string/struct.String.html
158/// [`str`]: ../../std/primitive.str.html
e9174d1e
SL
159#[stable(feature = "rust1", since = "1.0.0")]
160pub trait Borrow<Borrowed: ?Sized> {
161 /// Immutably borrows from an owned value.
162 ///
163 /// # Examples
164 ///
165 /// ```
166 /// use std::borrow::Borrow;
167 ///
168 /// fn check<T: Borrow<str>>(s: T) {
169 /// assert_eq!("Hello", s.borrow());
170 /// }
171 ///
172 /// let s = "Hello".to_string();
173 ///
174 /// check(s);
175 ///
176 /// let s = "Hello";
177 ///
178 /// check(s);
179 /// ```
180 #[stable(feature = "rust1", since = "1.0.0")]
181 fn borrow(&self) -> &Borrowed;
182}
183
184/// A trait for mutably borrowing data.
185///
0531ce1d
XL
186/// As a companion to [`Borrow<T>`] this trait allows a type to borrow as
187/// an underlying type by providing a mutable reference. See [`Borrow<T>`]
188/// for more information on borrowing as another type.
189///
190/// [`Borrow<T>`]: trait.Borrow.html
e9174d1e 191#[stable(feature = "rust1", since = "1.0.0")]
dfeec247 192pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
e9174d1e
SL
193 /// Mutably borrows from an owned value.
194 ///
195 /// # Examples
196 ///
197 /// ```
198 /// use std::borrow::BorrowMut;
199 ///
200 /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
201 /// assert_eq!(&mut [1, 2, 3], v.borrow_mut());
202 /// }
203 ///
204 /// let v = vec![1, 2, 3];
205 ///
206 /// check(v);
207 /// ```
208 #[stable(feature = "rust1", since = "1.0.0")]
209 fn borrow_mut(&mut self) -> &mut Borrowed;
210}
211
212#[stable(feature = "rust1", since = "1.0.0")]
213impl<T: ?Sized> Borrow<T> for T {
dfeec247
XL
214 fn borrow(&self) -> &T {
215 self
216 }
e9174d1e
SL
217}
218
219#[stable(feature = "rust1", since = "1.0.0")]
220impl<T: ?Sized> BorrowMut<T> for T {
dfeec247
XL
221 fn borrow_mut(&mut self) -> &mut T {
222 self
223 }
e9174d1e
SL
224}
225
226#[stable(feature = "rust1", since = "1.0.0")]
0bf4aa26 227impl<T: ?Sized> Borrow<T> for &T {
dfeec247
XL
228 fn borrow(&self) -> &T {
229 &**self
230 }
e9174d1e
SL
231}
232
233#[stable(feature = "rust1", since = "1.0.0")]
0bf4aa26 234impl<T: ?Sized> Borrow<T> for &mut T {
dfeec247
XL
235 fn borrow(&self) -> &T {
236 &**self
237 }
e9174d1e
SL
238}
239
240#[stable(feature = "rust1", since = "1.0.0")]
0bf4aa26 241impl<T: ?Sized> BorrowMut<T> for &mut T {
dfeec247
XL
242 fn borrow_mut(&mut self) -> &mut T {
243 &mut **self
244 }
e9174d1e 245}