about summary refs log tree commit diff
path: root/src/libcore/ptr.rs
AgeCommit message (Collapse)AuthorLines
2018-08-30fix exampleRalf Jung-2/+1
2018-08-30fix exampleRalf Jung-2/+3
2018-08-30improve volatile commentsRalf Jung-4/+4
2018-08-30address remaining remarks and add example for dropping unaligned dataRalf Jung-4/+32
2018-08-30apply commentsRalf Jung-12/+13
2018-08-30clarify ZST commentRalf Jung-10/+10
2018-08-29clarify that these are preliminary guaranteesRalf Jung-5/+4
2018-08-29edit docs a littleRalf Jung-24/+37
2018-08-29Resolve null/ZST conflict correctly (whoops)Dylan MacKenzie-4/+3
2018-08-29Add a list of known facts re: validityDylan MacKenzie-9/+26
Also rewrites the reads/writes section to be less reliant on `*const`, `*mut`
2018-08-29You can't make an omlette without breaking a few linksDylan MacKenzie-1/+1
2018-08-29Incorporate RalfJung's suggestionsDylan MacKenzie-28/+38
This splits "valid" into "valid for reads" and "valid for writes", and also adds the concept of operation size to validity. Now functions which operate on sequences state that e.g. pointer args must be "valid for reads of size x".
2018-08-29Redefine range validityDylan MacKenzie-8/+6
Uses `x.offset(i)` must be valid for all `i` in `0..count`.
2018-08-29Remove definiton of valid pointerDylan MacKenzie-7/+14
The enumerated list of conditions is replaced by an explanation that rust doesn't have a formal memory model. It does say that pointers created directly from references are guaranteed to be valid, and links to both the "Unsafe Code" section of the book and the "Undefined Behavior" section of the reference.
2018-08-29Fix off-by-one error when specifying a valid rangeDylan MacKenzie-2/+2
2018-08-29Reword module level docs re: alignmentDylan MacKenzie-4/+4
2018-08-29Update docs for `swap_nonoverlapping`Dylan MacKenzie-3/+19
They closely mirror the docs for `copy_nonoverlapping`
2018-08-29Fix unused variable warning in doctestDylan MacKenzie-0/+1
2018-08-29Fix failing doctestsDylan MacKenzie-3/+3
2018-08-29Mention alignment in top-level docsDylan MacKenzie-5/+11
This also removes the overlong link that failed tidy xD.
2018-08-29Rewrite docs for `std::ptr`Dylan MacKenzie-68/+351
- Add links to the GNU libc docs for `memmove`, `memcpy`, and `memset`, as well as internally linking to other functions in `std::ptr` - List invariants which, when violated, cause UB for all functions - Add example to `ptr::drop_in_place` and compares it to `ptr::read`. - Add examples which more closely mirror real world uses for the functions in `std::ptr`. Also, move the reimplementation of `mem::swap` to the examples of `ptr::read` and use a more interesting example for `copy_nonoverlapping`. - Change module level description - Define what constitutes a "valid" pointer. - Centralize discussion of ownership of bitwise copies in `ptr::read` and provide an example.
2018-08-22Rollup merge of #53574 - vorner:ptr_as_ref_unchecked, r=Mark-SimulacrumGuillaume Gomez-0/+30
Suggest direct raw-pointer dereference People often come looking for some kind of `as_ref_unchecked` method on raw pointers that would give them `&T` and not `Option<&T>` when they are sure the pointer is not NULL. There's no such method, but taking a reference of the dereferenced pointer accomplishes the same thing. Therefore, suggest using that, at the `as_ref` site ‒ it's a place people are likely going to look into.
2018-08-21Suggest direct raw-pointer dereferenceMichal 'vorner' Vaner-0/+30
People often come looking for some kind of `as_ref_unchecked` method on raw pointers that would give them `&T` and not `Option<&T>` when they are sure the pointer is not NULL. There's no such method, but taking a reference of the dereferenced pointer accomplishes the same thing. Therefore, suggest using that, at the `as_ref` site ‒ it's a place people are likely going to look into.
2018-08-21Rollup merge of #53329 - frewsxcv:frewsxcv-ptr-add-sub, r=RalfJungkennytm-8/+8
Replace usages of ptr::offset with ptr::{add,sub}. Rust provides these helper methods – so let's use them!
2018-08-20Replace usages of ptr::offset with ptr::{add,sub}.Corey Farwell-8/+8
2018-08-19Fix typos found by codespell.Matthias Krüger-1/+1
2018-08-12Rollup merge of #53059 - ljedrz:unneeded_returns, r=kennytmGuillaume Gomez-2/+2
Remove explicit returns where unnecessary
2018-08-04Remove explicit returns where unnecessaryljedrz-2/+2
2018-08-03volatile operations docs: clarify that this does not help wrt. concurrencyRalf Jung-0/+30
2018-07-30Remove unstable and deprecated APIsSimon Sapin-80/+0
2018-07-27Fix doc comment for 'ptr::copy_to' methodZakarum-2/+2
2018-07-24clarify offset function safety concernsRalf Jung-4/+16
2018-07-23Rollup merge of #52051 - scottmcm:swap-directly, r=alexcrichtonkennytm-0/+13
mem::swap the obvious way for types smaller than the SIMD optimization's block size LLVM isn't able to remove the alloca for the unaligned block in the post-SIMD tail in some cases, so doing this helps SRoA work in cases where it currently doesn't. Found in the `replace_with` RFC discussion. Examples of the improvements: <details> <summary>swapping `[u16; 3]` takes 1/3 fewer instructions and no stackalloc</summary> ```rust type Demo = [u16; 3]; pub fn swap_demo(x: &mut Demo, y: &mut Demo) { std::mem::swap(x, y); } ``` nightly: ```asm _ZN4blah9swap_demo17ha1732a9b71393a7eE: .seh_proc _ZN4blah9swap_demo17ha1732a9b71393a7eE sub rsp, 32 .seh_stackalloc 32 .seh_endprologue movzx eax, word ptr [rcx + 4] mov word ptr [rsp + 4], ax mov eax, dword ptr [rcx] mov dword ptr [rsp], eax movzx eax, word ptr [rdx + 4] mov word ptr [rcx + 4], ax mov eax, dword ptr [rdx] mov dword ptr [rcx], eax movzx eax, word ptr [rsp + 4] mov word ptr [rdx + 4], ax mov eax, dword ptr [rsp] mov dword ptr [rdx], eax add rsp, 32 ret .seh_handlerdata .section .text,"xr",one_only,_ZN4blah9swap_demo17ha1732a9b71393a7eE .seh_endproc ``` this PR: ```asm _ZN4blah9swap_demo17ha1732a9b71393a7eE: mov r8d, dword ptr [rcx] movzx r9d, word ptr [rcx + 4] movzx eax, word ptr [rdx + 4] mov word ptr [rcx + 4], ax mov eax, dword ptr [rdx] mov dword ptr [rcx], eax mov word ptr [rdx + 4], r9w mov dword ptr [rdx], r8d ret ``` </details> <details> <summary>`replace_with` optimizes down much better</summary> Inspired by https://github.com/rust-lang/rfcs/pull/2490, ```rust fn replace_with<T, F>(x: &mut Option<T>, f: F) where F: FnOnce(Option<T>) -> Option<T> { *x = f(x.take()); } pub fn inc_opt(mut x: &mut Option<i32>) { replace_with(&mut x, |i| i.map(|j| j + 1)); } ``` Rust 1.26.0: ```asm _ZN4blah7inc_opt17heb0acb64c51777cfE: mov rax, qword ptr [rcx] movabs r8, 4294967296 add r8, rax shl rax, 32 movabs rdx, -4294967296 and rdx, r8 xor r8d, r8d test rax, rax cmove rdx, rax setne r8b or rdx, r8 mov qword ptr [rcx], rdx ret ``` Nightly (better thanks to ScalarPair, maybe?): ```asm _ZN4blah7inc_opt17h66df690be0b5899dE: mov r8, qword ptr [rcx] mov rdx, r8 shr rdx, 32 xor eax, eax test r8d, r8d setne al add edx, 1 mov dword ptr [rcx], eax mov dword ptr [rcx + 4], edx ret ``` This PR: ```asm _ZN4blah7inc_opt17h1426dc215ecbdb19E: xor eax, eax cmp dword ptr [rcx], 0 setne al mov dword ptr [rcx], eax add dword ptr [rcx + 4], 1 ret ``` Where that add is beautiful -- using an addressing mode to not even need to explicitly go through a register -- and the remaining imperfection is well-known (https://github.com/rust-lang/rust/pull/49420#issuecomment-376805721). </details>
2018-07-21Don't use SIMD in mem::swap for types smaller than the block sizeScott McMurray-0/+13
LLVM isn't able to remove the alloca for the unaligned block in the SIMD tail in some cases, so doing this helps SRoA work in cases where it currently doesn't. Found in the `replace_with` RFC discussion.
2018-07-18Document that Unique::empty() and NonNull::dangling() aren't sentinel valuesJosh Triplett-0/+10
The documentation of Unique::empty() and NonNull::dangling() could potentially suggest that they work as sentinel values indicating a not-yet-initialized pointer. However, they both declare a non-null pointer equal to the alignment of the type, which could potentially reference a valid value of that type (specifically, the first such valid value in memory). Explicitly document that the return value of these functions does not work as a sentinel value.
2018-07-04Auto merge of #51395 - SimonSapin:repr-transparent, r=SimonSapinbors-0/+2
Add #[repr(transparent)] to some libcore types * `UnsafeCell` * `Cell` * `NonZero*` * `NonNull` * `Unique` CC https://github.com/rust-lang/rust/issues/43036
2018-06-30Bootstrap from 1.28.0-beta.3Mark Simulacrum-27/+0
2018-06-16Add #[repr(transparent)] to some libcore typesSimon Sapin-0/+2
* `UnsafeCell` * `Cell` * `NonZero*` * `NonNull` * `Unique`
2018-06-11Remove alloc::Opaque and use *mut u8 as pointer type for GlobalAllocMike Hommey-8/+0
2018-06-01Reword {ptr,mem}::replace docs.Corey Farwell-2/+3
Fixes https://github.com/rust-lang/rust/issues/50657.
2018-05-18Auto merge of #50319 - nagisa:align_to, r=alexcrichtonbors-46/+224
Implement [T]::align_to Note that this PR deviates from what is accepted by RFC slightly by making `align_offset` to return an offset in elements, rather than bytes. This is necessary to sanely support `[T]::align_to` and also simply makes more sense™. The caveat is that trying to align a pointer of ZST is now an equivalent to `is_aligned` check, rather than anything else (as no number of ZST elements will align a misaligned ZST pointer). It also implements the `align_to` slightly differently than proposed in the RFC to properly handle cases where size of T and U aren’t co-prime. Furthermore, a promise is made that the slice containing `U`s will be as large as possible (contrary to the RFC) – otherwise the function is quite useless. The implementation uses quite a few underhanded tricks and takes advantage of the fact that alignment is a power-of-two quite heavily to optimise the machine code down to something that results in as few known-expensive instructions as possible. Currently calling `ptr.align_offset` with an unknown-at-compile-time `align` results in code that has just a single "expensive" modulo operation; the rest is "cheap" arithmetic and bitwise ops. cc https://github.com/rust-lang/rust/issues/44488 @oli-obk As mentioned in the commit message for align_offset, many thanks go to Chris McDonald.
2018-05-17Remove the intrinsic for align_offsetSimonas Kazlauskas-10/+21
Keep only the language item. This removes some indirection and makes codegen worse for debug builds, but simplifies code significantly, which is a good tradeoff to make, in my opinion. Besides, the codegen can be improved even further with some constant evaluation improvements that we expect to happen in the future.
2018-05-17Change align_offset to support different stridesSimonas Kazlauskas-46/+213
This is necessary if we want to implement `[T]::align_to` and is more useful in general. This implementation effort has begun during the All Hands and represents a month of my futile efforts to do any sort of maths. Luckily, I found the very very nice Chris McDonald (cjm) on IRC who figured out the core formulas for me! All the thanks for existence of this PR go to them! Anyway… Those formulas were mangled by yours truly into the arcane forms you see here to squeeze out the best assembly possible on most of the modern architectures (x86 and ARM were evaluated in practice). I mean, just look at it: *one actual* modulo operation and everything else is just the cheap single cycle ops! Admitedly, the naive solution might be faster in some common scenarios, but this code absolutely butchers the naive solution on the worst case scenario. Alas, the result of this arcane magic also means that the code pretty heavily relies on the preconditions holding true and breaking those preconditions will unleash the UB-est of all UBs! So don’t.
2018-05-17Revert #49767steveklabnik-300/+70
There was [some confusion](https://github.com/rust-lang/rust/pull/49767#issuecomment-389250815) and I accidentally merged a PR that wasn't ready.
2018-05-16Make core::nonzero privateSimon Sapin-9/+2
It is now an implementation detail of ptr::NonNull and num::NonZero*
2018-05-15Rollup merge of #49767 - ecstatic-morse:ptr-docs, r=steveklabnikGuillaume Gomez-70/+300
Rewrite docs for `std::ptr` This PR attempts to resolve #29371. This is a fairly major rewrite of the `std::ptr` docs, and deserves a fair bit of scrutiny. It adds links to the GNU libc docs for various instrinsics, adds internal links to types and functions referenced in the docs, adds new, more complex examples for many functions, and introduces a common template for discussing unsafety of functions in `std::ptr`. All functions in `std::ptr` (with the exception of `ptr::eq`) are unsafe because they either read from or write to a raw pointer. The "Safety" section now informs that the function is unsafe because it dereferences a raw pointer and requires that any pointer to be read by the function points to "a valid vaue of type `T`". Additionally, each function imposes some subset of the following conditions on its arguments. * The pointer points to valid memory. * The pointer points to initialized memory. * The pointer is properly aligned. These requirements are discussed in the "Undefined Behavior" section along with the consequences of using functions that perform bitwise copies without requiring `T: Copy`. I don't love my new descriptions of the consequences of making such copies. Perhaps the old ones were good enough? Some issues which still need to be addressed before this is merged: - [ ] The new docs assert that `drop_in_place` is equivalent to calling `read` and discarding the value. Is this correct? - [ ] Do `write_bytes` and `swap_nonoverlapping` require properly aligned pointers? - [ ] The new example for `drop_in_place` is a lackluster. - [ ] Should these docs rigorously define what `valid` memory is? Or should is that the job of the reference? Should we link to the reference? - [ ] Is it correct to require that pointers that will be read from refer to "valid values of type `T`"? - [x] I can't imagine ever using `{read,write}_volatile` with non-`Copy` types. Should I just link to {read,write} and say that the same issues with non-`Copy` types apply? - [x] `write_volatile` doesn't link back to `read_volatile`. - [ ] Update docs for the unstable [`swap_nonoverlapping`](https://github.com/rust-lang/rust/issues/42818) - [ ] Update docs for the unstable [unsafe pointer methods RFC](https://github.com/rust-lang/rfcs/pull/1966) Looking forward to your feedback. r? @steveklabnik
2018-05-09Shorten ownership safety discussion in `read_volatile`Dylan MacKenzie-8/+15
Non-`Copy` types should not be in volatile memory.
2018-05-09Use the "Safety" heading instead of "Undefined Behavior"Dylan MacKenzie-43/+1
2018-05-01Rollup merge of #50233 - mark-i-m:const_vec, r=kennytmkennytm-3/+2
Make `Vec::new` a `const fn` `RawVec::empty/_in` are a hack. They're there because `if size_of::<T> == 0 { !0 } else { 0 }` is not allowed in `const` yet. However, because `RawVec` is unstable, the `empty/empty_in` constructors can be removed when #49146 is done...
2018-04-28Rollup merge of #49858 - dmizuk:unique-doc-hidden, r=steveklabnikkennytm-0/+1
std: Mark `ptr::Unique` with `#[doc(hidden)]` `Unique` is now perma-unstable, so let's hide its docs.