rust/library/std/src
bors 734368a200 Auto merge of #87869 - thomcc:skinny-io-error, r=yaahc
Make io::Error use 64 bits on targets with 64 bit pointers.

I've wanted this for a long time, but didn't see a good way to do it without having extra allocation. When looking at it yesterday, it was more clear what to do for some reason.

This approach avoids any additional allocations, and reduces the size by half (8 bytes, down from 16). AFAICT it doesn't come additional runtime cost, and the compiler seems to do a better job with code using it.

Additionally, this `io::Error` has a niche (still), so `io::Result<()>` is *also* 64 bits (8 bytes, down from 16), and `io::Result<usize>` (used for lots of io trait functions) is 2x64 bits (16 bytes, down from 24 — this means on x86_64 it can use the nice rax/rdx 2-reg struct return). More generally, it shaves a whole 64 bit integer register off of the size of basically any `io::Result<()>`.

(For clarity: Improving `io::Result` (rather than io::Error) was most of the motivation for this)

On 32 bit (or other non-64bit) targets we still use something equivalent the old repr — I don't think think there's improving it, since one of the fields it stores is a `i32`, so we can't get below that, and it's already about as close as we can get to it.

---

### Isn't Pointer Tagging Dodgy?

The details of the layout, and why its implemented the way it is, are explained in the header comment of library/std/src/io/error/repr_bitpacked.rs. There's probably more details than there need to be, but I didn't trim it down that much, since there's a lot of stuff I did deliberately, that might have not seemed that way.

There's actually only one variant holding a pointer which gets tagged. This one is the (holder for the) user-provided error.

I believe the scheme used to tag it is not UB, and that it preserves pointer provenance (even though often pointer tagging does not) because the tagging operation is just `core::ptr::add`, and untagging is `core::ptr::sub`. The result of both operations lands inside the original allocation, so it would follow the safety contract of `core::ptr::{add,sub}`.

The other pointer this had to encode is not tagged — or rather, the tagged repr is equivalent to untagged (it's tagged with 0b00, and has >=4b alignment, so we can reuse the bottom bits). And the other variants we encode are just integers, which (which can be untagged using bitwise operations without worry — they're integers).

CC `@RalfJung` for the stuff in repr_bitpacked.rs, as my comments are informed by a lot of the UCG work, but it's possible I missed something or got it wrong (even if the implementation is okay, there are parts of the header comment that says things like "We can't do $x" which could be false).

---

### Why So Many Changes?

The repr change was mostly internal, but changed one widely used API: I had to switch how `io::Error::new_const` works.

This required switching `io::Error::new_const` to take the full message data (including the kind) as a `&'static`, rather than just the string. This would have been really tedious, but I made a macro that made it much simpler, but it was a wide change since `io::Error::new_const` is used everywhere.

This included changing files for a lot of targets I don't have easy access to (SGX? Haiku? Windows? Who has heard of these things), so I expect there to be spottiness in CI initially, unless luck is on my side.

Anyway this large only tangentially-related change is all in the first commit (although that commit also pulls the previous repr out into its own file), whereas the packing stuff is all in commit 2.

---

P.S. I haven't looked at all of this since writing it, and will do a pass over it again later, sorry for any obvious typos or w/e. I also definitely repeat myself in comments and such.

