]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Basic functions for dealing with memory | |
12 | //! | |
13 | //! This module contains functions for querying the size and alignment of | |
14 | //! types, initializing and manipulating memory. | |
15 | ||
85aaf69f | 16 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
17 | |
18 | use marker::Sized; | |
19 | use intrinsics; | |
20 | use ptr; | |
21 | ||
85aaf69f | 22 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
23 | pub use intrinsics::transmute; |
24 | ||
bd371182 AL |
25 | /// Leaks a value into the void, consuming ownership and never running its |
26 | /// destructor. | |
1a4d82fc | 27 | /// |
bd371182 AL |
28 | /// This function will take ownership of its argument, but is distinct from the |
29 | /// `mem::drop` function in that it **does not run the destructor**, leaking the | |
30 | /// value and any resources that it owns. | |
1a4d82fc | 31 | /// |
bd371182 AL |
32 | /// # Safety |
33 | /// | |
34 | /// This function is not marked as `unsafe` as Rust does not guarantee that the | |
35 | /// `Drop` implementation for a value will always run. Note, however, that | |
36 | /// leaking resources such as memory or I/O objects is likely not desired, so | |
37 | /// this function is only recommended for specialized use cases. | |
38 | /// | |
39 | /// The safety of this function implies that when writing `unsafe` code | |
40 | /// yourself care must be taken when leveraging a destructor that is required to | |
41 | /// run to preserve memory safety. There are known situations where the | |
42 | /// destructor may not run (such as if ownership of the object with the | |
43 | /// destructor is returned) which must be taken into account. | |
44 | /// | |
45 | /// # Other forms of Leakage | |
46 | /// | |
47 | /// It's important to point out that this function is not the only method by | |
48 | /// which a value can be leaked in safe Rust code. Other known sources of | |
49 | /// leakage are: | |
50 | /// | |
51 | /// * `Rc` and `Arc` cycles | |
52 | /// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally) | |
53 | /// * Panicking destructors are likely to leak local resources | |
54 | /// | |
62682a34 SL |
55 | /// # When To Use |
56 | /// | |
57 | /// There's only a few reasons to use this function. They mainly come | |
58 | /// up in unsafe code or FFI code. | |
59 | /// | |
60 | /// * You have an uninitialized value, perhaps for performance reasons, and | |
61 | /// need to prevent the destructor from running on it. | |
62 | /// * You have two copies of a value (like `std::mem::swap`), but need the | |
63 | /// destructor to only run once to prevent a double free. | |
64 | /// * Transferring resources across FFI boundries. | |
65 | /// | |
bd371182 AL |
66 | /// # Example |
67 | /// | |
62682a34 SL |
68 | /// Leak some heap memory by never deallocating it. |
69 | /// | |
70 | /// ```rust | |
bd371182 | 71 | /// use std::mem; |
bd371182 | 72 | /// |
bd371182 AL |
73 | /// let heap_memory = Box::new(3); |
74 | /// mem::forget(heap_memory); | |
62682a34 SL |
75 | /// ``` |
76 | /// | |
77 | /// Leak an I/O object, never closing the file. | |
78 | /// | |
79 | /// ```rust,no_run | |
80 | /// use std::mem; | |
81 | /// use std::fs::File; | |
bd371182 | 82 | /// |
bd371182 AL |
83 | /// let file = File::open("foo.txt").unwrap(); |
84 | /// mem::forget(file); | |
85 | /// ``` | |
62682a34 SL |
86 | /// |
87 | /// The swap function uses forget to good effect. | |
88 | /// | |
89 | /// ```rust | |
90 | /// use std::mem; | |
91 | /// use std::ptr; | |
92 | /// | |
93 | /// fn swap<T>(x: &mut T, y: &mut T) { | |
94 | /// unsafe { | |
95 | /// // Give ourselves some scratch space to work with | |
96 | /// let mut t: T = mem::uninitialized(); | |
97 | /// | |
98 | /// // Perform the swap, `&mut` pointers never alias | |
99 | /// ptr::copy_nonoverlapping(&*x, &mut t, 1); | |
100 | /// ptr::copy_nonoverlapping(&*y, x, 1); | |
101 | /// ptr::copy_nonoverlapping(&t, y, 1); | |
102 | /// | |
103 | /// // y and t now point to the same thing, but we need to completely | |
104 | /// // forget `t` because we do not want to run the destructor for `T` | |
105 | /// // on its value, which is still owned somewhere outside this function. | |
106 | /// mem::forget(t); | |
107 | /// } | |
108 | /// } | |
109 | /// ``` | |
85aaf69f | 110 | #[stable(feature = "rust1", since = "1.0.0")] |
bd371182 AL |
111 | pub fn forget<T>(t: T) { |
112 | unsafe { intrinsics::forget(t) } | |
113 | } | |
1a4d82fc JJ |
114 | |
115 | /// Returns the size of a type in bytes. | |
116 | /// | |
117 | /// # Examples | |
118 | /// | |
119 | /// ``` | |
120 | /// use std::mem; | |
121 | /// | |
122 | /// assert_eq!(4, mem::size_of::<i32>()); | |
123 | /// ``` | |
124 | #[inline] | |
85aaf69f SL |
125 | #[stable(feature = "rust1", since = "1.0.0")] |
126 | pub fn size_of<T>() -> usize { | |
1a4d82fc JJ |
127 | unsafe { intrinsics::size_of::<T>() } |
128 | } | |
129 | ||
d9579d0f AL |
130 | /// Returns the size of the type that `val` points to in bytes. |
131 | /// | |
132 | /// # Examples | |
133 | /// | |
134 | /// ``` | |
135 | /// use std::mem; | |
136 | /// | |
137 | /// assert_eq!(4, mem::size_of_val(&5i32)); | |
138 | /// ``` | |
d9579d0f AL |
139 | #[inline] |
140 | #[stable(feature = "rust1", since = "1.0.0")] | |
141 | pub fn size_of_val<T: ?Sized>(val: &T) -> usize { | |
142 | unsafe { intrinsics::size_of_val(val) } | |
143 | } | |
144 | ||
1a4d82fc JJ |
145 | /// Returns the ABI-required minimum alignment of a type |
146 | /// | |
147 | /// This is the alignment used for struct fields. It may be smaller than the preferred alignment. | |
148 | /// | |
149 | /// # Examples | |
150 | /// | |
151 | /// ``` | |
152 | /// use std::mem; | |
153 | /// | |
154 | /// assert_eq!(4, mem::min_align_of::<i32>()); | |
155 | /// ``` | |
156 | #[inline] | |
85aaf69f | 157 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 158 | #[deprecated(reason = "use `align_of` instead", since = "1.2.0")] |
85aaf69f | 159 | pub fn min_align_of<T>() -> usize { |
1a4d82fc JJ |
160 | unsafe { intrinsics::min_align_of::<T>() } |
161 | } | |
162 | ||
d9579d0f AL |
163 | /// Returns the ABI-required minimum alignment of the type of the value that `val` points to |
164 | /// | |
165 | /// # Examples | |
166 | /// | |
167 | /// ``` | |
168 | /// use std::mem; | |
169 | /// | |
170 | /// assert_eq!(4, mem::min_align_of_val(&5i32)); | |
171 | /// ``` | |
d9579d0f AL |
172 | #[inline] |
173 | #[stable(feature = "rust1", since = "1.0.0")] | |
62682a34 | 174 | #[deprecated(reason = "use `align_of_val` instead", since = "1.2.0")] |
d9579d0f AL |
175 | pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize { |
176 | unsafe { intrinsics::min_align_of_val(val) } | |
177 | } | |
178 | ||
1a4d82fc JJ |
179 | /// Returns the alignment in memory for a type. |
180 | /// | |
62682a34 | 181 | /// This is the alignment used for struct fields. It may be smaller than the preferred alignment. |
1a4d82fc JJ |
182 | /// |
183 | /// # Examples | |
184 | /// | |
185 | /// ``` | |
186 | /// use std::mem; | |
187 | /// | |
188 | /// assert_eq!(4, mem::align_of::<i32>()); | |
189 | /// ``` | |
190 | #[inline] | |
85aaf69f SL |
191 | #[stable(feature = "rust1", since = "1.0.0")] |
192 | pub fn align_of<T>() -> usize { | |
62682a34 | 193 | unsafe { intrinsics::min_align_of::<T>() } |
1a4d82fc JJ |
194 | } |
195 | ||
62682a34 | 196 | /// Returns the ABI-required minimum alignment of the type of the value that `val` points to |
1a4d82fc JJ |
197 | /// |
198 | /// # Examples | |
199 | /// | |
200 | /// ``` | |
201 | /// use std::mem; | |
202 | /// | |
203 | /// assert_eq!(4, mem::align_of_val(&5i32)); | |
204 | /// ``` | |
205 | #[inline] | |
85aaf69f | 206 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
207 | pub fn align_of_val<T: ?Sized>(val: &T) -> usize { |
208 | unsafe { intrinsics::min_align_of_val(val) } | |
1a4d82fc JJ |
209 | } |
210 | ||
9346a6ac | 211 | /// Creates a value initialized to zero. |
1a4d82fc JJ |
212 | /// |
213 | /// This function is similar to allocating space for a local variable and zeroing it out (an unsafe | |
214 | /// operation). | |
215 | /// | |
216 | /// Care must be taken when using this function, if the type `T` has a destructor and the value | |
217 | /// falls out of scope (due to unwinding or returning) before being initialized, then the | |
218 | /// destructor will run on zeroed data, likely leading to crashes. | |
219 | /// | |
220 | /// This is useful for FFI functions sometimes, but should generally be avoided. | |
221 | /// | |
222 | /// # Examples | |
223 | /// | |
224 | /// ``` | |
225 | /// use std::mem; | |
226 | /// | |
85aaf69f | 227 | /// let x: i32 = unsafe { mem::zeroed() }; |
1a4d82fc JJ |
228 | /// ``` |
229 | #[inline] | |
85aaf69f | 230 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
231 | pub unsafe fn zeroed<T>() -> T { |
232 | intrinsics::init() | |
233 | } | |
234 | ||
9346a6ac | 235 | /// Creates a value initialized to an unspecified series of bytes. |
c34b1796 AL |
236 | /// |
237 | /// The byte sequence usually indicates that the value at the memory | |
238 | /// in question has been dropped. Thus, *if* T carries a drop flag, | |
239 | /// any associated destructor will not be run when the value falls out | |
240 | /// of scope. | |
241 | /// | |
242 | /// Some code at one time used the `zeroed` function above to | |
243 | /// accomplish this goal. | |
244 | /// | |
245 | /// This function is expected to be deprecated with the transition | |
246 | /// to non-zeroing drop. | |
247 | #[inline] | |
248 | #[unstable(feature = "filling_drop")] | |
249 | pub unsafe fn dropped<T>() -> T { | |
250 | #[inline(always)] | |
251 | unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() } | |
252 | ||
253 | dropped_impl() | |
254 | } | |
255 | ||
9346a6ac | 256 | /// Creates an uninitialized value. |
1a4d82fc JJ |
257 | /// |
258 | /// Care must be taken when using this function, if the type `T` has a destructor and the value | |
259 | /// falls out of scope (due to unwinding or returning) before being initialized, then the | |
260 | /// destructor will run on uninitialized data, likely leading to crashes. | |
261 | /// | |
262 | /// This is useful for FFI functions sometimes, but should generally be avoided. | |
263 | /// | |
264 | /// # Examples | |
265 | /// | |
266 | /// ``` | |
267 | /// use std::mem; | |
268 | /// | |
85aaf69f | 269 | /// let x: i32 = unsafe { mem::uninitialized() }; |
1a4d82fc JJ |
270 | /// ``` |
271 | #[inline] | |
85aaf69f | 272 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
273 | pub unsafe fn uninitialized<T>() -> T { |
274 | intrinsics::uninit() | |
275 | } | |
276 | ||
277 | /// Swap the values at two mutable locations of the same type, without deinitialising or copying | |
278 | /// either one. | |
279 | /// | |
280 | /// # Examples | |
281 | /// | |
282 | /// ``` | |
283 | /// use std::mem; | |
284 | /// | |
85aaf69f SL |
285 | /// let x = &mut 5; |
286 | /// let y = &mut 42; | |
1a4d82fc JJ |
287 | /// |
288 | /// mem::swap(x, y); | |
289 | /// | |
85aaf69f SL |
290 | /// assert_eq!(42, *x); |
291 | /// assert_eq!(5, *y); | |
1a4d82fc JJ |
292 | /// ``` |
293 | #[inline] | |
85aaf69f | 294 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
295 | pub fn swap<T>(x: &mut T, y: &mut T) { |
296 | unsafe { | |
297 | // Give ourselves some scratch space to work with | |
298 | let mut t: T = uninitialized(); | |
299 | ||
300 | // Perform the swap, `&mut` pointers never alias | |
c34b1796 AL |
301 | ptr::copy_nonoverlapping(&*x, &mut t, 1); |
302 | ptr::copy_nonoverlapping(&*y, x, 1); | |
303 | ptr::copy_nonoverlapping(&t, y, 1); | |
1a4d82fc | 304 | |
62682a34 SL |
305 | // y and t now point to the same thing, but we need to completely |
306 | // forget `t` because we do not want to run the destructor for `T` | |
307 | // on its value, which is still owned somewhere outside this function. | |
1a4d82fc JJ |
308 | forget(t); |
309 | } | |
310 | } | |
311 | ||
9346a6ac | 312 | /// Replaces the value at a mutable location with a new one, returning the old value, without |
1a4d82fc JJ |
313 | /// deinitialising or copying either one. |
314 | /// | |
315 | /// This is primarily used for transferring and swapping ownership of a value in a mutable | |
316 | /// location. | |
317 | /// | |
318 | /// # Examples | |
319 | /// | |
320 | /// A simple example: | |
321 | /// | |
322 | /// ``` | |
323 | /// use std::mem; | |
324 | /// | |
325 | /// let mut v: Vec<i32> = Vec::new(); | |
326 | /// | |
327 | /// mem::replace(&mut v, Vec::new()); | |
328 | /// ``` | |
329 | /// | |
330 | /// This function allows consumption of one field of a struct by replacing it with another value. | |
331 | /// The normal approach doesn't always work: | |
332 | /// | |
333 | /// ```rust,ignore | |
334 | /// struct Buffer<T> { buf: Vec<T> } | |
335 | /// | |
336 | /// impl<T> Buffer<T> { | |
337 | /// fn get_and_reset(&mut self) -> Vec<T> { | |
338 | /// // error: cannot move out of dereference of `&mut`-pointer | |
339 | /// let buf = self.buf; | |
340 | /// self.buf = Vec::new(); | |
341 | /// buf | |
342 | /// } | |
343 | /// } | |
344 | /// ``` | |
345 | /// | |
346 | /// Note that `T` does not necessarily implement `Clone`, so it can't even clone and reset | |
347 | /// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from | |
348 | /// `self`, allowing it to be returned: | |
349 | /// | |
c34b1796 | 350 | /// ``` |
1a4d82fc JJ |
351 | /// use std::mem; |
352 | /// # struct Buffer<T> { buf: Vec<T> } | |
353 | /// impl<T> Buffer<T> { | |
354 | /// fn get_and_reset(&mut self) -> Vec<T> { | |
355 | /// mem::replace(&mut self.buf, Vec::new()) | |
356 | /// } | |
357 | /// } | |
358 | /// ``` | |
359 | #[inline] | |
85aaf69f | 360 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
361 | pub fn replace<T>(dest: &mut T, mut src: T) -> T { |
362 | swap(dest, &mut src); | |
363 | src | |
364 | } | |
365 | ||
366 | /// Disposes of a value. | |
367 | /// | |
368 | /// This function can be used to destroy any value by allowing `drop` to take ownership of its | |
369 | /// argument. | |
370 | /// | |
371 | /// # Examples | |
372 | /// | |
373 | /// ``` | |
374 | /// use std::cell::RefCell; | |
375 | /// | |
85aaf69f | 376 | /// let x = RefCell::new(1); |
1a4d82fc JJ |
377 | /// |
378 | /// let mut mutable_borrow = x.borrow_mut(); | |
379 | /// *mutable_borrow = 1; | |
380 | /// | |
381 | /// drop(mutable_borrow); // relinquish the mutable borrow on this slot | |
382 | /// | |
383 | /// let borrow = x.borrow(); | |
384 | /// println!("{}", *borrow); | |
385 | /// ``` | |
386 | #[inline] | |
85aaf69f | 387 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
388 | pub fn drop<T>(_x: T) { } |
389 | ||
c34b1796 AL |
390 | macro_rules! repeat_u8_as_u32 { |
391 | ($name:expr) => { (($name as u32) << 24 | | |
392 | ($name as u32) << 16 | | |
393 | ($name as u32) << 8 | | |
394 | ($name as u32)) } | |
395 | } | |
396 | macro_rules! repeat_u8_as_u64 { | |
397 | ($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 | | |
398 | (repeat_u8_as_u32!($name) as u64)) } | |
399 | } | |
400 | ||
401 | // NOTE: Keep synchronized with values used in librustc_trans::trans::adt. | |
402 | // | |
403 | // In particular, the POST_DROP_U8 marker must never equal the | |
404 | // DTOR_NEEDED_U8 marker. | |
405 | // | |
406 | // For a while pnkfelix was using 0xc1 here. | |
407 | // But having the sign bit set is a pain, so 0x1d is probably better. | |
408 | // | |
409 | // And of course, 0x00 brings back the old world of zero'ing on drop. | |
410 | #[unstable(feature = "filling_drop")] | |
411 | pub const POST_DROP_U8: u8 = 0x1d; | |
412 | #[unstable(feature = "filling_drop")] | |
413 | pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8); | |
414 | #[unstable(feature = "filling_drop")] | |
415 | pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8); | |
416 | ||
417 | #[cfg(target_pointer_width = "32")] | |
418 | #[unstable(feature = "filling_drop")] | |
419 | pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize; | |
420 | #[cfg(target_pointer_width = "64")] | |
421 | #[unstable(feature = "filling_drop")] | |
422 | pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize; | |
423 | ||
424 | /// Interprets `src` as `&U`, and then reads `src` without moving the contained | |
425 | /// value. | |
1a4d82fc | 426 | /// |
c34b1796 AL |
427 | /// This function will unsafely assume the pointer `src` is valid for |
428 | /// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It | |
429 | /// will also unsafely create a copy of the contained value instead of moving | |
430 | /// out of `src`. | |
1a4d82fc | 431 | /// |
c34b1796 AL |
432 | /// It is not a compile-time error if `T` and `U` have different sizes, but it |
433 | /// is highly encouraged to only invoke this function where `T` and `U` have the | |
434 | /// same size. This function triggers undefined behavior if `U` is larger than | |
435 | /// `T`. | |
1a4d82fc JJ |
436 | /// |
437 | /// # Examples | |
438 | /// | |
439 | /// ``` | |
440 | /// use std::mem; | |
441 | /// | |
85aaf69f | 442 | /// let one = unsafe { mem::transmute_copy(&1) }; |
1a4d82fc | 443 | /// |
85aaf69f | 444 | /// assert_eq!(1, one); |
1a4d82fc JJ |
445 | /// ``` |
446 | #[inline] | |
85aaf69f | 447 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 448 | pub unsafe fn transmute_copy<T, U>(src: &T) -> U { |
c34b1796 AL |
449 | // FIXME(#23542) Replace with type ascription. |
450 | #![allow(trivial_casts)] | |
1a4d82fc JJ |
451 | ptr::read(src as *const T as *const U) |
452 | } | |
453 | ||
454 | /// Transforms lifetime of the second pointer to match the first. | |
455 | #[inline] | |
62682a34 | 456 | #[unstable(feature = "copy_lifetime", |
85aaf69f SL |
457 | reason = "this function may be removed in the future due to its \ |
458 | questionable utility")] | |
62682a34 SL |
459 | #[deprecated(since = "1.2.0", |
460 | reason = "unclear that this function buys more safety and \ | |
461 | lifetimes are generally not handled as such in unsafe \ | |
462 | code today")] | |
1a4d82fc JJ |
463 | pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S, |
464 | ptr: &T) -> &'a T { | |
465 | transmute(ptr) | |
466 | } | |
467 | ||
468 | /// Transforms lifetime of the second mutable pointer to match the first. | |
469 | #[inline] | |
62682a34 | 470 | #[unstable(feature = "copy_lifetime", |
85aaf69f SL |
471 | reason = "this function may be removed in the future due to its \ |
472 | questionable utility")] | |
62682a34 SL |
473 | #[deprecated(since = "1.2.0", |
474 | reason = "unclear that this function buys more safety and \ | |
475 | lifetimes are generally not handled as such in unsafe \ | |
476 | code today")] | |
85aaf69f SL |
477 | pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S, |
478 | ptr: &mut T) | |
479 | -> &'a mut T | |
480 | { | |
1a4d82fc JJ |
481 | transmute(ptr) |
482 | } |