(It probably could use more tests too. I did some basic testing, and made it so we `debug_assert!` in cases the decode isn't what we encoded, but I don't know the degree which I can assume libstd's testing of IO would exercise this. That is: it wouldn't be surprising to me if libstds IO testing were minimal, especially around error cases, although I have no idea).
2022-02-07 20:32:56 +00:00
..
backtrace Add Frames iterator for Backtrace 2021-01-23 11:56:33 -06:00
collections add a rustc::query_stability lint 2022-02-01 10:15:59 +01:00
env std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
error silence tidy errors 2022-01-07 13:59:27 -08:00
f32 Implement IEEE 754-2019 minimun and maximum functions for f32/f64 2021-11-20 10:14:03 +01:00
f64 Remove fNN::lerp - consensus unlikely 2021-10-25 22:44:41 -05:00
ffi Auto merge of #87869 - thomcc:skinny-io-error, r=yaahc 2022-02-07 20:32:56 +00:00
fs fs: Add a regression test for #93384 2022-01-29 16:37:21 -05:00
io Add more tests for io::Error packing, and fix some comments that weren't quite accurate anymore 2022-02-04 23:15:02 -08:00
lazy Upgrade wasm32 image to Ubuntu 20.04 2021-02-06 13:05:56 +01:00
net Hide Repr details from io::Error, and rework io::Error::new_const. 2022-02-04 18:47:29 -08:00
num rustc_expand: Mark inner #![test] attributes as soft-unstable 2020-11-20 19:35:03 +03:00
os Hide Repr details from io::Error, and rework io::Error::new_const. 2022-02-04 18:47:29 -08:00
panic review: fix nits and move panic safety tests to the correct place 2020-09-25 23:10:24 +02:00
path add benchmarks and tests for Hash and Eq impls on Path 2021-11-09 20:54:00 +01:00
prelude update cfg(bootstrap)s 2022-01-28 15:01:07 +01:00
process Rollup merge of #92208 - ChrisDenton:win-bat-cmd, r=dtolnay 2021-12-23 00:28:56 +01:00
sync update cfg(bootstrap)s 2022-01-28 15:01:07 +01:00
sys Auto merge of #87869 - thomcc:skinny-io-error, r=yaahc 2022-02-07 20:32:56 +00:00
sys_common Hide Repr details from io::Error, and rework io::Error::new_const. 2022-02-04 18:47:29 -08:00
thread Rollup merge of #92555 - m-ou-se:scoped-threads, r=Amanieu 2022-01-23 20:13:02 +01:00
time Add #[must_use] to remaining std functions (O-Z) 2021-10-30 23:37:32 -04:00
alloc.rs Rename rterr to rtprintpanic 2021-05-19 15:52:09 +02:00
ascii.rs Convert many files to intra-doc links 2020-09-02 17:37:40 -04:00
backtrace.rs Change Backtrace::enabled atomic from SeqCst to Relaxed 2021-12-20 12:34:10 -08:00
env.rs Rollup merge of #89999 - talagrand:GetTempPath2, r=m-ou-se 2021-12-09 05:08:31 +01:00
error.rs Improve Duration::try_from_secs_f32/64 accuracy by directly processing exponent and mantissa 2022-01-26 18:14:25 +03:00
f32.rs Remove fNN::lerp - consensus unlikely 2021-10-25 22:44:41 -05:00
f64.rs Remove fNN::lerp - consensus unlikely 2021-10-25 22:44:41 -05:00
fs.rs Hide Repr details from io::Error, and rework io::Error::new_const. 2022-02-04 18:47:29 -08:00
keyword_docs.rs eplace usages of vec![].into_iter with [].into_iter 2022-01-09 14:09:25 +11:00
lazy.rs Add #[must_use] to core and std constructors 2021-10-10 02:44:26 -04:00
lib.rs Auto merge of #93146 - workingjubilee:use-std-simd, r=Mark-Simulacrum 2022-02-03 09:15:16 +00:00
macros.rs Add diagnostic items for macros 2022-01-06 14:59:33 +00:00
num.rs Add Saturating type (based on Wrapping type) 2021-08-10 19:27:01 +02:00
panic.rs Configure panic hook backtrace behavior 2022-02-02 13:46:42 -05:00
panicking.rs Configure panic hook backtrace behavior 2022-02-02 13:46:42 -05:00
path.rs Link try_exists docs to Path::exists 2022-02-01 18:40:29 +00:00
primitive_docs.rs Fix annotation of code blocks 2022-02-01 21:44:53 +00:00
process.rs add inline attribute to new method 2022-01-31 11:57:17 -08:00
rt.rs Change Termination::report return type to ExitCode 2022-01-28 12:53:36 -08:00
time.rs Document SystemTime platform precision 2022-01-29 20:41:18 +00:00